aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Embroidery
diff options
context:
space:
mode:
authorRoy Ben-Shabat <Roy@Twine-s.com>2018-02-25 17:52:27 +0200
committerRoy Ben-Shabat <Roy@Twine-s.com>2018-02-25 17:52:27 +0200
commita89c62d8fc0401b437ecb51d1bbf46b8c66b9b77 (patch)
treefe50517b5ee63e058d00856c82eb600462951e32 /Software/Visual_Studio/Embroidery
parent76a11483dd6ecd9bae36323b2bb5f475cbe109f1 (diff)
downloadTango-a89c62d8fc0401b437ecb51d1bbf46b8c66b9b77.tar.gz
Tango-a89c62d8fc0401b437ecb51d1bbf46b8c66b9b77.zip
Added LibEmbroidery to solution.
Diffstat (limited to 'Software/Visual_Studio/Embroidery')
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/README.md21
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/api-start.h48
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/api-stop.h4
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/compound-file-common.h41
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/compound-file-difat.c88
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/compound-file-difat.h35
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/compound-file-directory.c129
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/compound-file-directory.h52
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/compound-file-fat.c37
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/compound-file-fat.h30
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/compound-file-header.c42
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/compound-file-header.h44
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/compound-file.c143
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/compound-file.h35
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-arc.c76
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-arc.h54
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-circle.c106
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-circle.h54
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-color.c52
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-color.h28
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-compress.c1112
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-compress.h163
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-ellipse.c133
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-ellipse.h61
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-file.c143
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-file.h41
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-flag.c62
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-flag.h31
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-format.c383
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-format.h51
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-hash.c17
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-hash.h34
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-hoop.c17
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-hoop.h26
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-layer.c3
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-layer.h25
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-line.c163
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-line.h60
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-logging.c47
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-logging.h24
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-outline.c551
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-outline.h18
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-path.c96
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-path.h59
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-pattern.c1068
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-pattern.h104
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-point.c166
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-point.h65
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-polygon.c92
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-polygon.h44
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-polyline.c92
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-polyline.h44
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-reader-writer.c582
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-reader-writer.h27
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-rect.c153
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-rect.h66
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-satin-line.c139
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-satin-line.h29
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-settings.c24
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-settings.h30
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-spline.c22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-spline.h51
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-stitch.c71
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-stitch.h46
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-thread.c150
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-thread.h45
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-time.c40
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-time.h30
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-vector.c85
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/emb-vector.h43
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/examples/README.md4
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/examples/barebones/barebones.ino84
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-100.c65
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-100.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-10o.c84
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-10o.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-art.c35
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-art.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-bmc.c35
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-bmc.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-bro.c97
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-bro.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-cnd.c35
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-cnd.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-col.c94
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-col.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-csd.c218
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-csd.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-csv.c345
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-csv.h39
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-dat.c90
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-dat.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-dem.c35
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-dem.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-dsb.c87
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-dsb.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-dst.c505
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-dst.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-dsz.c83
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-dsz.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-dxf.c603
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-dxf.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-edr.c78
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-edr.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-emd.c107
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-emd.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-exp.c192
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-exp.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-exy.c124
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-exy.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-eys.c35
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-eys.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-fxy.c78
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-fxy.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-gc.c36
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-gc.h23
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-gnc.c35
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-gnc.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-gt.c78
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-gt.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-hus.c300
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-hus.h61
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-inb.c115
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-inb.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-inf.c106
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-inf.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-jef.c400
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-jef.h103
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-ksm.c136
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-ksm.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-max.c134
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-max.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-mit.c104
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-mit.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-new.c100
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-new.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-ofm.c277
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-ofm.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-pcd.c187
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-pcd.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-pcm.c101
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-pcm.h42
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-pcq.c187
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-pcq.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-pcs.c199
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-pcs.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-pec.c426
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-pec.h135
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-pel.c35
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-pel.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-pem.c35
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-pem.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-pes.c255
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-pes.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-phb.c96
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-phb.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-phc.c82
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-phc.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-plt.c116
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-plt.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-rgb.c76
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-rgb.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-sew.c210
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-sew.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-shv.c182
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-shv.h71
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-sst.c83
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-sst.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-stx.c262
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-stx.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-svg.c3638
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-svg.h80
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-t01.c220
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-t01.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-t09.c72
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-t09.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-tap.c220
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-tap.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-thr.c282
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-thr.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-txt.c55
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-txt.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-u00.c96
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-u00.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-u01.c76
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-u01.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-vip.c350
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-vip.h50
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-vp3.c533
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-vp3.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-xxx.c283
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-xxx.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-zsk.c112
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/format-zsk.h22
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/formats.h76
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/geom-arc.c279
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/geom-arc.dxf1834
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/geom-arc.h35
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/geom-circle.c181
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/geom-circle.dxf2460
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/geom-circle.h35
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/geom-line.c32
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/geom-line.h19
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/hashtable.c706
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/hashtable.h437
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/helpers-binary.c203
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/helpers-binary.h44
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/helpers-misc.c131
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/helpers-misc.h37
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/helpers-unused.h13
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/keywords.txt445
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/libembroidery-generate-todo49
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/libembroidery-shared.pro36
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/libembroidery-static.pro34
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/libembroidery-undocumented.doxyfile1890
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/libembroidery.dox7
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/libembroidery.doxyfile1890
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/libembroidery.pri234
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/libembroidery.pro8
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/thread-color.c5096
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/thread-color.h49
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/utility/README.md49
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/utility/ino-event.cpp19
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/utility/ino-event.h20
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/utility/ino-file.cpp92
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/utility/ino-file.h29
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/utility/ino-logging.cpp10
-rw-r--r--Software/Visual_Studio/Embroidery/libembroidery/utility/ino-logging.h17
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/README.md9
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/TODO160
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/debian/control/control14
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/debian/control/postinst2
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/debian/control/postrm2
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/debian/control/prerm2
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/application-registry/embroidermodder2.applications7
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/applications/embroidermodder2.desktop10
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/doc/embroidermodder2/README7
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/man/man1/embroidermodder2.1.gzbin0 -> 480 bytes
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/menu/embroidermodder27
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/mime-info/embroidermodder2.keys4
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/mime-info/embroidermodder2.mime51
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/mime/application/x-embroidermodder.xml56
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/pixmaps/embroidermodder2.pngbin0 -> 6866 bytes
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/format-progress.txt67
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/nsis/LICENSE11
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/nsis/checkboxes.bmpbin0 -> 2512 bytes
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/nsis/embroidermodder2-installer.nsi157
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/nsis/embroidermodder2.icobin0 -> 67646 bytes
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/nsis/header-install.bmpbin0 -> 9744 bytes
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/nsis/header-uninstall.bmpbin0 -> 9744 bytes
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/nsis/install.bmpbin0 -> 52576 bytes
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/nsis/uninstall.bmpbin0 -> 52576 bytes
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/osx/README.md14
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/qmake/README.md32
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/qmake/embroidermodder23
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/qmake/everything.pro44
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/qmake/libembroidery-convert3
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/version/MAJOR.txt1
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/version/MINOR.txt1
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/version/PATCH.txt1
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/version/README.md17
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/visualstudio/.gitignore196
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/visualstudio/README.md19
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/visualstudio/libEmbroideryVS2008.sln20
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/visualstudio/libEmbroideryVS2008.vcproj982
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/visualstudio/libEmbroideryVS2008.vcxproj299
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/visualstudio/libEmbroideryVS2008.vcxproj.filters612
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/visualstudio/libEmbroideryVS2013.sln22
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/visualstudio/libembroidery-convert.sln20
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/visualstudio/libembroidery-convert.vcxproj290
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/visualstudio/libembroidery.sln20
-rw-r--r--Software/Visual_Studio/Embroidery/project-files/visualstudio/libembroidery.vcxproj287
272 files changed, 42843 insertions, 0 deletions
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/README.md b/Software/Visual_Studio/Embroidery/libembroidery/README.md
new file mode 100644
index 000000000..9e8ebe898
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/README.md
@@ -0,0 +1,21 @@
+What is libembroidery ?
+-----------------------
+
+libembroidery is the underlying library that is used and
+developed by [Embroidermodder 2](http://embroidermodder.github.io).
+It handles over 45 different embroidery specific formats as well
+as several non-embroidery specific vector formats.
+
+Documentation
+-------------
+
+Developer Documentation can be generated using [Doxygen](http://www.doxygen.org)
+
+- For clean docs that only includes documented items (most people):
+```
+doxygen libembroidery.doxyfile
+```
+- For verbose docs that includes undocumented items (core developers):
+```
+doxygen libembroidery-undocumented.doxyfile
+```
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/api-start.h b/Software/Visual_Studio/Embroidery/libembroidery/api-start.h
new file mode 100644
index 000000000..6aa827a0d
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/api-start.h
@@ -0,0 +1,48 @@
+/* Only include this in libembroidery header files around functions to be exported as shared library */
+#if defined(API_START_H)
+ #error Nested inclusion of api-start.h is not allowed
+#endif
+#define API_START_H
+
+/* Sanity check */
+#if defined(LIBEMBROIDERY_SHARED) && defined(LIBEMBROIDERY_STATIC)
+ #error Library cannot be shared and static at the same time
+#endif
+
+/* When building a shared library, use the proper export keyword depending on the compiler */
+#if defined(LIBEMBROIDERY_SHARED)
+ #if defined(__WIN32__)
+ #define EMB_PUBLIC __declspec(dllexport)
+ #define EMB_PRIVATE
+ #else
+ #if defined(__GNUC__) && __GNUC__ >= 4
+ #define EMB_PUBLIC __attribute__ ((visibility("default")))
+ #define EMB_PRIVATE __attribute__ ((visibility("hidden")))
+ #elif defined(__GNUC__) && __GNUC__ >= 2
+ #define EMB_PUBLIC __declspec(dllexport)
+ #define EMB_PRIVATE
+ #else
+ #define EMB_PUBLIC
+ #define EMB_PRIVATE
+ #endif
+ #endif
+#else
+ #define EMB_PUBLIC
+ #define EMB_PRIVATE
+#endif
+
+/* Use the C calling convention */
+#ifndef EMB_CALL
+ #if defined(__WIN32__) && !defined(__GNUC__)
+ #define EMB_CALL __cdecl
+ #else
+ #define EMB_CALL
+ #endif
+#endif /* EMBCALL */
+
+/* Disable warnings about unsafe use of fopen, fseek etc */
+#if !defined(__GNUC__)
+ #pragma warning(disable: 4996)
+#endif
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/api-stop.h b/Software/Visual_Studio/Embroidery/libembroidery/api-stop.h
new file mode 100644
index 000000000..6a97bc4cd
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/api-stop.h
@@ -0,0 +1,4 @@
+/* Reverse the effects of api-start.h and should only be included at the bottom of the libembroidery headers */
+#undef API_START_H
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/compound-file-common.h b/Software/Visual_Studio/Embroidery/libembroidery/compound-file-common.h
new file mode 100644
index 000000000..9bdbfd270
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/compound-file-common.h
@@ -0,0 +1,41 @@
+/*! @file compound-file-common.h */
+#ifndef COMPOUND_FILE_COMMON_H
+#define COMPOUND_FILE_COMMON_H
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ Type of sector
+*/
+#define CompoundFileSector_MaxRegSector 0xFFFFFFFA
+#define CompoundFileSector_DIFAT_Sector 0xFFFFFFFC
+#define CompoundFileSector_FAT_Sector 0xFFFFFFFD
+#define CompoundFileSector_EndOfChain 0xFFFFFFFE
+#define CompoundFileSector_FreeSector 0xFFFFFFFF
+
+/**
+ Type of directory object
+*/
+#define ObjectTypeUnknown 0x00 /*!< Probably unallocated */
+#define ObjectTypeStorage 0x01 /*!< a directory type object */
+#define ObjectTypeStream 0x02 /*!< a file type object */
+#define ObjectTypeRootEntry 0x05 /*!< the root entry */
+
+/**
+ Special values for Stream Identifiers
+*/
+#define CompoundFileStreamId_MaxRegularStreamId 0xFFFFFFFA /*!< All real stream Ids are less than this */
+#define CompoundFileStreamId_NoStream 0xFFFFFFFF /*!< There is no valid stream Id */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* COMPOUND_FILE_COMMON_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
+
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/compound-file-difat.c b/Software/Visual_Studio/Embroidery/libembroidery/compound-file-difat.c
new file mode 100644
index 000000000..cad9817b8
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/compound-file-difat.c
@@ -0,0 +1,88 @@
+#include "compound-file-difat.h"
+#include "compound-file-common.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+#include <stdlib.h>
+
+static const unsigned int sizeOfDifatEntry = 4;
+static const unsigned int sizeOfChainingEntryAtEndOfDifatSector = 4;
+
+bcf_file_difat* bcf_difat_create(EmbFile* file, unsigned int fatSectors, const unsigned int sectorSize)
+{
+ unsigned int i;
+ bcf_file_difat* difat = 0;
+ unsigned int sectorRef;
+
+ difat = (bcf_file_difat*)malloc(sizeof(bcf_file_difat));
+ if(!difat) { embLog_error("compound-file-difat.c bcf_difat_create(), cannot allocate memory for difat\n"); } /* TODO: avoid crashing. null pointer will be accessed */
+
+ difat->sectorSize = sectorSize;
+ if(fatSectors > NumberOfDifatEntriesInHeader)
+ {
+ fatSectors = NumberOfDifatEntriesInHeader;
+ }
+
+ for(i = 0; i < fatSectors; ++i)
+ {
+ sectorRef = binaryReadUInt32(file);
+ difat->fatSectorEntries[i] = sectorRef;
+ }
+ difat->fatSectorCount = fatSectors;
+ for(i = fatSectors; i < NumberOfDifatEntriesInHeader; ++i)
+ {
+ sectorRef = binaryReadUInt32(file);
+ if(sectorRef != CompoundFileSector_FreeSector)
+ {
+ embLog_error("compound-file-difat.c bcf_difat_create(), Unexpected sector value %x at DIFAT[%d]\n", sectorRef, i);
+ }
+ }
+ return difat;
+}
+
+unsigned int numberOfEntriesInDifatSector(bcf_file_difat* fat)
+{
+ return (fat->sectorSize - sizeOfChainingEntryAtEndOfDifatSector ) / sizeOfDifatEntry;
+}
+
+unsigned int readFullSector(EmbFile* file, bcf_file_difat* bcfFile, unsigned int* numberOfDifatEntriesStillToRead)
+{
+ unsigned int i;
+ unsigned int sectorRef;
+ unsigned int nextDifatSectorInChain;
+ unsigned int entriesToReadInThisSector = 0;
+ if(*numberOfDifatEntriesStillToRead > numberOfEntriesInDifatSector(bcfFile))
+ {
+ entriesToReadInThisSector = numberOfEntriesInDifatSector(bcfFile);
+ *numberOfDifatEntriesStillToRead -= entriesToReadInThisSector;
+ }
+ else
+ {
+ entriesToReadInThisSector = *numberOfDifatEntriesStillToRead;
+ *numberOfDifatEntriesStillToRead = 0;
+ }
+
+ for(i = 0; i < entriesToReadInThisSector; ++i)
+ {
+ sectorRef = binaryReadUInt32(file);
+ bcfFile->fatSectorEntries[bcfFile->fatSectorCount]= sectorRef;
+ bcfFile->fatSectorCount++;
+ }
+ for(i = entriesToReadInThisSector; i < numberOfEntriesInDifatSector(bcfFile); ++i)
+ {
+ sectorRef = binaryReadUInt32(file);
+ if(sectorRef != CompoundFileSector_FreeSector)
+ {
+ embLog_error("compound-file-difat.c readFullSector(), Unexpected sector value %x at DIFAT[%d]]\n", sectorRef, i);
+ }
+ }
+ nextDifatSectorInChain = binaryReadUInt32(file);
+ return nextDifatSectorInChain;
+}
+
+void bcf_file_difat_free(bcf_file_difat* difat)
+{
+ free(difat);
+ difat = 0;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/compound-file-difat.h b/Software/Visual_Studio/Embroidery/libembroidery/compound-file-difat.h
new file mode 100644
index 000000000..d7051a759
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/compound-file-difat.h
@@ -0,0 +1,35 @@
+/*! @file compound-file-difat.h */
+#ifndef COMPOUND_FILE_DIFAT_H
+#define COMPOUND_FILE_DIFAT_H
+
+#include "emb-file.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* double-indirection file allocation table references */
+typedef struct _bcf_file_difat
+{
+ unsigned int fatSectorCount;
+ unsigned int fatSectorEntries[109];
+ unsigned int sectorSize;
+} bcf_file_difat;
+
+extern EMB_PRIVATE bcf_file_difat* EMB_CALL bcf_difat_create(EmbFile* file, unsigned int fatSectors, const unsigned int sectorSize);
+extern EMB_PRIVATE unsigned int EMB_CALL readFullSector(EmbFile* file, bcf_file_difat* bcfFile, unsigned int* numberOfDifatEntriesStillToRead);
+extern EMB_PRIVATE unsigned int EMB_CALL numberOfEntriesInDifatSector(bcf_file_difat* fat);
+extern EMB_PRIVATE void EMB_CALL bcf_file_difat_free(bcf_file_difat* difat);
+
+/*! Constant representing the number of Double Indirect FAT entries in a single header */
+static const unsigned int NumberOfDifatEntriesInHeader = 109;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* COMPOUND_FILE_DIFAT_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/compound-file-directory.c b/Software/Visual_Studio/Embroidery/libembroidery/compound-file-directory.c
new file mode 100644
index 000000000..9608b51e0
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/compound-file-directory.c
@@ -0,0 +1,129 @@
+#include "compound-file-directory.h"
+#include "compound-file-common.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static void parseDirectoryEntryName(EmbFile* file, bcf_directory_entry* dir)
+{
+ int i;
+ unsigned short unicodechar;
+ for(i = 0; i < 32; ++i)
+ {
+ unicodechar = binaryReadUInt16(file);
+ if(unicodechar != 0x0000)
+ {
+ dir->directoryEntryName[i] = (char)unicodechar;
+ }
+ }
+}
+
+static void readCLSID(EmbFile* file, bcf_directory_entry* dir)
+{
+ int i;
+ unsigned char scratch;
+ const int guidSize = 16;
+ for(i = 0; i < guidSize; ++i)
+ {
+ scratch = binaryReadByte(file);
+ dir->CLSID[i] = scratch;
+ }
+}
+
+bcf_directory* CompoundFileDirectory(const unsigned int maxNumberOfDirectoryEntries)
+{
+ bcf_directory* dir = (bcf_directory*)malloc(sizeof(bcf_directory));
+ if(!dir) { embLog_error("compound-file-directory.c CompoundFileDirectory(), cannot allocate memory for dir\n"); } /* TODO: avoid crashing. null pointer will be accessed */
+ dir->maxNumberOfDirectoryEntries = maxNumberOfDirectoryEntries;
+ dir->dirEntries = 0;
+ return dir;
+}
+
+EmbTime parseTime(EmbFile* file)
+{
+ EmbTime returnVal;
+ unsigned int ft_low, ft_high;
+ /*embTime_time(&returnVal); TODO: use embTime_time() rather than time(). */
+ ft_low = binaryReadInt32(file);
+ ft_high = binaryReadInt32(file);
+ /* TODO: translate to actual date time */
+ return returnVal;
+}
+
+bcf_directory_entry* CompoundFileDirectoryEntry(EmbFile* file)
+{
+ bcf_directory_entry* dir = (bcf_directory_entry*)malloc(sizeof(bcf_directory_entry));
+ if(!dir) { embLog_error("compound-file-directory.c CompoundFileDirectoryEntry(), cannot allocate memory for dir\n"); } /* TODO: avoid crashing. null pointer will be accessed */
+ memset(dir->directoryEntryName, 0, 32);
+ parseDirectoryEntryName(file, dir);
+ dir->next = 0;
+ dir->directoryEntryNameLength = binaryReadUInt16(file);
+ dir->objectType = (unsigned char)binaryReadByte(file);
+ if( (dir->objectType != ObjectTypeStorage) &&
+ (dir->objectType != ObjectTypeStream) &&
+ (dir->objectType != ObjectTypeRootEntry))
+ {
+ embLog_error("compound-file-directory.c CompoundFileDirectoryEntry(), unexpected object type: %d\n", dir->objectType);
+ return 0;
+ }
+ dir->colorFlag = (unsigned char)binaryReadByte(file);
+ dir->leftSiblingId = binaryReadUInt32(file);
+ dir->rightSiblingId = binaryReadUInt32(file);
+ dir->childId = binaryReadUInt32(file);
+ readCLSID(file, dir);
+ dir->stateBits = binaryReadUInt32(file);
+ dir->creationTime = parseTime(file);
+ dir->modifiedTime = parseTime(file);
+ dir->startingSectorLocation = binaryReadUInt32(file);
+ dir->streamSize = binaryReadUInt32(file); /* This should really be __int64 or long long, but for our uses we should never run into an issue */
+ dir->streamSizeHigh = binaryReadUInt32(file); /* top portion of int64 */
+ return dir;
+}
+
+void readNextSector(EmbFile* file, bcf_directory* dir)
+{
+ unsigned int i;
+ for(i = 0; i < dir->maxNumberOfDirectoryEntries; ++i)
+ {
+ bcf_directory_entry* dirEntry = CompoundFileDirectoryEntry(file);
+ bcf_directory_entry* pointer = dir->dirEntries;
+ if(!pointer)
+ {
+ dir->dirEntries = dirEntry;
+ }
+ else
+ {
+ while(pointer)
+ {
+ if(!pointer->next)
+ {
+ pointer->next = dirEntry;
+ break;
+ }
+ pointer = pointer->next;
+ }
+ }
+ }
+}
+
+void bcf_directory_free(bcf_directory* dir)
+{
+ bcf_directory_entry* pointer = dir->dirEntries;
+ bcf_directory_entry* entryToFree = 0;
+ while(pointer)
+ {
+ entryToFree = pointer;
+ pointer = pointer->next;
+ free(entryToFree);
+ entryToFree = 0;
+ }
+ if(dir)
+ {
+ free(dir);
+ dir = 0;
+ }
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/compound-file-directory.h b/Software/Visual_Studio/Embroidery/libembroidery/compound-file-directory.h
new file mode 100644
index 000000000..019ee26e6
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/compound-file-directory.h
@@ -0,0 +1,52 @@
+/*! @file compound-file-directory.h */
+#ifndef COMPOUND_FILE_DIRECTORY_H
+#define COMPOUND_FILE_DIRECTORY_H
+
+#include "emb-time.h"
+#include "emb-file.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _bcf_directory_entry
+{
+ char directoryEntryName[32];
+ unsigned short directoryEntryNameLength;
+ unsigned char objectType;
+ unsigned char colorFlag;
+ unsigned int leftSiblingId;
+ unsigned int rightSiblingId;
+ unsigned int childId;
+ unsigned char CLSID[16];
+ unsigned int stateBits;
+ EmbTime creationTime;
+ EmbTime modifiedTime;
+ unsigned int startingSectorLocation;
+ unsigned long streamSize; /* should be long long but in our case we shouldn't need it, and hard to support on c89 cross platform */
+ unsigned int streamSizeHigh; /* store the high int of streamsize */
+ struct _bcf_directory_entry* next;
+} bcf_directory_entry;
+
+typedef struct _bcf_directory
+{
+ bcf_directory_entry* dirEntries;
+ unsigned int maxNumberOfDirectoryEntries;
+ /* TODO: possibly add a directory tree in the future */
+
+} bcf_directory;
+
+extern EMB_PRIVATE bcf_directory_entry* EMB_CALL CompoundFileDirectoryEntry(EmbFile* file);
+extern EMB_PRIVATE bcf_directory* EMB_CALL CompoundFileDirectory(const unsigned int maxNumberOfDirectoryEntries);
+extern EMB_PRIVATE void EMB_CALL readNextSector(EmbFile* file, bcf_directory* dir);
+extern EMB_PRIVATE void EMB_CALL bcf_directory_free(bcf_directory* dir);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* COMPOUND_FILE_DIRECTORY_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/compound-file-fat.c b/Software/Visual_Studio/Embroidery/libembroidery/compound-file-fat.c
new file mode 100644
index 000000000..3bb237dc4
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/compound-file-fat.c
@@ -0,0 +1,37 @@
+#include "compound-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+const unsigned int sizeOfFatEntry = sizeof(unsigned int);
+
+bcf_file_fat* bcfFileFat_create(const unsigned int sectorSize)
+{
+ bcf_file_fat* fat = (bcf_file_fat*)malloc(sizeof(bcf_file_fat));
+ if(!fat) { embLog_error("compound-file-fat.c bcfFileFat_create(), cannot allocate memory for fat\n"); } /* TODO: avoid crashing. null pointer will be accessed */
+ fat->numberOfEntriesInFatSector = sectorSize / sizeOfFatEntry;
+ fat->fatEntryCount = 0;
+ return fat;
+}
+
+void loadFatFromSector(bcf_file_fat* fat, EmbFile* file)
+{
+ unsigned int i;
+ unsigned int currentNumberOfFatEntries = fat->fatEntryCount;
+ unsigned int newSize = currentNumberOfFatEntries + fat->numberOfEntriesInFatSector;
+ for(i = currentNumberOfFatEntries; i < newSize; ++i)
+ {
+ unsigned int fatEntry = binaryReadUInt32(file);
+ fat->fatEntries[i] = fatEntry;
+ }
+ fat->fatEntryCount = newSize;
+}
+
+void bcf_file_fat_free(bcf_file_fat* fat)
+{
+ free(fat);
+ fat = 0;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/compound-file-fat.h b/Software/Visual_Studio/Embroidery/libembroidery/compound-file-fat.h
new file mode 100644
index 000000000..17c5cb24c
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/compound-file-fat.h
@@ -0,0 +1,30 @@
+/*! @file compound-file-fat.h */
+#ifndef COMPOUND_FILE_FAT_H
+#define COMPOUND_FILE_FAT_H
+
+#include "emb-file.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _bcf_file_fat
+{
+ int fatEntryCount;
+ unsigned int fatEntries[255]; /* maybe make this dynamic */
+ unsigned int numberOfEntriesInFatSector;
+} bcf_file_fat;
+
+extern EMB_PRIVATE bcf_file_fat* EMB_CALL bcfFileFat_create(const unsigned int sectorSize);
+extern EMB_PRIVATE void EMB_CALL loadFatFromSector(bcf_file_fat* fat, EmbFile* file);
+extern EMB_PRIVATE void EMB_CALL bcf_file_fat_free(bcf_file_fat* fat);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* COMPOUND_FILE_FAT_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/compound-file-header.c b/Software/Visual_Studio/Embroidery/libembroidery/compound-file-header.c
new file mode 100644
index 000000000..ed349dbc8
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/compound-file-header.c
@@ -0,0 +1,42 @@
+#include "compound-file-header.h"
+#include "helpers-binary.h"
+#include <string.h>
+#include <stdio.h>
+
+bcf_file_header bcfFileHeader_read(EmbFile* file)
+{
+ bcf_file_header header;
+ binaryReadBytes(file, header.signature, 8);
+ binaryReadBytes(file, header.CLSID, 16);
+ header.minorVersion = (unsigned short)binaryReadUInt16(file);
+ header.majorVersion = (unsigned short)binaryReadUInt16(file);
+ header.byteOrder = (unsigned short)binaryReadUInt16(file);
+ header.sectorShift = (unsigned short)binaryReadUInt16(file);
+ header.miniSectorShift = (unsigned short)binaryReadUInt16(file);
+ header.reserved1 = (unsigned short)binaryReadUInt16(file);
+ header.reserved2 = (unsigned int)binaryReadUInt32(file);
+ header.numberOfDirectorySectors = (unsigned int)binaryReadUInt32(file);
+ header.numberOfFATSectors = (unsigned int)binaryReadUInt32(file);
+ header.firstDirectorySectorLocation = (unsigned int)binaryReadUInt32(file);
+ header.transactionSignatureNumber = (unsigned int)binaryReadUInt32(file);
+ header.miniStreamCutoffSize = (unsigned int)binaryReadUInt32(file);
+ header.firstMiniFATSectorLocation = (unsigned int)binaryReadUInt32(file);
+ header.numberOfMiniFatSectors = (unsigned int)binaryReadUInt32(file);
+ header.firstDifatSectorLocation = (unsigned int)binaryReadUInt32(file);
+ header.numberOfDifatSectors = (unsigned int)binaryReadUInt32(file);
+ return header;
+}
+static const int supportedMinorVersion = 0x003E;
+static const int littleEndianByteOrderMark = 0xFFFE;
+
+int bcfFileHeader_isValid(bcf_file_header header)
+{
+ if(memcmp(header.signature, "\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1", 8) != 0)
+ {
+ printf("bad header signature\n");
+ return 0;
+ }
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/compound-file-header.h b/Software/Visual_Studio/Embroidery/libembroidery/compound-file-header.h
new file mode 100644
index 000000000..ae5b8eb11
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/compound-file-header.h
@@ -0,0 +1,44 @@
+/*! @file compound-file-header.h */
+#ifndef COMPOUND_FILE_HEADER_H
+#define COMPOUND_FILE_HEADER_H
+
+#include "emb-file.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _bcf_file_header
+{
+ unsigned char signature[8];
+ unsigned char CLSID[16]; /* TODO: this should be a separate type */
+ unsigned short minorVersion;
+ unsigned short majorVersion;
+ unsigned short byteOrder;
+ unsigned short sectorShift;
+ unsigned short miniSectorShift;
+ unsigned short reserved1;
+ unsigned int reserved2;
+ unsigned int numberOfDirectorySectors;
+ unsigned int numberOfFATSectors;
+ unsigned int firstDirectorySectorLocation;
+ unsigned int transactionSignatureNumber;
+ unsigned int miniStreamCutoffSize;
+ unsigned int firstMiniFATSectorLocation;
+ unsigned int numberOfMiniFatSectors;
+ unsigned int firstDifatSectorLocation;
+ unsigned int numberOfDifatSectors;
+} bcf_file_header;
+
+extern EMB_PRIVATE bcf_file_header EMB_CALL bcfFileHeader_read(EmbFile* file);
+extern EMB_PRIVATE int EMB_CALL bcfFileHeader_isValid(bcf_file_header header);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* COMPOUND_FILE_HEADER_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/compound-file.c b/Software/Visual_Studio/Embroidery/libembroidery/compound-file.c
new file mode 100644
index 000000000..370c14675
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/compound-file.c
@@ -0,0 +1,143 @@
+#include "compound-file.h"
+#include "compound-file-difat.h"
+#include "compound-file-header.h"
+#include "compound-file-fat.h"
+#include "compound-file-common.h"
+#include "emb-logging.h"
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+static unsigned int sizeOfDirectoryEntry = 128;
+
+static unsigned int sectorSize(bcf_file* bcfFile)
+{
+ /* version 3 uses 512 byte */
+ if(bcfFile->header.majorVersion == 3)
+ {
+ return 512;
+ }
+ else if(bcfFile->header.majorVersion == 4)
+ {
+ return 4096;
+ }
+ return 4096;
+}
+
+static int haveExtraDIFATSectors(bcf_file* file)
+{
+ return (int)(numberOfEntriesInDifatSector(file->difat) > 0);
+}
+
+static int seekToOffset(EmbFile* file, const unsigned int offset)
+{
+ return embFile_seek(file, offset, SEEK_SET);
+}
+
+static int seekToSector(bcf_file* bcfFile, EmbFile* file, const unsigned int sector)
+{
+ unsigned int offset = sector * sectorSize(bcfFile) + sectorSize(bcfFile);
+ return seekToOffset(file, offset);
+}
+
+static void parseDIFATSectors(EmbFile* file, bcf_file* bcfFile)
+{
+ unsigned int numberOfDifatEntriesStillToRead = bcfFile->header.numberOfFATSectors - NumberOfDifatEntriesInHeader;
+ unsigned int difatSectorNumber = bcfFile->header.firstDifatSectorLocation;
+ while((difatSectorNumber != CompoundFileSector_EndOfChain) &&
+ (numberOfDifatEntriesStillToRead > 0 ))
+ {
+ seekToSector(bcfFile, file, difatSectorNumber);
+ difatSectorNumber = readFullSector(file, bcfFile->difat, &numberOfDifatEntriesStillToRead);
+ }
+}
+
+int bcfFile_read(EmbFile* file, bcf_file* bcfFile)
+{
+ unsigned int i, numberOfDirectoryEntriesPerSector, directorySectorToReadFrom;
+
+ bcfFile->header = bcfFileHeader_read(file);
+ if(!bcfFileHeader_isValid(bcfFile->header))
+ {
+ printf( "Failed to parse header\n" );
+ return 0;
+ }
+
+ bcfFile->difat = bcf_difat_create(file, bcfFile->header.numberOfFATSectors, sectorSize(bcfFile));
+ if(haveExtraDIFATSectors(bcfFile))
+ {
+ parseDIFATSectors(file, bcfFile);
+ }
+
+ bcfFile->fat = bcfFileFat_create(sectorSize(bcfFile));
+ for(i = 0; i < bcfFile->header.numberOfFATSectors; ++i)
+ {
+ unsigned int fatSectorNumber = bcfFile->difat->fatSectorEntries[i];
+ seekToSector(bcfFile, file, fatSectorNumber);
+ loadFatFromSector(bcfFile->fat, file);
+ }
+
+ numberOfDirectoryEntriesPerSector = sectorSize(bcfFile) / sizeOfDirectoryEntry;
+ bcfFile->directory = CompoundFileDirectory(numberOfDirectoryEntriesPerSector);
+ directorySectorToReadFrom = bcfFile->header.firstDirectorySectorLocation;
+ while(directorySectorToReadFrom != CompoundFileSector_EndOfChain)
+ {
+ seekToSector(bcfFile, file, directorySectorToReadFrom);
+ readNextSector(file, bcfFile->directory);
+ directorySectorToReadFrom = bcfFile->fat->fatEntries[directorySectorToReadFrom];
+ }
+
+ return 1;
+}
+
+EmbFile* GetFile(bcf_file* bcfFile, EmbFile* file, char* fileToFind)
+{
+ int filesize, sectorSize, currentSector, sizeToWrite, currentSize, totalSectors, i;
+ char* input = 0;
+ EmbFile* fileOut = embFile_tmpfile();
+ bcf_directory_entry* pointer = bcfFile->directory->dirEntries;
+ while(pointer)
+ {
+ if(strcmp(fileToFind, pointer->directoryEntryName) == 0)
+ break;
+ pointer = pointer->next;
+ }
+ filesize = pointer->streamSize;
+ sectorSize = bcfFile->difat->sectorSize;
+ input = (char*)malloc(sectorSize);
+ if(!input) { embLog_error("compound-file.c GetFile(), cannot allocate memory for input\n"); } /* TODO: avoid crashing. null pointer will be accessed */
+ currentSize = 0;
+ currentSector = pointer->startingSectorLocation;
+ totalSectors = (int)ceil((float)filesize / sectorSize);
+ for(i = 0; i < totalSectors; i++)
+ {
+ seekToSector(bcfFile, file, currentSector);
+ sizeToWrite = filesize - currentSize;
+ if(sectorSize < sizeToWrite)
+ {
+ sizeToWrite = sectorSize;
+ }
+ embFile_read(input, 1, sizeToWrite, file);
+ embFile_write(input, 1, sizeToWrite, fileOut);
+ currentSize += sizeToWrite;
+ currentSector = bcfFile->fat->fatEntries[currentSector];
+ }
+ free(input);
+ input = 0;
+ return fileOut;
+}
+
+void bcf_file_free(bcf_file* bcfFile)
+{
+ bcf_file_difat_free(bcfFile->difat);
+ bcfFile->difat = 0;
+ bcf_file_fat_free(bcfFile->fat);
+ bcfFile->fat = 0;
+ bcf_directory_free(bcfFile->directory);
+ bcfFile->directory = 0;
+ free(bcfFile);
+ bcfFile = 0;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/compound-file.h b/Software/Visual_Studio/Embroidery/libembroidery/compound-file.h
new file mode 100644
index 000000000..72cbe1d81
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/compound-file.h
@@ -0,0 +1,35 @@
+/*! @file compound-file.h */
+#ifndef COMPOUND_FILE_H
+#define COMPOUND_FILE_H
+
+#include "compound-file-difat.h"
+#include "compound-file-directory.h"
+#include "compound-file-fat.h"
+#include "compound-file-header.h"
+#include "emb-file.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _bcf_file
+{
+ bcf_file_header header; /*! The header for the CompoundFile */
+ bcf_file_difat* difat; /*! The "Double Indirect FAT" for the CompoundFile */
+ bcf_file_fat* fat; /*! The File Allocation Table for the Compound File */
+ bcf_directory* directory; /*! The directory for the CompoundFile */
+} bcf_file;
+
+extern EMB_PRIVATE int EMB_CALL bcfFile_read(EmbFile* file, bcf_file* bcfFile);
+extern EMB_PRIVATE EmbFile* EMB_CALL GetFile(bcf_file* bcfFile, EmbFile* file, char* fileToFind);
+extern EMB_PRIVATE void EMB_CALL bcf_file_free(bcf_file* bcfFile);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* COMPOUND_FILE_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-arc.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-arc.c
new file mode 100644
index 000000000..08c636124
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-arc.c
@@ -0,0 +1,76 @@
+#include "emb-arc.h"
+#include "emb-logging.h"
+#include <stdlib.h>
+
+/* Returns an EmbArcObject. It is created on the stack. */
+EmbArcObject embArcObject_make(double sx, double sy, double mx, double my, double ex, double ey)
+{
+ EmbArcObject stackArcObj;
+ stackArcObj.arc.startX = sx;
+ stackArcObj.arc.startY = sy;
+ stackArcObj.arc.midX = mx;
+ stackArcObj.arc.midY = my;
+ stackArcObj.arc.endX = ex;
+ stackArcObj.arc.endY = ey;
+ return stackArcObj;
+}
+
+/* Returns a pointer to an EmbArcObject. It is created on the heap. The caller is responsible for freeing the allocated memory. */
+EmbArcObject* embArcObject_create(double sx, double sy, double mx, double my, double ex, double ey)
+{
+ EmbArcObject* heapArcObj = (EmbArcObject*)malloc(sizeof(EmbArcObject));
+ if(!heapArcObj) return 0;
+ heapArcObj->arc.startX = sx;
+ heapArcObj->arc.startY = sy;
+ heapArcObj->arc.midX = mx;
+ heapArcObj->arc.midY = my;
+ heapArcObj->arc.endX = ex;
+ heapArcObj->arc.endY = ey;
+ return heapArcObj;
+}
+
+EmbArcObjectList* embArcObjectList_add(EmbArcObjectList* pointer, EmbArcObject data)
+{
+ if(!pointer) { embLog_error("emb-arc.c embArcObjectList_add(), pointer argument is null\n"); return 0; }
+ if(pointer->next) { embLog_error("emb-arc.c embArcObjectList_add(), pointer->next should be null\n"); return 0; }
+ pointer->next = (EmbArcObjectList*)malloc(sizeof(EmbArcObjectList));
+ if(!pointer->next) { embLog_error("emb-arc.c embArcObjectList_add(), cannot allocate memory for pointer->next\n"); return 0; }
+ pointer = pointer->next;
+ pointer->arcObj = data;
+ pointer->next = 0;
+ return pointer;
+}
+
+int embArcObjectList_count(EmbArcObjectList* pointer)
+{
+ int i = 1;
+ if(!pointer) return 0;
+ while(pointer->next)
+ {
+ pointer = pointer->next;
+ i++;
+ }
+ return i;
+}
+
+int embArcObjectList_empty(EmbArcObjectList* pointer)
+{
+ if(!pointer)
+ return 1;
+ return 0;
+}
+
+void embArcObjectList_free(EmbArcObjectList* pointer)
+{
+ EmbArcObjectList* tempPointer = pointer;
+ EmbArcObjectList* nextPointer = 0;
+ while(tempPointer)
+ {
+ nextPointer = tempPointer->next;
+ free(tempPointer);
+ tempPointer = nextPointer;
+ }
+ pointer = 0;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-arc.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-arc.h
new file mode 100644
index 000000000..ec54ad779
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-arc.h
@@ -0,0 +1,54 @@
+/*! @file emb-arc.h */
+#ifndef EMB_ARC_H
+#define EMB_ARC_H
+
+#include "emb-color.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct EmbArc_
+{
+ double startX; /* absolute position (not relative) */
+ double startY;
+
+ double midX; /* absolute position (not relative) */
+ double midY;
+
+ double endX; /* absolute position (not relative) */
+ double endY;
+} EmbArc;
+
+typedef struct EmbArcObject_
+{
+ EmbArc arc;
+
+ /* Properties */
+ int lineType;
+ EmbColor color;
+} EmbArcObject;
+
+extern EMB_PUBLIC EmbArcObject EMB_CALL embArcObject_make(double sx, double sy, double mx, double my, double ex, double ey);
+extern EMB_PUBLIC EmbArcObject* EMB_CALL embArcObject_create(double sx, double sy, double mx, double my, double ex, double ey);
+
+typedef struct EmbArcObjectList_
+{
+ EmbArcObject arcObj;
+ struct EmbArcObjectList_* next;
+} EmbArcObjectList;
+
+extern EMB_PUBLIC EmbArcObjectList* EMB_CALL embArcObjectList_add(EmbArcObjectList* pointer, EmbArcObject data);
+extern EMB_PUBLIC int EMB_CALL embArcObjectList_count(EmbArcObjectList* pointer);
+extern EMB_PUBLIC int EMB_CALL embArcObjectList_empty(EmbArcObjectList* pointer);
+extern EMB_PUBLIC void EMB_CALL embArcObjectList_free(EmbArcObjectList* pointer);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_ARC_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-circle.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-circle.c
new file mode 100644
index 000000000..15d18ab14
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-circle.c
@@ -0,0 +1,106 @@
+#include "emb-circle.h"
+#include "emb-logging.h"
+#include <stdlib.h>
+
+/**************************************************/
+/* EmbCircle */
+/**************************************************/
+
+double embCircle_centerX(EmbCircle circle)
+{
+ return circle.centerX;
+}
+
+double embCircle_centerY(EmbCircle circle)
+{
+ return circle.centerY;
+}
+
+double embCircle_radius(EmbCircle circle)
+{
+ return circle.radius;
+}
+
+/**************************************************/
+/* EmbCircleObject */
+/**************************************************/
+
+/* Returns an EmbCircleObject. It is created on the stack. */
+EmbCircleObject embCircleObject_make(double cx, double cy, double r)
+{
+ EmbCircleObject stackCircleObj;
+ stackCircleObj.circle.centerX = cx;
+ stackCircleObj.circle.centerY = cy;
+ stackCircleObj.circle.radius = r;
+ return stackCircleObj;
+}
+
+/* Returns a pointer to an EmbCircleObject. It is created on the heap. The caller is responsible for freeing the allocated memory. */
+EmbCircleObject* embCircleObject_create(double cx, double cy, double r)
+{
+ EmbCircleObject* heapCircleObj = (EmbCircleObject*)malloc(sizeof(EmbCircleObject));
+ if(!heapCircleObj) { embLog_error("emb-circle.c embCircleObject_create(), cannot allocate memory for heapCircleObj\n"); return 0; }
+ heapCircleObj->circle.centerX = cx;
+ heapCircleObj->circle.centerY = cy;
+ heapCircleObj->circle.radius = r;
+ return heapCircleObj;
+}
+
+/**************************************************/
+/* EmbCircleObjectList */
+/**************************************************/
+
+EmbCircleObjectList* embCircleObjectList_create(EmbCircleObject data)
+{
+ EmbCircleObjectList* heapCircleObjList = (EmbCircleObjectList*)malloc(sizeof(EmbCircleObjectList));
+ if(!heapCircleObjList) { embLog_error("emb-circle.c embCircleObjectList_create(), cannot allocate memory for heapCircleObjList\n"); return 0; }
+ heapCircleObjList->circleObj = data;
+ heapCircleObjList->next = 0;
+ return heapCircleObjList;
+}
+
+EmbCircleObjectList* embCircleObjectList_add(EmbCircleObjectList* pointer, EmbCircleObject data)
+{
+ if(!pointer) { embLog_error("emb-circle.c embCircleObjectList_add(), pointer argument is null\n"); return 0; }
+ if(pointer->next) { embLog_error("emb-circle.c embCircleObjectList_add(), pointer->next should be null\n"); return 0; }
+ pointer->next = (EmbCircleObjectList*)malloc(sizeof(EmbCircleObjectList));
+ if(!pointer->next) { embLog_error("emb-circle.c embCircleObjectList_add(), cannot allocate memory for pointer->next\n"); return 0; }
+ pointer = pointer->next;
+ pointer->circleObj = data;
+ pointer->next = 0;
+ return pointer;
+}
+
+int embCircleObjectList_count(EmbCircleObjectList* pointer)
+{
+ int i = 1;
+ if(!pointer) return 0;
+ while(pointer->next)
+ {
+ pointer = pointer->next;
+ i++;
+ }
+ return i;
+}
+
+int embCircleObjectList_empty(EmbCircleObjectList* pointer)
+{
+ if(!pointer)
+ return 1;
+ return 0;
+}
+
+void embCircleObjectList_free(EmbCircleObjectList* pointer)
+{
+ EmbCircleObjectList* tempPointer = pointer;
+ EmbCircleObjectList* nextPointer = 0;
+ while(tempPointer)
+ {
+ nextPointer = tempPointer->next;
+ free(tempPointer);
+ tempPointer = nextPointer;
+ }
+ pointer = 0;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-circle.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-circle.h
new file mode 100644
index 000000000..cffb827c1
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-circle.h
@@ -0,0 +1,54 @@
+/*! @file emb-circle.h */
+#ifndef EMB_CIRCLE_H
+#define EMB_CIRCLE_H
+
+#include "emb-color.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct EmbCircle_
+{
+ double centerX;
+ double centerY;
+ double radius;
+} EmbCircle;
+
+extern EMB_PUBLIC double EMB_CALL embCircle_centerX(EmbCircle circle);
+extern EMB_PUBLIC double EMB_CALL embCircle_centerY(EmbCircle circle);
+extern EMB_PUBLIC double EMB_CALL embCircle_radius(EmbCircle circle);
+
+typedef struct EmbCircleObject_
+{
+ EmbCircle circle;
+
+ /* Properties */
+ int lineType;
+ EmbColor color;
+} EmbCircleObject;
+
+extern EMB_PUBLIC EmbCircleObject EMB_CALL embCircleObject_make(double cx, double cy, double r);
+extern EMB_PUBLIC EmbCircleObject* EMB_CALL embCircleObject_create(double cx, double cy, double r);
+
+typedef struct EmbCircleObjectList_
+{
+ EmbCircleObject circleObj;
+ struct EmbCircleObjectList_* next;
+} EmbCircleObjectList;
+
+extern EMB_PUBLIC EmbCircleObjectList* EMB_CALL embCircleObjectList_create(EmbCircleObject data);
+extern EMB_PUBLIC EmbCircleObjectList* EMB_CALL embCircleObjectList_add(EmbCircleObjectList* pointer, EmbCircleObject data);
+extern EMB_PUBLIC int EMB_CALL embCircleObjectList_count(EmbCircleObjectList* pointer);
+extern EMB_PUBLIC int EMB_CALL embCircleObjectList_empty(EmbCircleObjectList* pointer);
+extern EMB_PUBLIC void EMB_CALL embCircleObjectList_free(EmbCircleObjectList* pointer);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_CIRCLE_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-color.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-color.c
new file mode 100644
index 000000000..9e0431625
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-color.c
@@ -0,0 +1,52 @@
+#include "emb-color.h"
+#include "emb-logging.h"
+#include <stdlib.h>
+
+/* Returns an EmbColor. It is created on the stack. */
+EmbColor embColor_make(unsigned char r, unsigned char g, unsigned char b)
+{
+ EmbColor stackColor;
+ stackColor.r = r;
+ stackColor.g = g;
+ stackColor.b = b;
+ return stackColor;
+}
+
+/* Returns a pointer to an EmbColor. It is created on the heap. The caller is responsible for freeing the allocated memory. */
+EmbColor* embColor_create(unsigned char r, unsigned char g, unsigned char b)
+{
+ EmbColor* heapColor = (EmbColor*)malloc(sizeof(EmbColor));
+ if(!heapColor) { embLog_error("emb-color.c embColor_create(), cannot allocate memory for heapColor\n"); return 0; }
+ heapColor->r = r;
+ heapColor->g = g;
+ heapColor->b = b;
+ return heapColor;
+}
+
+/* Converts a 6 digit hex string (I.E. "00FF00") into an EmbColor and returns it. */
+EmbColor embColor_fromHexStr(char* val)
+{
+ EmbColor color;
+ char r[3];
+ char g[3];
+ char b[3];
+
+ r[0] = val[0];
+ r[1] = val[1];
+ r[2] = 0;
+
+ g[0] = val[2];
+ g[1] = val[3];
+ g[2] = 0;
+
+ b[0] = val[4];
+ b[1] = val[5];
+ b[2] = 0;
+
+ color.r = (unsigned char)strtol(r, 0, 16);
+ color.g = (unsigned char)strtol(g, 0, 16);
+ color.b = (unsigned char)strtol(b, 0, 16);
+ return color;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-color.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-color.h
new file mode 100644
index 000000000..e5da22202
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-color.h
@@ -0,0 +1,28 @@
+/*! @file emb-color.h */
+#ifndef EMB_COLOR_H
+#define EMB_COLOR_H
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct EmbColor_
+{
+ unsigned char r;
+ unsigned char g;
+ unsigned char b;
+} EmbColor;
+
+extern EMB_PUBLIC EmbColor EMB_CALL embColor_make(unsigned char r, unsigned char g, unsigned char b);
+extern EMB_PUBLIC EmbColor* EMB_CALL embColor_create(unsigned char r, unsigned char g, unsigned char b);
+extern EMB_PUBLIC EmbColor EMB_CALL embColor_fromHexStr(char* val);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_COLOR_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-compress.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-compress.c
new file mode 100644
index 000000000..4fbc59daa
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-compress.c
@@ -0,0 +1,1112 @@
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "emb-compress.h"
+#include "emb-thread.h"
+
+void husExpand(unsigned char* input, unsigned char* output, int compressedSize, int _269)
+{
+ currentPosition = 0;
+ outputPosition = 0;
+ currentIndex =0;
+ inputBufferSize = bufferSize;
+ mStatus = 0;
+ outputArray = output;
+ inputArray = input;
+ inputSize = bufferSize;
+
+ remainingBytes = compressedSize;
+ if(_269 > _137 || _269 < _138)
+ {
+ mStatus = -1;
+ _175 = 2;
+ }
+ else
+ {
+ _175 = (short) (1 << _269);
+ }
+ _172 = 0;
+ _243 = 0;
+ _246 = 0;
+ _244 = 0;
+ _245 = 0;
+
+ _176 = (short) (_175 - 1);
+
+ _166 = (unsigned char*)malloc(sizeof(unsigned char)*(_175+2));
+ if(_166) memset(_166, 0, (_175+2)*sizeof(unsigned char));
+ _240 = (unsigned short*)malloc(sizeof(unsigned short)*(_148));
+ if(_240) memset(_240, 0, (_148)*sizeof(unsigned short));
+ _241 = (unsigned short*)malloc(sizeof(unsigned short)*(_149));
+ if(_241) memset(_241, 0, (_149)*sizeof(unsigned short));
+ _189 = (unsigned short*)malloc(sizeof(unsigned short)*(2*_141-1));
+ if(_189) memset(_189, 0, (2*_141-1)*sizeof(unsigned short));
+ _190 = (unsigned short*)malloc(sizeof(unsigned short)*(2*_141-1));
+ if(_190) memset(_190, 0, (2*_141-1)*sizeof(unsigned short));
+ _180 = (unsigned char*)malloc(sizeof(unsigned char)*(_141));
+ if(_180) memset(_180, 0, (_141)*sizeof(unsigned char));
+ _181 = (unsigned char*)malloc(sizeof(unsigned char)*(_152));
+ if(_181) memset(_181, 0, (_152)*sizeof(unsigned char));
+
+ if( _166 == NULL ||
+ _189 == NULL ||
+ _190 == NULL ||
+ _180 == NULL ||
+ _181 == NULL ||
+ _240 == NULL ||
+ _241 == NULL ||
+ inputBuffer == NULL)
+ {
+ mStatus = -1;
+ }
+
+ husExpand_expand();
+ husExpand_cleanup();
+}
+
+void husExpand_cleanup(void)
+{
+ free(_166);
+ free(_189);
+ free(_190);
+ free(_180);
+ free(_181);
+ free(_240);
+ free(_241);
+}
+
+void husExpand_253(short _254,short _220,short _221)
+{
+ short _226,_203,_219;
+ unsigned short _283;
+ _219=husExpand_252(_220);
+ if(_219==0)
+ {
+ _203=husExpand_252(_220);
+ for(_226=0;_226<_254;_226++) _181[_226]=0;
+ for(_226=0;_226<256;_226++) _241[_226]=_203;
+ }
+ else
+ {
+ _226=0;
+ while(_226<_219)
+ {
+ _203=(short)(_182>>13);
+ if(_203==7)
+ {
+ _283=1U<<12;
+ while(_283&_182)
+ {
+ _283>>=1;
+ _203++;
+ }
+ }
+ husExpand_256((_203<7)?3:_203-3);
+ _181[_226++]=(unsigned char )_203;
+ if(_226==_221)
+ {
+ _203=husExpand_252(2);
+ while(--_203>=0) _181[_226++]=0;
+ }
+ }
+ while(_226<_254) _181[_226++]=0;
+ husExpand_258(_254,_181,8,_241,_149);
+ }
+}
+
+int husExpand_expand(void)
+{
+ short _200 = 0;
+ unsigned char* _278 = _166;
+ short _279 = _175;
+ short _280 = _176;
+ _243 = 0;
+ husExpand_251();
+
+ while(_243 < 5)
+ {
+ short _203;
+ if((_203 = (short) husExpand_249()) <= byte_MAX)
+ {
+ _278[_200] = (unsigned char) _203;
+ if(++_200 >= _279)
+ {
+ _200 = 0;
+ memcpy(&outputArray[outputPosition], _278, _279);
+ outputPosition += _279;
+ }
+ }
+ else
+ {
+ short _226;
+ short _276 = (short) (_203 - (byte_MAX + 1 - _135));
+ if(_276 == _144) break;
+ _226 = (short) ((_200 - husExpand_250() - 1) & _280);
+ if(_226 < _279 - _140 - 1 && _200 < _279 - _140 - 1)
+ {
+ while(--_276 >= 0) _278[_200++] = _278[_226++];
+ }
+ else
+ {
+ while(--_276 >= 0)
+ {
+ _278[_200] = _278[_226];
+ if(++_200 >= _279)
+ {
+ _200 = 0;
+ memcpy(&outputArray[outputPosition], _278, _279);
+ outputPosition += _279;
+ }
+ _226 = (short) ((_226 + 1) & _280);
+ }
+ }
+ }
+ }
+ if(_200 != 0)
+ {
+ memcpy(&outputArray[outputPosition], _278, _200);
+ outputPosition += _200;
+ }
+ return 0;
+}
+
+unsigned short husExpand_249(void)
+{
+ unsigned short _276,_283;
+ if(_244==0)
+ {
+ _244=husExpand_252(16);
+ husExpand_253(_145,_147,3);
+ husExpand_255();
+ husExpand_253(_142,_540,-1);
+ if(mStatus<0) return 0;
+ }
+ _244--;
+ _276=_240[_182>>4];
+ if(_276>=_141)
+ {
+ _283=1U<<3;
+ do
+ {
+ if(_182&_283) _276=_190[_276];
+ else _276=_189[_276];
+ _283>>=1;
+ }
+ while(_276 >= _141);
+ }
+ husExpand_256(_180[_276]);
+ return _276;
+}
+
+unsigned short husExpand_250(void)
+{
+ unsigned short _276,_283;
+ _276=_241[_182>>8];
+ if(_276>=_142)
+ {
+ _283=1U<<7;
+ do
+ {
+ if(_182&_283) _276=_190[_276];
+ else _276=_189[_276];
+ _283>>=1;
+ }
+ while(_276 >= _142);
+ }
+ husExpand_256(_181[_276]);
+ if(_276!=0)
+ {
+ _276--;
+ _276=(short)((1U<<_276)+husExpand_252(_276));
+ }
+ return _276;
+}
+
+void husExpand_251(void)
+{
+ _244 = 0;
+ husExpand_257();
+}
+
+unsigned short husExpand_252(int _219)
+{
+ unsigned short _284 = (unsigned short) (_182 >> (16 - _219));
+ husExpand_256(_219);
+ return _284;
+}
+
+void husExpand_255(void)
+{
+ short _226, _203;
+ short _219 = (short) husExpand_252(_143);
+ if(_219 == 0)
+ {
+ _203 = (short) husExpand_252(_143);
+ for(_226 = 0; _226 < _141; _226++) _180[_226] = 0;
+ for(_226 = 0; _226 < _148; _226++) _240[_226] = (unsigned short) _203;
+ }
+ else
+ {
+ _226 = 0;
+ while(_226 < _219)
+ {
+ _203 = (short) _241[_182 >> 8];
+ if(_203 >= _145)
+ {
+ unsigned short _283 = (unsigned short) 1U << 7;
+ do
+ {
+ if((_182 & _283) != 0)
+ {
+ _203 = (short) _190[_203];
+ }
+ else
+ {
+ _203 = (short) _189[_203];
+ }
+ _283 >>= 1;
+ }
+ while(_203 >= _145);
+ }
+ husExpand_256(_181[_203]);
+ if(_203 <= 2)
+ {
+ if(_203 == 0)
+ {
+ _203 = 1;
+ }
+ else
+ {
+ if(_203 == 1)
+ {
+ _203 = (short) (husExpand_252(4) + 3);
+ }
+ else
+ {
+ _203 = (short) (husExpand_252(_143) + 20);
+ }
+ }
+ while(--_203 >= 0)
+ {
+ _180[_226++] = 0;
+ }
+ }
+ else
+ {
+ _180[_226++] = (unsigned char) (_203 - 2);
+ }
+ }
+ while(_226 < _141)
+ {
+ _180[_226++] = 0;
+ }
+ husExpand_258(_141, _180, 12, _240, _148);
+ }
+}
+
+void husExpand_256(int _219)
+{
+ while(_219 > _172)
+ {
+ _219 -= _172;
+ _182 = (unsigned short) ((_182 << _172) + (_245 >> (8 - _172)));
+ if(_246 <= 0)
+ {
+ currentIndex = 0;
+
+ if(remainingBytes >= 0 && remainingBytes < bufferSize)
+ {
+ inputBuffer = &inputArray[currentPosition];
+ currentPosition += remainingBytes;
+ _246 = (short)remainingBytes;
+ remainingBytes -= _246;
+ inputBufferSize = _246;
+ }
+ else
+ {
+ inputBuffer = &inputArray[currentPosition];
+ currentPosition += bufferSize;
+ _246 = bufferSize;
+ inputBufferSize = _246;
+ }
+ if(_246 <= 0) _243++;
+ }
+ _245 = inputBuffer[currentIndex++];
+ _246--;
+ _172 = 8;
+ }
+ _172 = (short) (_172 - _219);
+ _182 = (unsigned short) ((_182 << _219) + (_245 >> (8 - _219)));
+ _245 <<= _219;
+}
+
+void husExpand_257(void)
+{
+ _182 = 0;
+ _245 = 0;
+ _172 = 0;
+ _246 = 0;
+ husExpand_256(16);
+}
+
+void husExpand_258(int _259, unsigned char* _260, int _261, unsigned short* _262, unsigned short _263)
+{
+ unsigned short _277[17],_287[17],_288[18],*_204;
+ unsigned int _226,_289,_209,_290,_291,_292,_293,_283;
+ _288[0] = 0;
+ _277[0] = 0;
+ _287[0] = 0;
+
+ for(_226=1;_226<=16;_226++) _277[_226]=0;
+ for(_226=0;(int)_226<_259;_226++) _277[_260[_226]]++;
+ _288[1]=0;
+ for(_226=1;_226<=16;_226++) _288[_226+1]=(unsigned short)(_288[_226]+(_277[_226]<<(16-_226)));
+ if(_288[17] != (unsigned short)(1U<<16))
+ {
+ mStatus = -1;
+ _243=10;
+ return;
+ }
+ _291=16-_261;
+ for(_226=1;(int )_226<=_261;_226++)
+ {
+ _288[_226]>>=_291;
+ _287[_226]=(unsigned short )(1U<<(_261-_226));
+ }
+ while(_226<=16)
+ {
+ _287[_226]=(unsigned short )(1U<<(16-_226));
+ _226++;
+ }
+ _226=_288[_261+1]>>_291;
+ if(_226!=(unsigned short )(1U<<16))
+ {
+ _289=1U<<_261;
+ while(_226!=_289) _262[_226++]=0;
+ }
+ _292=_259;
+ _283=1U<<(15-_261);
+ for(_290=0;(int)_290<_259;_290++)
+ {
+ if((_209=_260[_290])==0) continue;
+ _293=_288[_209]+_287[_209];
+ if((int)_209<=_261)
+ {
+ if(_293 > _263)
+ {
+ mStatus = -1;
+ _243 = 10;
+ return;
+ }
+ for(_226=_288[_209];_226<_293;_226++) _262[_226]=(unsigned short )_290;
+ }
+ else
+ {
+ _289=_288[_209];
+ _204=&_262[_289>>_291];
+ _226=_209-_261;
+ while(_226!=0)
+ {
+ if(*_204==0)
+ {
+ _190[_292]=_189[_292]=0;
+ *_204=(unsigned short )_292++;
+ }
+ if(_289&_283) _204=&_190[*_204];
+ else _204=&_189[*_204];
+ _289<<=1;
+ _226--;
+ }
+ *_204=(unsigned short )_290;
+ }
+ _288[_209]=(unsigned short )_293;
+ }
+}
+
+/*****************************************
+* HUS Compress Functions
+****************************************/
+
+int husCompress(unsigned char* _266, unsigned long _inputSize, unsigned char* _267, int _269, int _235)
+{
+ int returnVal;
+ inputArray = _266;
+ outputArray = _267;
+ _531 = _235;
+ if(_269 > _137 || _269 < _138)
+ {
+ mStatus = -1;
+ _175 = 2;
+ }
+ else
+ {
+ _175 = (short)(1<<_269);
+ }
+ _176 = (short)(_175-1);
+
+ _166 = (unsigned char*)malloc(sizeof(unsigned char)*(_175+_140+2));
+ if(_166) memset(_166, 0, (_175+_140+2)*sizeof(unsigned char));
+ _163 = (short*)malloc(sizeof(short)*(_175+_153));
+ if(_163) memset(_163, 0, (_175+_153)*sizeof(short));
+ _164 = (short*)malloc(sizeof(short)*(_175));
+ if(_164) memset(_164, 0, (_175)*sizeof(short));
+ _165 = (unsigned char*)malloc(sizeof(unsigned char)*(_155));
+ if(_165) memset(_165, 0, (_155)*sizeof(unsigned char));
+ _179 = (unsigned char*)malloc(sizeof(unsigned char)*(_156));
+ if(_179) memset(_179, 0, (_156)*sizeof(unsigned char));
+ _189 = (unsigned short*)malloc(sizeof(unsigned short)*(2*_141-1));
+ if(_189) memset(_189, 0, (2*_141-1)*sizeof(unsigned short));
+ _190 = (unsigned short*)malloc(sizeof(unsigned short)*(2*_141-1));
+ if(_190) memset(_190, 0, (2*_141-1)*sizeof(unsigned short));
+ _177 = (short*)malloc(sizeof(short)*(_141+1));
+ if(_177) memset(_177, 0, (_141+1)*sizeof(short));
+ _180 = (unsigned char*)malloc(sizeof(unsigned char)*(_141));
+ if(_180) memset(_180, 0, (_141)*sizeof(unsigned char));
+ _191 = (unsigned short*)malloc(sizeof(unsigned short)*(2*_141-1));
+ if(_191) memset(_191, 0, (2*_141-1)*sizeof(unsigned short));
+ _192 = (unsigned short*)malloc(sizeof(unsigned short)*(_141));
+ if(_192) memset(_192, 0, (_141)*sizeof(unsigned short));
+ _181 = (unsigned char*)malloc(sizeof(unsigned char)*(_152));
+ if(_181) memset(_181, 0, (_152)*sizeof(unsigned char));
+ _193 = (unsigned short*)malloc(sizeof(unsigned short)*(2*_142-1));
+ if(_193) memset(_193, 0, (2*_142-1)*sizeof(unsigned short));
+ _194 = (unsigned short*)malloc(sizeof(unsigned short)*(_152));
+ if(_194) memset(_194, 0, (_152)*sizeof(unsigned short));
+
+ if(!_166|| !_163|| !_164|| !_165|| !_179|| !_189|| !_190|| !_177|| !_180|| !_191|| !_192|| !_181|| !_193|| !_194)
+ {
+ mStatus = -1;
+ }
+ _533 = 0;
+ _534 = _inputSize;
+ inputLength = _inputSize;
+ inputPosition = 0;
+ outputPosition = 0;
+
+ returnVal = husCompress_compress();
+ husCompress_cleanup();
+ return returnVal;
+}
+
+void husCompress_cleanup(void)
+{
+ free(_166);
+ free(_163);
+ free(_164);
+ free(_165);
+ free(_179);
+ free(_189);
+ free(_190);
+ free(_177);
+ free(_180);
+ free(_191);
+ free(_192);
+ free(_181);
+ free(_193);
+ free(_194);
+}
+
+void husCompress_223(short _203)
+{
+ husCompress_208(_180[_203], _192[_203]);
+}
+
+int husCompress_compress(void)
+{
+ short _209;
+ short _201;
+ short _200;
+ short s;
+ int _231;
+ unsigned char* _278;
+ short _280;
+ short _279;
+ _278 = _166;
+ _280 = _176;
+ _279 = _175;
+ _231 = 0;
+ husCompress_196();
+ husCompress_198();
+ _200 = 0;
+
+ memcpy(_278, &inputArray[inputPosition], _279);
+
+ inputPosition += _279;
+ if(inputPosition > inputLength)
+ {
+ _209 = (short)(inputLength - inputPosition);
+ }
+ else
+ {
+ _209 = _279;
+ }
+ s = (short)(_209&_280);
+ _169 = 0;
+ _168 = 0;
+ _201 = (short)(((_278[_200]<<_154)^(_278[_200+1]))&(_153-1));
+ _201 = (short)(husCompress_445(_200,_201)+_279);
+ while(_209 > _140 + 4 && !_170)
+ {
+ husCompress_199(_200, _201);
+ if(_168 < _135)
+ {
+ husCompress_202(_278[_200], 0);
+ husCompress_447(_200, _201);
+ _200++;
+ _201 = (short)(husCompress_445(_200,_201)+_279);
+ _209--;
+ }
+ else
+ {
+ _209 -= _168;
+ husCompress_202((unsigned short)(_168+(UCHAR_MAX+1-_135)), _169);
+ while(--_168 >= 0)
+ {
+ husCompress_447(_200, _201);
+ _200++;
+ _201 = (short)(husCompress_445(_200, _201) + _279);
+ }
+ }
+ }
+ for(; _209 < _140; _209++)
+ {
+ int _203;
+ if(inputPosition >= inputLength)
+ break;
+ _203 = (int)(unsigned char)inputArray[inputPosition];
+ inputPosition += 1;
+ _278[s] = (unsigned char)_203;
+ if(s < _140 - 1)
+ _278[s + _279] = _278[s];
+ husCompress_448(s);
+ s = (short)((s + 1)&(_280));
+ }
+ while(_209 > 0 && !_170)
+ {
+ husCompress_199(_200, _201);
+ if(_168 > _209)
+ _168 = _209;
+ if(_168 < _135)
+ {
+ _168 = 1;
+ husCompress_202(_278[_200], 0);
+ }
+ else
+ husCompress_202((unsigned short)(_168+(UCHAR_MAX + 1 - _135)), _169);
+ while(--_168 >= 0)
+ {
+ int _203;
+ if(inputPosition >= inputLength)
+ break;
+ _203 = (int)(unsigned char) inputArray[inputPosition];
+ inputPosition += 1;
+ _278[s] = (unsigned char)_203;
+ if(s < _140 - 1)
+ _278[s+_279] = _278[s];
+ husCompress_448(s);
+ s = (short)((s + 1)&(_280));
+ husCompress_447(_200, _201);
+ _200 = (short)((_200 + 1)&(_280));
+ _201 = (short)(husCompress_445(_200, _201) + _279);
+ }
+ while(_168-- >= 0)
+ {
+ husCompress_447(_200, _201);
+ _200 = (short)((_200 + 1)&_280);
+ _201 = (short)(husCompress_445(_200, _201) + _279);
+ _209--;
+ }
+ if(mStatus < 0)
+ return 1;
+ }
+ if(!_170)
+ husCompress_202(_144+(UCHAR_MAX + 1 - _135), 0);
+ husCompress_197();
+ return outputPosition;
+}
+
+void husCompress_196(void)
+{
+ int i;
+ for(i = 0; i < _141; i++)
+ _191[i] = 0;
+ for(i = 0; i < _142; i++)
+ _193[i] = 0;
+ _173 = 0;
+ husCompress_205();
+ _170 = 0;
+ _185 = 1;
+ _184 = 0;
+ _186 = 0;
+ _165[0] = 0;
+ _183 = _155;
+ _183 -= (unsigned short)((3*CHAR_BIT)+6);
+}
+
+void husCompress_197(void)
+{
+ if(!_170)
+ husCompress_207();
+ husCompress_206();
+ _183 = 0;
+ _184 = 0;
+}
+
+void husCompress_198(void)
+{
+ int i;
+ short* _450;
+ _450 = &_163[_175];
+
+ for(i = _153; i > 0; i--)
+ *_450++ = _157;
+ _450 = _164;
+ for(i = _175; i > 0; i--)
+ *_450++ = _157;
+}
+
+void husCompress_199(short _200, short _201)
+{
+ unsigned char* _451;
+ unsigned char* _278;
+ short _226, _452, _204, _453;
+ _452 = _158;
+ _168 = 0;
+ _451 = &_166[_200];
+ _204 = _201;
+ while((_204 = _163[_204]) != _157)
+ {
+ if(--_452 < 0)
+ break;
+ _278 = &_166[_204];
+ if(_451[_168] != _278[_168])
+ continue;
+ if(_451[0] != _278[0])
+ continue;
+ if(_451[1] != _278[1])
+ continue;
+ if(_451[2] != _278[2])
+ continue;
+ for(_226 = 3; _226 < _140; _226++)
+ if(_451[_226]!=_278[_226])
+ break;
+ if(_226 > _168)
+ {
+ _453 = (short)(_200 - _204 - 1);
+ if(_453 < 0)
+ _453 += _175;
+ if(_453 >= _175)
+ break;
+ _169 = _453;
+ if((_168 = _226) >= _140)
+ break;
+ }
+ }
+}
+
+void husCompress_202(unsigned short _203, unsigned short _204)
+{
+ if((_185>>=1) == 0)
+ {
+ _185=1U<<(CHAR_BIT-1);
+ if(_184 >= _183)
+ {
+ husCompress_207();
+ if(_170)
+ return;
+ _184 = 0;
+ }
+ _186 = _184++;
+ _165[_186] = 0;
+ }
+ _165[_184++] = (unsigned char)_203;
+ _191[_203]++;
+ if(_203 >= (1U<<CHAR_BIT))
+ {
+ _165[_186] |= (unsigned char)_185;
+ _165[_184++] = (unsigned char)_204;
+ _165[_184++] = (unsigned char)(_204>>CHAR_BIT);
+ _203 = 0;
+ while(_204)
+ {
+ _203++;
+ _204>>=1;
+ }
+ _193[_203]++;
+ }
+}
+
+void husCompress_205(void)
+{
+ _172 = 0;
+ _182 = 0;
+ _171 = 0;
+}
+
+void husCompress_206(void)
+{
+ if(!_170)
+ {
+ husCompress_208(CHAR_BIT-1, 0);
+ if(_171)
+ {
+ husCompress_210();
+ }
+ }
+ _171 = 0;
+}
+
+void husCompress_207(void)
+{
+ unsigned int _226, _289, _229, _454, _455;
+ unsigned int _456 = 0;
+ unsigned short _217[2 * _145 - 1];
+ _229 = husCompress_211(_141, _191, _180, _192);
+ _455 = _191[_229];
+ husCompress_208(16, (unsigned short)_455);
+ if(_229 >= _141)
+ {
+ husCompress_216(_217);
+ _229 = husCompress_211(_145, _217, _181, _194);
+ if(_229 >= _145)
+ {
+ husCompress_218(_145, _147, 3);
+ }
+ else
+ {
+ husCompress_208(_147, 0);
+ husCompress_208(_147, (unsigned short)_229);
+ }
+ husCompress_222();
+ }
+ else
+ {
+ husCompress_208(_147, 0);
+ husCompress_208(_147, 0);
+ husCompress_208(_143, 0);
+ husCompress_208(_143, (unsigned short)_229);
+ }
+ _229 = husCompress_211(_142, _193, _181, _194);
+ if(_229 >= _142)
+ {
+ husCompress_218(_142, _540, -1);
+ }
+ else
+ {
+ husCompress_208(_540, 0);
+ husCompress_208(_540, (unsigned short )_229);
+ }
+ _454 = 0;
+ for(_226 = 0; _226 < _455; _226++)
+ {
+ if(_226 % CHAR_BIT == 0)
+ _456 = _165[_454++];
+ else
+ _456<<=1;
+ if(_456&(1U<<(CHAR_BIT-1)))
+ {
+ husCompress_223((short)(_165[_454++]+(1U<<CHAR_BIT)));
+ _289 = _165[_454++];
+ _289 += _165[_454++]<<CHAR_BIT;
+ husCompress_224((short)_289);
+ }
+ else
+ husCompress_223(_165[_454++]);
+ if(_170)
+ return;
+ }
+ for(_226 = 0; _226 < _141; _226++)
+ _191[_226] = 0;
+ for(_226 = 0; _226 < _142; _226++)
+ _193[_226] = 0;
+}
+
+void husCompress_208(int _209, unsigned short _203)
+{
+ _203<<=_133-_209;
+ _182|=(unsigned short)(_203>>_172);
+ if((_172 += (short)_209) >= 8)
+ {
+ if(_171 >= _156)
+ husCompress_210();
+ _179[_171++] = (unsigned char)(_182>>CHAR_BIT);
+ if((_172 = (unsigned short)(_172- CHAR_BIT))<CHAR_BIT)
+ _182<<=CHAR_BIT;
+ else
+ {
+ if(_171 >= _156)
+ husCompress_210();
+ _179[_171++] = (unsigned char)_182;
+ _172 = (unsigned short)(_172-CHAR_BIT);
+ _182 = (unsigned short)(_203<<(_209-_172));
+ }
+ }
+}
+
+void husCompress_210(void)
+{
+ if(_171 <= 0)
+ return;
+ if(_531 && (_533 += _171) >= _534)
+ _170 = 1;
+ else
+ {
+ memcpy(outputArray + outputPosition, _179, _171);
+ outputPosition += _171;
+ }
+ _171 = 0;
+}
+
+int husCompress_211(int _212, unsigned short* _213, unsigned char* _214, unsigned short* _215)
+{
+ int _226, _276, _289, _292;
+ short _227;
+ _174 = (short)_212;
+ _187 = _213;
+ _178 = _214;
+ _292 = _174;
+ _227 = 0;
+ _177[1] = 0;
+ for(_226 = 0; _226 < _174; _226++)
+ {
+ _178[_226] = 0;
+ if(_187[_226])
+ {
+ _177[++_227] = (short)_226;
+ }
+ }
+ if(_227 < 2)
+ {
+ _215[_177[1]]=0;
+ return _177[1];
+ }
+ for(_226 = _227/2; _226 >= 1; _226--)
+ {
+ husCompress_225(_226, _187, _177, _227);
+ }
+ _188 = _215;
+ do
+ {
+ _226 = _177[1];
+ if(_226 < _174)
+ {
+ *_188++=(unsigned short)_226;
+ }
+ _177[1] = _177[_227--];
+ husCompress_225(1, _187, _177, _227);
+ _276 = _177[1];
+ if(_276 < _174)
+ *_188++ = (unsigned short)_276;
+ _289 = _292++;
+ _187[_289] = (unsigned short)(_187[_226] + _187[_276]);
+ _177[1] = (short)_289;
+ husCompress_225(1, _187, _177, _227);
+ _189[_289] = (unsigned short)_226;
+ _190[_289] = (unsigned short)_276;
+ }
+ while(_227 > 1);
+ _188 = _215;
+ husCompress_228(_289);
+ husCompress_230(_212, _214, _215);
+ return _289;
+}
+
+void husCompress_216(unsigned short* _217)
+{
+ short _226, _289, _219, _277;
+ for(_226 = 0; _226 < _145; _226++)
+ _217[_226] = 0;
+ _219 = _141;
+ while(_219 > 0 && _180[_219-1] == 0)
+ _219--;
+ _226 = 0;
+ while(_226 < _219)
+ {
+ _289 = _180[_226++];
+ if(_289 == 0)
+ {
+ _277 = 1;
+ while(_226 < _219 && _180[_226] == 0)
+ {
+ _226++;
+ _277++;
+ }
+ if(_277 <= 2)
+ _217[0] += _277;
+ else if(_277 <= 18)
+ _217[1]++;
+ else if(_277 == 19)
+ {
+ _217[0]++;
+ _217[1]++;
+ }
+ else
+ _217[2]++;
+ }
+ else
+ {
+ _217[_289+2]++;
+ }
+ }
+}
+
+void husCompress_218(short _219, short _220, short _221)
+{
+ short _226, _289;
+ while(_219 > 0 && _181[_219-1] == 0)
+ _219--;
+ husCompress_208(_220, _219);
+ _226 = 0;
+ while(_226 < _219)
+ {
+ _289 = _181[_226++];
+ if(_289 <= 6)
+ {
+ husCompress_208(3, _289);
+ }
+ else
+ husCompress_208(_289-3, (unsigned short)(USHRT_MAX<<1));
+ if(_226 == _221)
+ {
+ while(_226 < 6 && _181[_226] == 0)
+ _226++;
+ husCompress_208(2, (unsigned short)(_226-3));
+ }
+ }
+}
+
+void husCompress_222(void)
+{
+ short _226, _289, _219, _277;
+ _219 = _141;
+ while(_219 > 0 && _180[_219-1] == 0)
+ _219--;
+ husCompress_208(_143, _219);
+ _226 = 0;
+ while(_226 < _219)
+ {
+ _289 = _180[_226++];
+ if(_289 == 0)
+ {
+ _277 = 1;
+ while(_226 < _219 && _180[_226] == 0)
+ {
+ _226++;
+ _277++;
+ }
+ if(_277 <= 2)
+ {
+ for(_289 = 0; _289 < _277; _289++)
+ husCompress_208(_181[0], _194[0]);
+ }
+ else if(_277 <= 18)
+ {
+ husCompress_208(_181[1], _194[1]);
+ husCompress_208(4, (unsigned short)(_277-3));
+ }
+ else if(_277 == 19)
+ {
+ husCompress_208(_181[0], _194[0]);
+ husCompress_208(_181[1], _194[1]);
+ husCompress_208(4, 15);
+ }
+ else
+ {
+ husCompress_208(_181[2], _194[2]);
+ husCompress_208(_143, (unsigned short)(_277-20));
+ }
+ }
+ else
+ husCompress_208(_181[_289+2], _194[_289+2]);
+ }
+}
+
+void husCompress_224(unsigned short _204)
+{
+ unsigned short _203, _457;
+ _203 = 0;
+ _457 = _204;
+ while(_457)
+ {
+ _203++;
+ _457>>=1;
+ }
+ husCompress_208(_181[_203], _194[_203]);
+ if(_203 > 1)
+ husCompress_208(_203-1, _204);
+}
+
+void husCompress_225(int _226, unsigned short* _187, short* _177, short _227)
+{
+ int _276, _289;
+ _289 = _177[_226];
+ while((_276 = 2 * _226) <= _227)
+ {
+ if(_276 < _227 && _187[_177[_276]] > _187[_177[_276+1]])
+ _276++;
+ if(_187[_289] <= _187[_177[_276]])
+ break;
+ _177[_226] = _177[_276];
+ _226 = _276;
+ }
+ _177[_226] = (unsigned short)_289;
+}
+
+void husCompress_228(int _229)
+{
+ int _226, _289;
+ unsigned int _458;
+ for(_226 = 0; _226 <= 16; _226++)
+ _167[_226] = 0;
+ husCompress_232(_229);
+ _458 = 0;
+ for(_226 = 16; _226 > 0; _226--)
+ _458+=_167[_226]<<(16-_226);
+ while(_458 != (1U<<16))
+ {
+ _167[16]--;
+ for(_226 = 15; _226 > 0; _226--)
+ {
+ if(_167[_226] != 0)
+ {
+ _167[_226]--;
+ _167[_226+1] = (unsigned short)(_167[_226+1]+2);
+ break;
+ }
+ }
+ _458--;
+ }
+ for(_226 = 16; _226 > 0; _226--)
+ {
+ _289 = _167[_226];
+ while(--_289 >= 0)
+ _178[*_188++] = (unsigned char)_226;
+ }
+}
+
+void husCompress_230(int _219, unsigned char* _209, unsigned short* _231)
+{
+ int _226;
+ unsigned short _288[18];
+ _288[1] = 0;
+ for(_226 = 1; _226 <= 16; _226++)
+ _288[_226+1] = (unsigned short)((_288[_226]+_167[_226])<<1);
+ for(_226 = 0; _226 < _219; _226++)
+ _231[_226] = _288[_209[_226]]++;
+}
+
+void husCompress_232(int _226)
+{
+ if(_226 < _174)
+ _167[(_173<16)?_173:16]++;
+ else
+ {
+ _173++;
+ husCompress_232(_189[_226]);
+ husCompress_232(_190[_226]);
+ _173--;
+ }
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-compress.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-compress.h
new file mode 100644
index 000000000..c1ed08f25
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-compress.h
@@ -0,0 +1,163 @@
+/*! @file emb-compress.h */
+#ifndef EMB_COMPRESS_H
+#define EMB_COMPRESS_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE void EMB_CALL husExpand(unsigned char* input, unsigned char* output, int compressedSize, int _269);
+extern EMB_PRIVATE int EMB_CALL husCompress(unsigned char* _266, unsigned long _inputSize, unsigned char* _267, int _269, int _235);
+
+/*****************************************
+ * HUS Expand/Compress Constants
+ ****************************************/
+#define _132 (CHAR_BIT*sizeof(unsigned short))
+#define _133 (16)
+#define _135 (3)
+#define _136 (16384)
+#define _137 (14)
+#define _138 (10)
+#define _139 (8)
+#define _140 (256)
+#define byte_MAX (255)
+#define _141 (byte_MAX + 1 + _140 - _135 + 1 + 1)
+#define _142 (_137 + 1)
+#define _143 (9)
+#define _144 (_140 + 1)
+#define _145 (_133 + 3)
+#define _147 (5)
+#define _148 (4096)
+#define _149 (256)
+
+#define _152 (_145)
+#define _153 (4096)
+#define _154 (4)
+#define _155 (8192)
+#define _156 (512)
+#define _157 (-1)
+#define _158 (128)
+#define _159 (512)
+#define _540 (5)
+#define bufferSize (512)
+
+/*****************************************
+ * HUS Expand/Compress Variables
+ ****************************************/
+short* _163;
+short* _164;
+unsigned char* _165;
+unsigned char* _166;
+unsigned short _167[17];
+short _168;
+short _169;
+short _170;
+short _171;
+short _172;
+short _173;
+short _174;
+short _175;
+short _176;
+short* _177;
+unsigned char* _178;
+unsigned char* _179;
+unsigned char* _180;
+unsigned char* _181;
+unsigned short _182;
+unsigned short _183;
+unsigned short _184;
+unsigned short _185;
+unsigned short _186;
+unsigned short* _187;
+unsigned short* _188;
+unsigned short* _189;
+unsigned short* _190;
+unsigned short* _191;
+unsigned short* _192;
+unsigned short* _193;
+unsigned short* _194;
+unsigned short* _240;
+unsigned short* _241;
+short _243;
+unsigned short _244;
+unsigned char _245;
+short _246;
+int _531;
+unsigned long _533;
+unsigned long _534;
+
+int mStatus;
+int currentIndex;
+long remainingBytes;
+int inputSize;
+int inputBufferSize;
+int inputLength;
+unsigned char* outputArray;
+unsigned char* inputArray;
+unsigned char* inputBuffer;
+int currentPosition;
+int inputPosition;
+int outputPosition;
+
+/*****************************************
+ * HUS Expand Functions
+ ****************************************/
+extern EMB_PRIVATE void EMB_CALL husExpand_258(int _259, unsigned char* _260, int _261, unsigned short* _262, unsigned short _263);
+extern EMB_PRIVATE void EMB_CALL husExpand_257(void);
+extern EMB_PRIVATE void EMB_CALL husExpand_256(int _219);
+extern EMB_PRIVATE void EMB_CALL husExpand_255(void);
+extern EMB_PRIVATE void EMB_CALL husExpand_253(short _254, short _220, short _221);
+extern EMB_PRIVATE unsigned short EMB_CALL husExpand_252(int _219);
+extern EMB_PRIVATE void EMB_CALL husExpand_251(void);
+extern EMB_PRIVATE unsigned short EMB_CALL husExpand_250(void);
+extern EMB_PRIVATE unsigned short EMB_CALL husExpand_249(void);
+
+extern EMB_PRIVATE void EMB_CALL husExpand(unsigned char* input, unsigned char* output, int compressedSize, int _269);
+extern EMB_PRIVATE int EMB_CALL husExpand_expand(void);
+extern EMB_PRIVATE void EMB_CALL husExpand_cleanup(void);
+
+/*****************************************
+ * HUS Compress Functions
+ ****************************************/
+extern EMB_PRIVATE void EMB_CALL husCompress_196(void);
+extern EMB_PRIVATE void EMB_CALL husCompress_197(void);
+extern EMB_PRIVATE void EMB_CALL husCompress_198(void);
+extern EMB_PRIVATE void EMB_CALL husCompress_199(short _200, short _201);
+extern EMB_PRIVATE void EMB_CALL husCompress_202(unsigned short _203, unsigned short _204);
+extern EMB_PRIVATE void EMB_CALL husCompress_205(void);
+extern EMB_PRIVATE void EMB_CALL husCompress_206(void);
+extern EMB_PRIVATE void EMB_CALL husCompress_207(void);
+extern EMB_PRIVATE void EMB_CALL husCompress_208(int _209, unsigned short _203);
+extern EMB_PRIVATE void EMB_CALL husCompress_210(void);
+extern EMB_PRIVATE int EMB_CALL husCompress_211(int _212, unsigned short* _213, unsigned char* _214, unsigned short* _215);
+extern EMB_PRIVATE void EMB_CALL husCompress_216(unsigned short* _217);
+extern EMB_PRIVATE void EMB_CALL husCompress_218(short _219, short _220, short _221);
+extern EMB_PRIVATE void EMB_CALL husCompress_222(void);
+extern EMB_PRIVATE void EMB_CALL husCompress_223(short _203);
+extern EMB_PRIVATE void EMB_CALL husCompress_224(unsigned short _204);
+extern EMB_PRIVATE void EMB_CALL husCompress_225(int _226, unsigned short* _187, short* _177, short _227);
+extern EMB_PRIVATE void EMB_CALL husCompress_228(int _229);
+extern EMB_PRIVATE void EMB_CALL husCompress_230(int _219, unsigned char* _209, unsigned short* _231);
+extern EMB_PRIVATE void EMB_CALL husCompress_232(int _226);
+
+/* extern EMB_PRIVATE int EMB_CALL husCompress(unsigned char* _266, unsigned long _inputSize, unsigned char* _267, int _269, int _235);
+extern EMB_PRIVATE int EMB_CALL husCompress(unsigned char* _233, unsigned long _inputSize, unsigned char* _202, int _234, int _235);*/
+extern EMB_PRIVATE void EMB_CALL husCompress_cleanup(void);
+extern EMB_PRIVATE int EMB_CALL husCompress_compress(void);
+
+/*TODO: macros are nasty, bleh */
+#define husCompress_445(_200,_446)((short)((_446<<_154)^(_278[_200+2]))&(_153-1))
+#define husCompress_447(_200,_201){short _204;if((_204=_163[_201])!=_157)_164[_204]=_200;_164[_200]=_201;_163[_200]=_204;_163[_201]=_200;}
+#define husCompress_448(s){short _204;if((_204=_164[s])!=_157){_164[s]=_157;_163[_204]=_157;}}
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_COMPRESS_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-ellipse.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-ellipse.c
new file mode 100644
index 000000000..26683b1da
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-ellipse.c
@@ -0,0 +1,133 @@
+#include "emb-ellipse.h"
+#include "emb-logging.h"
+#include <stdlib.h>
+
+/**************************************************/
+/* EmbEllipse */
+/**************************************************/
+
+double embEllipse_centerX(EmbEllipse ellipse)
+{
+ return ellipse.centerX;
+}
+
+double embEllipse_centerY(EmbEllipse ellipse)
+{
+ return ellipse.centerY;
+}
+
+double embEllipse_radiusX(EmbEllipse ellipse)
+{
+ return ellipse.radiusX;
+}
+
+double embEllipse_radiusY(EmbEllipse ellipse)
+{
+ return ellipse.radiusY;
+}
+
+double embEllipse_diameterX(EmbEllipse ellipse)
+{
+ return ellipse.radiusX * 2.0;
+}
+
+double embEllipse_diameterY(EmbEllipse ellipse)
+{
+ return ellipse.radiusY * 2.0;
+}
+
+double embEllipse_width(EmbEllipse ellipse)
+{
+ return ellipse.radiusX * 2.0;
+}
+
+double embEllipse_height(EmbEllipse ellipse)
+{
+ return ellipse.radiusY * 2.0;
+}
+
+/**************************************************/
+/* EmbEllipseObject */
+/**************************************************/
+
+/* Returns an EmbEllipseObject. It is created on the stack. */
+EmbEllipseObject embEllipseObject_make(double cx, double cy, double rx, double ry)
+{
+ EmbEllipseObject stackEllipseObj;
+ stackEllipseObj.ellipse.centerX = cx;
+ stackEllipseObj.ellipse.centerY = cy;
+ stackEllipseObj.ellipse.radiusX = rx;
+ stackEllipseObj.ellipse.radiusY = ry;
+ return stackEllipseObj;
+}
+
+/* Returns a pointer to an EmbEllipseObject. It is created on the heap. The caller is responsible for freeing the allocated memory. */
+EmbEllipseObject* embEllipseObject_create(double cx, double cy, double rx, double ry)
+{
+ EmbEllipseObject* heapEllipseObj = (EmbEllipseObject*)malloc(sizeof(EmbEllipseObject));
+ if(!heapEllipseObj) { embLog_error("emb-ellipse.c embEllipseObject_create(), cannot allocate memory for heapEllipseObj\n"); return 0; }
+ heapEllipseObj->ellipse.centerX = cx;
+ heapEllipseObj->ellipse.centerY = cy;
+ heapEllipseObj->ellipse.radiusX = rx;
+ heapEllipseObj->ellipse.radiusY = ry;
+ return heapEllipseObj;
+}
+
+/**************************************************/
+/* EmbEllipseObjectList */
+/**************************************************/
+
+EmbEllipseObjectList* embEllipseObjectList_create(EmbEllipseObject data)
+{
+ EmbEllipseObjectList* heapEllipseObjList = (EmbEllipseObjectList*)malloc(sizeof(EmbEllipseObjectList));
+ if(!heapEllipseObjList) { embLog_error("emb-ellipse.c embEllipseObjectList_create(), cannot allocate memory for heapEllipseObjList\n"); return 0; }
+ heapEllipseObjList->ellipseObj = data;
+ heapEllipseObjList->next = 0;
+ return heapEllipseObjList;
+}
+
+EmbEllipseObjectList* embEllipseObjectList_add(EmbEllipseObjectList* pointer, EmbEllipseObject data)
+{
+ if(!pointer) { embLog_error("emb-ellipse.c embEllipseObjectList_add(), pointer argument is null\n"); return 0; }
+ if(pointer->next) { embLog_error("emb-ellipse.c embEllipseObjectList_add(), pointer->next should be null\n"); return 0; }
+ pointer->next = (EmbEllipseObjectList*)malloc(sizeof(EmbEllipseObjectList));
+ if(!pointer->next) { embLog_error("emb-ellipse.c embEllipseObjectList_add(), cannot allocate memory for pointer->next\n"); return 0; }
+ pointer = pointer->next;
+ pointer->ellipseObj = data;
+ pointer->next = 0;
+ return pointer;
+}
+
+int embEllipseObjectList_count(EmbEllipseObjectList* pointer)
+{
+ int i = 1;
+ if(!pointer) return 0;
+ while(pointer->next)
+ {
+ pointer = pointer->next;
+ i++;
+ }
+ return i;
+}
+
+int embEllipseObjectList_empty(EmbEllipseObjectList* pointer)
+{
+ if(!pointer)
+ return 1;
+ return 0;
+}
+
+void embEllipseObjectList_free(EmbEllipseObjectList* pointer)
+{
+ EmbEllipseObjectList* tempPointer = pointer;
+ EmbEllipseObjectList* nextPointer = 0;
+ while(tempPointer)
+ {
+ nextPointer = tempPointer->next;
+ free(tempPointer);
+ tempPointer = nextPointer;
+ }
+ pointer = 0;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-ellipse.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-ellipse.h
new file mode 100644
index 000000000..867c28786
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-ellipse.h
@@ -0,0 +1,61 @@
+/*! @file emb-ellipse.h */
+#ifndef EMB_ELLIPSE_H
+#define EMB_ELLIPSE_H
+
+#include "emb-color.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct EmbEllipse_
+{
+ double centerX;
+ double centerY;
+ double radiusX;
+ double radiusY;
+} EmbEllipse;
+
+extern EMB_PUBLIC double EMB_CALL embEllipse_centerX(EmbEllipse ellipse);
+extern EMB_PUBLIC double EMB_CALL embEllipse_centerY(EmbEllipse ellipse);
+extern EMB_PUBLIC double EMB_CALL embEllipse_radiusX(EmbEllipse ellipse);
+extern EMB_PUBLIC double EMB_CALL embEllipse_radiusY(EmbEllipse ellipse);
+extern EMB_PUBLIC double EMB_CALL embEllipse_diameterX(EmbEllipse ellipse);
+extern EMB_PUBLIC double EMB_CALL embEllipse_diameterY(EmbEllipse ellipse);
+extern EMB_PUBLIC double EMB_CALL embEllipse_width(EmbEllipse ellipse);
+extern EMB_PUBLIC double EMB_CALL embEllipse_height(EmbEllipse ellipse);
+
+typedef struct EmbEllipseObject_
+{
+ EmbEllipse ellipse;
+ double rotation;
+
+ /* Properties */
+ int lineType;
+ EmbColor color;
+} EmbEllipseObject;
+
+extern EMB_PUBLIC EmbEllipseObject EMB_CALL embEllipseObject_make(double cx, double cy, double rx, double ry);
+extern EMB_PUBLIC EmbEllipseObject* EMB_CALL embEllipseObject_create(double cx, double cy, double rx, double ry);
+
+typedef struct EmbEllipseObjectList_
+{
+ EmbEllipseObject ellipseObj;
+ struct EmbEllipseObjectList_* next;
+} EmbEllipseObjectList;
+
+extern EMB_PUBLIC EmbEllipseObjectList* EMB_CALL embEllipseObjectList_create(EmbEllipseObject data);
+extern EMB_PUBLIC EmbEllipseObjectList* EMB_CALL embEllipseObjectList_add(EmbEllipseObjectList* pointer, EmbEllipseObject data);
+extern EMB_PUBLIC int EMB_CALL embEllipseObjectList_count(EmbEllipseObjectList* pointer);
+extern EMB_PUBLIC int EMB_CALL embEllipseObjectList_empty(EmbEllipseObjectList* pointer);
+extern EMB_PUBLIC void EMB_CALL embEllipseObjectList_free(EmbEllipseObjectList* pointer);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_ELLIPSE_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-file.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-file.c
new file mode 100644
index 000000000..81e627ae7
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-file.c
@@ -0,0 +1,143 @@
+#include "emb-file.h"
+#include <stdarg.h>
+#include <stdlib.h>
+
+EmbFile* embFile_open(const char* fileName, const char* mode)
+{
+#ifdef ARDUINO
+ return inoFile_open(fileName, mode);
+#else
+ EmbFile* eFile = 0;
+ FILE* oFile = fopen(fileName, mode);
+ if(!oFile)
+ return 0;
+
+ eFile = (EmbFile*)malloc(sizeof(EmbFile));
+ if(!eFile)
+ {
+ fclose(oFile);
+ return 0;
+ }
+
+ eFile->file = oFile;
+ return eFile;
+#endif
+}
+
+int embFile_close(EmbFile* stream)
+{
+#ifdef ARDUINO
+ return inoFile_close(stream);
+#else /* ARDUINO */
+ int retVal = fclose(stream->file);
+ free(stream);
+ stream = 0;
+ return retVal;
+#endif /* ARDUINO */
+}
+
+int embFile_eof(EmbFile* stream)
+{
+#ifdef ARDUINO
+ return inoFile_eof(stream);
+#else /* ARDUINO */
+ return feof(stream->file);
+#endif /* ARDUINO */
+}
+
+int embFile_getc(EmbFile* stream)
+{
+#ifdef ARDUINO
+ return inoFile_getc(stream);
+#else /* ARDUINO */
+ return fgetc(stream->file);
+#endif /* ARDUINO */
+}
+
+size_t embFile_read(void* ptr, size_t size, size_t nmemb, EmbFile* stream)
+{
+#ifdef ARDUINO
+ return 0; /* ARDUINO TODO: SD File read() doesn't appear to return the same way as fread(). This will need work. */
+#else /* ARDUINO */
+ return fread(ptr, size, nmemb, stream->file);
+#endif /* ARDUINO */
+}
+
+size_t embFile_write(const void* ptr, size_t size, size_t nmemb, EmbFile* stream)
+{
+#ifdef ARDUINO
+ return 0; /* ARDUINO TODO: Implement inoFile_write. */
+#else /* ARDUINO */
+ return fwrite(ptr, size, nmemb, stream->file);
+#endif /* ARDUINO */
+}
+
+int embFile_seek(EmbFile* stream, long offset, int origin)
+{
+#ifdef ARDUINO
+ return inoFile_seek(stream, offset, origin);
+#else /* ARDUINO */
+ return fseek(stream->file, offset, origin);
+#endif /* ARDUINO */
+}
+
+long embFile_tell(EmbFile* stream)
+{
+#ifdef ARDUINO
+ return inoFile_tell(stream);
+#else /* ARDUINO */
+ return ftell(stream->file);
+#endif /* ARDUINO */
+}
+
+EmbFile* embFile_tmpfile(void)
+{
+#ifdef ARDUINO
+ return inoFile_tmpfile();
+#else
+ EmbFile* eFile = 0;
+ FILE* tFile = tmpfile();
+ if(!tFile)
+ return 0;
+
+ eFile = (EmbFile*)malloc(sizeof(EmbFile));
+ if(!eFile)
+ {
+ fclose(tFile);
+ return 0;
+ }
+
+ eFile->file = tFile;
+ return eFile;
+#endif
+}
+
+int embFile_putc(int ch, EmbFile* stream)
+{
+#ifdef ARDUINO
+ return inoFile_putc(ch, stream);
+#else /* ARDUINO */
+ return fputc(ch, stream->file);
+#endif /* ARDUINO */
+}
+
+int embFile_printf(EmbFile* stream, const char* format, ...)
+{
+#ifdef ARDUINO /* ARDUINO */
+ char buff[256];
+ va_list args;
+ va_start(args, format);
+ vsprintf(buff, format, args);
+ va_end(args);
+ return inoFile_printf(stream, buff);
+#else /* ARDUINO */
+ int retVal;
+ va_list args;
+ va_start(args, format);
+ retVal = vfprintf(stream->file, format, args);
+ va_end(args);
+ return retVal;
+#endif /* ARDUINO */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-file.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-file.h
new file mode 100644
index 000000000..ef0cf1ab7
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-file.h
@@ -0,0 +1,41 @@
+/*! @file emb-file.h */
+#ifndef EMB_FILE_H
+#define EMB_FILE_H
+
+#include <stdio.h>
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef ARDUINO
+#include "utility/ino-file.h"
+#else
+typedef struct EmbFile_
+{
+ FILE* file;
+} EmbFile;
+#endif /* ARDUINO */
+
+extern EMB_PUBLIC EmbFile* EMB_CALL embFile_open(const char* fileName, const char* mode);
+extern EMB_PUBLIC int EMB_CALL embFile_close(EmbFile* stream);
+extern EMB_PUBLIC int EMB_CALL embFile_eof(EmbFile* stream);
+extern EMB_PUBLIC int EMB_CALL embFile_getc(EmbFile* stream);
+extern EMB_PUBLIC size_t EMB_CALL embFile_read(void* ptr, size_t size, size_t nmemb, EmbFile* stream);
+extern EMB_PUBLIC size_t EMB_CALL embFile_write(const void* ptr, size_t size, size_t nmemb, EmbFile* stream);
+extern EMB_PUBLIC int EMB_CALL embFile_seek(EmbFile* stream, long offset, int origin);
+extern EMB_PUBLIC long EMB_CALL embFile_tell(EmbFile* stream);
+extern EMB_PUBLIC EmbFile* EMB_CALL embFile_tmpfile(void);
+extern EMB_PUBLIC int EMB_CALL embFile_putc(int ch, EmbFile* stream);
+
+extern EMB_PUBLIC int EMB_CALL embFile_printf(EmbFile* stream, const char* format, ...);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_FILE_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-flag.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-flag.c
new file mode 100644
index 000000000..d192bd72e
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-flag.c
@@ -0,0 +1,62 @@
+#include "emb-flag.h"
+#include "emb-logging.h"
+#include <stdlib.h>
+
+/**************************************************/
+/* EmbFlagList */
+/**************************************************/
+
+EmbFlagList* embFlagList_create(EmbFlag data)
+{
+ EmbFlagList* heapFlagList = (EmbFlagList*)malloc(sizeof(EmbFlagList));
+ if(!heapFlagList) { embLog_error("emb-flag.c embFlagList_create(), cannot allocate memory for heapFlagList\n"); return 0; }
+ heapFlagList->flag = data;
+ heapFlagList->next = 0;
+ return heapFlagList;
+}
+
+EmbFlagList* embFlagList_add(EmbFlagList* pointer, EmbFlag data)
+{
+ if(!pointer) { embLog_error("emb-flag.c embFlagList_add(), pointer argument is null\n"); return 0; }
+ if(pointer->next) { embLog_error("emb-flag.c embFlagList_add(), pointer->next should be null\n"); return 0; }
+ pointer->next = (EmbFlagList*)malloc(sizeof(EmbFlagList));
+ if(!pointer->next) { embLog_error("emb-flag.c embFlagList_add(), cannot allocate memory for pointer->next\n"); return 0; }
+ pointer = pointer->next;
+ pointer->flag = data;
+ pointer->next = 0;
+ return pointer;
+}
+
+int embFlagList_count(EmbFlagList* pointer)
+{
+ int i = 1;
+ if(!pointer) return 0;
+ while(pointer->next)
+ {
+ pointer = pointer->next;
+ i++;
+ }
+ return i;
+}
+
+int embFlagList_empty(EmbFlagList* pointer)
+{
+ if(!pointer)
+ return 1;
+ return 0;
+}
+
+void embFlagList_free(EmbFlagList* pointer)
+{
+ EmbFlagList* tempPointer = pointer;
+ EmbFlagList* nextPointer = 0;
+ while(tempPointer)
+ {
+ nextPointer = tempPointer->next;
+ free(tempPointer);
+ tempPointer = nextPointer;
+ }
+ pointer = 0;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-flag.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-flag.h
new file mode 100644
index 000000000..ac816176f
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-flag.h
@@ -0,0 +1,31 @@
+/*! @file emb-flag.h */
+#ifndef EMB_FLAG_H
+#define EMB_FLAG_H
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef int EmbFlag;
+
+typedef struct EmbFlagList_
+{
+ int flag;
+ struct EmbFlagList_* next;
+} EmbFlagList;
+
+extern EMB_PUBLIC EmbFlagList* EMB_CALL embFlagList_create(EmbFlag data);
+extern EMB_PUBLIC EmbFlagList* EMB_CALL embFlagList_add(EmbFlagList* pointer, EmbFlag data);
+extern EMB_PUBLIC int EMB_CALL embFlagList_count(EmbFlagList* pointer);
+extern EMB_PUBLIC int EMB_CALL embFlagList_empty(EmbFlagList* pointer);
+extern EMB_PUBLIC void EMB_CALL embFlagList_free(EmbFlagList* pointer);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_FLAG_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-format.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-format.c
new file mode 100644
index 000000000..fc92df2c4
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-format.c
@@ -0,0 +1,383 @@
+#include "emb-format.h"
+#include "emb-logging.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+/**************************************************/
+/* EmbFormatList */
+/**************************************************/
+
+EmbFormatList* embFormatList_create()
+{
+ EmbFormatList* firstFormat = 0;
+
+ /* TODO: This list needs reviewed in case some stitch formats also can contain object data (EMBFORMAT_STCHANDOBJ). */
+
+ EmbFormatList* heapFormatList = (EmbFormatList*)malloc(sizeof(EmbFormatList));
+ if(!heapFormatList) { embLog_error("emb-format.c embFormatList_create(), cannot allocate memory for heapFormatList\n"); return 0; }
+ heapFormatList->extension = ".10o";
+ heapFormatList->description = "Toyota Embroidery Format";
+ heapFormatList->reader = 'U';
+ heapFormatList->writer = ' ';
+ heapFormatList->type = EMBFORMAT_STITCHONLY;
+ heapFormatList->next = 0;
+
+ firstFormat = heapFormatList;
+
+ heapFormatList = embFormatList_add(heapFormatList, ".100", "Toyota Embroidery Format", 'U', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".art", "Bernina Embroidery Format", ' ', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".bmc", "Bitmap Cache Embroidery Format", ' ', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".bro", "Bits & Volts Embroidery Format", 'U', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".cnd", "Melco Embroidery Format", ' ', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".col", "Embroidery Thread Color Format", 'U', 'U', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".csd", "Singer Embroidery Format", 'U', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".csv", "Comma Separated Values Format", 'U', 'U', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".dat", "Barudan Embroidery Format", 'U', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".dem", "Melco Embroidery Format", ' ', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".dsb", "Barudan Embroidery Format", 'U', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".dst", "Tajima Embroidery Format", 'U', 'U', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".dsz", "ZSK USA Embroidery Format", 'U', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".dxf", "Drawing Exchange Format", ' ', ' ', EMBFORMAT_OBJECTONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".edr", "Embird Embroidery Format", 'U', 'U', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".emd", "Elna Embroidery Format", 'U', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".exp", "Melco Embroidery Format", 'U', 'U', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".exy", "Eltac Embroidery Format", 'U', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".eys", "Sierra Expanded Embroidery Format", ' ', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".fxy", "Fortron Embroidery Format", 'U', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".gc", "Smoothie G-Code Format", ' ', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".gnc", "Great Notions Embroidery Format", ' ', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".gt", "Gold Thread Embroidery Format", 'U', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".hus", "Husqvarna Viking Embroidery Format", 'U', 'U', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".inb", "Inbro Embroidery Format", 'U', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".inf", "Embroidery Color Format", 'U', 'U', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".jef", "Janome Embroidery Format", 'U', 'U', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".ksm", "Pfaff Embroidery Format", 'U', 'U', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".max", "Pfaff Embroidery Format", 'U', 'U', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".mit", "Mitsubishi Embroidery Format", 'U', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".new", "Ameco Embroidery Format", 'U', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".ofm", "Melco Embroidery Format", 'U', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".pcd", "Pfaff Embroidery Format", 'U', 'U', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".pcm", "Pfaff Embroidery Format", 'U', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".pcq", "Pfaff Embroidery Format", 'U', 'U', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".pcs", "Pfaff Embroidery Format", 'U', 'U', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".pec", "Brother Embroidery Format", 'U', 'U', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".pel", "Brother Embroidery Format", ' ', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".pem", "Brother Embroidery Format", ' ', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".pes", "Brother Embroidery Format", 'U', 'U', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".phb", "Brother Embroidery Format", 'U', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".phc", "Brother Embroidery Format", 'U', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".plt", "AutoCAD Plot Drawing Format", 'U', 'U', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".rgb", "RGB Embroidery Format", 'U', 'U', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".sew", "Janome Embroidery Format", 'U', 'U', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".shv", "Husqvarna Viking Embroidery Format", 'U', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".sst", "Sunstar Embroidery Format", 'U', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".stx", "Data Stitch Embroidery Format", 'U', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".svg", "Scalable Vector Graphics", 'U', 'U', EMBFORMAT_OBJECTONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".t01", "Pfaff Embroidery Format", 'U', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".t09", "Pfaff Embroidery Format", 'U', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".tap", "Happy Embroidery Format", 'U', 'U', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".thr", "ThredWorks Embroidery Format", 'U', 'U', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".txt", "Text File", ' ', 'U', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".u00", "Barudan Embroidery Format", 'U', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".u01", "Barudan Embroidery Format", ' ', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".vip", "Pfaff Embroidery Format", 'U', ' ', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".vp3", "Pfaff Embroidery Format", 'U', 'U', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".xxx", "Singer Embroidery Format", 'U', 'U', EMBFORMAT_STITCHONLY);
+ heapFormatList = embFormatList_add(heapFormatList, ".zsk", "ZSK USA Embroidery Format", 'U', ' ', EMBFORMAT_STITCHONLY);
+
+ return firstFormat;
+}
+
+EmbFormatList* embFormatList_add(EmbFormatList* pointer, char* extension, char* description, char reader, char writer, int type)
+{
+ if(!pointer) { embLog_error("emb-format.c embFormatList_add(), pointer argument is null\n"); return 0; }
+ if(pointer->next) { embLog_error("emb-format.c embFormatList_add(), pointer->next should be null\n"); return 0; }
+ pointer->next = (EmbFormatList*)malloc(sizeof(EmbFormatList));
+ if(!pointer->next) { embLog_error("emb-format.c embFormatList_add(), cannot allocate memory for pointer->next\n"); return 0; }
+ pointer = pointer->next;
+ pointer->extension = extension;
+ pointer->description = description;
+ pointer->reader = reader;
+ pointer->writer = writer;
+ pointer->type = type;
+ pointer->next = 0;
+ return pointer;
+}
+
+int embFormatList_count(EmbFormatList* pointer)
+{
+ int i = 1;
+ if(!pointer) return 0;
+ while(pointer->next)
+ {
+ pointer = pointer->next;
+ i++;
+ }
+ return i;
+}
+
+int embFormatList_empty(EmbFormatList* pointer)
+{
+ if(!pointer)
+ return 1;
+ return 0;
+}
+
+void embFormatList_free(EmbFormatList* pointer)
+{
+ EmbFormatList* tempPointer = pointer;
+ EmbFormatList* nextPointer = 0;
+ while(tempPointer)
+ {
+ nextPointer = tempPointer->next;
+ free(tempPointer);
+ tempPointer = nextPointer;
+ }
+ pointer = 0;
+}
+
+
+const char* embFormat_extension(EmbFormatList* pointer)
+{
+ if(!pointer) { embLog_error("emb-format.c embFormat_extension(), pointer argument is null\n"); return 0; }
+ return pointer->extension;
+}
+
+const char* embFormat_description(EmbFormatList* pointer)
+{
+ if(!pointer) { embLog_error("emb-format.c embFormat_description(), pointer argument is null\n"); return 0; }
+ return pointer->description;
+}
+
+char embFormat_readerState(EmbFormatList* pointer)
+{
+ if(!pointer) { embLog_error("emb-format.c embFormat_readerState(), pointer argument is null\n"); return 0; }
+ return pointer->reader;
+}
+
+char embFormat_writerState(EmbFormatList* pointer)
+{
+ if(!pointer) { embLog_error("emb-format.c embFormat_writerState(), pointer argument is null\n"); return 0; }
+ return pointer->writer;
+}
+
+int embFormat_type(EmbFormatList* pointer)
+{
+ if(!pointer) { embLog_error("emb-format.c embFormat_type(), pointer argument is null\n"); return 0; }
+ return pointer->type;
+}
+
+
+const char* embFormat_extensionFromName(const char* fileName)
+{
+ int i = 0;
+ char ending[2 + EMBFORMAT_MAXEXT];
+ EmbFormatList* formatList = 0;
+ EmbFormatList* curFormat = 0;
+ const char* extension = 0;
+
+ if(!fileName) { embLog_error("emb-format.c embFormat_extensionFromName(), fileName argument is null\n"); return 0; }
+
+ formatList = embFormatList_create();
+
+ if(strlen(fileName) == 0) return 0;
+ if(strrchr(fileName, '.'))
+ strcpy(ending, strrchr(fileName, '.'));
+ else
+ return 0;
+
+ while(ending[i] != '\0')
+ {
+ ending[i] = (char)tolower(ending[i]);
+ ++i;
+ }
+
+ curFormat = formatList;
+ while(curFormat)
+ {
+ if(!strcmp(ending, curFormat->extension))
+ {
+ extension = curFormat->extension;
+ break;
+ }
+
+ curFormat = curFormat->next;
+ }
+
+ embFormatList_free(formatList);
+ formatList = 0;
+
+ return extension;
+}
+
+const char* embFormat_descriptionFromName(const char* fileName)
+{
+ int i = 0;
+ char ending[2 + EMBFORMAT_MAXEXT];
+ EmbFormatList* formatList = 0;
+ EmbFormatList* curFormat = 0;
+ const char* description = 0;
+
+ if(!fileName) { embLog_error("emb-format.c embFormat_descriptionFromName(), fileName argument is null\n"); return 0; }
+
+ formatList = embFormatList_create();
+
+ if(strlen(fileName) == 0) return 0;
+ if(strrchr(fileName, '.'))
+ strcpy(ending, strrchr(fileName, '.'));
+ else
+ return 0;
+
+ while(ending[i] != '\0')
+ {
+ ending[i] = (char)tolower(ending[i]);
+ ++i;
+ }
+
+ curFormat = formatList;
+ while(curFormat)
+ {
+ if(!strcmp(ending, curFormat->extension))
+ {
+ description = curFormat->description;
+ break;
+ }
+
+ curFormat = curFormat->next;
+ }
+
+ embFormatList_free(formatList);
+ formatList = 0;
+
+ return description;
+}
+
+char embFormat_readerStateFromName(const char* fileName)
+{
+ int i = 0;
+ char ending[2 + EMBFORMAT_MAXEXT];
+ EmbFormatList* formatList = 0;
+ EmbFormatList* curFormat = 0;
+ char readerState = ' ';
+
+ if(!fileName) { embLog_error("emb-format.c embFormat_readerStateFromName(), fileName argument is null\n"); return 0; }
+
+ formatList = embFormatList_create();
+
+ if(strlen(fileName) == 0) return 0;
+ if(strrchr(fileName, '.'))
+ strcpy(ending, strrchr(fileName, '.'));
+ else
+ return 0;
+
+ while(ending[i] != '\0')
+ {
+ ending[i] = (char)tolower(ending[i]);
+ ++i;
+ }
+
+ curFormat = formatList;
+ while(curFormat)
+ {
+ if(!strcmp(ending, curFormat->extension))
+ {
+ readerState = curFormat->reader;
+ break;
+ }
+
+ curFormat = curFormat->next;
+ }
+
+ embFormatList_free(formatList);
+ formatList = 0;
+
+ return readerState;
+}
+
+char embFormat_writerStateFromName(const char* fileName)
+{
+ int i = 0;
+ char ending[2 + EMBFORMAT_MAXEXT];
+ EmbFormatList* formatList = 0;
+ EmbFormatList* curFormat = 0;
+ char writerState = ' ';
+
+ if(!fileName) { embLog_error("emb-format.c embFormat_writerStateFromName(), fileName argument is null\n"); return 0; }
+
+ formatList = embFormatList_create();
+
+ if(strlen(fileName) == 0) return 0;
+ if(strrchr(fileName, '.'))
+ strcpy(ending, strrchr(fileName, '.'));
+ else
+ return 0;
+
+ while(ending[i] != '\0')
+ {
+ ending[i] = (char)tolower(ending[i]);
+ ++i;
+ }
+
+ curFormat = formatList;
+ while(curFormat)
+ {
+ if(!strcmp(ending, curFormat->extension))
+ {
+ writerState = curFormat->writer;
+ break;
+ }
+
+ curFormat = curFormat->next;
+ }
+
+ embFormatList_free(formatList);
+ formatList = 0;
+
+ return writerState;
+}
+
+int embFormat_typeFromName(const char* fileName)
+{
+ int i = 0;
+ char ending[2 + EMBFORMAT_MAXEXT];
+ EmbFormatList* formatList = 0;
+ EmbFormatList* curFormat = 0;
+ int type = EMBFORMAT_UNSUPPORTED;
+
+ if(!fileName) { embLog_error("emb-format.c embFormat_typeFromName(), fileName argument is null\n"); return 0; }
+
+ formatList = embFormatList_create();
+
+ if(strlen(fileName) == 0) return 0;
+ if(strrchr(fileName, '.'))
+ strcpy(ending, strrchr(fileName, '.'));
+ else
+ return 0;
+
+ while(ending[i] != '\0')
+ {
+ ending[i] = (char)tolower(ending[i]);
+ ++i;
+ }
+
+ curFormat = formatList;
+ while(curFormat)
+ {
+ if(!strcmp(ending, curFormat->extension))
+ {
+ type = curFormat->type;
+ break;
+ }
+
+ curFormat = curFormat->next;
+ }
+
+ embFormatList_free(formatList);
+ formatList = 0;
+
+ return type;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-format.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-format.h
new file mode 100644
index 000000000..bdcd33b33
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-format.h
@@ -0,0 +1,51 @@
+#ifndef EMB_FORMAT_H
+#define EMB_FORMAT_H
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define EMBFORMAT_UNSUPPORTED 0
+#define EMBFORMAT_STITCHONLY 1
+#define EMBFORMAT_OBJECTONLY 2
+#define EMBFORMAT_STCHANDOBJ 3 /* binary operation: 1+2=3 */
+
+#define EMBFORMAT_MAXEXT 3 /* maximum length of extension without dot */
+
+typedef struct EmbFormatList_
+{
+ char* extension;
+ char* description;
+ char reader;
+ char writer;
+ int type;
+ struct EmbFormatList_* next;
+} EmbFormatList;
+
+extern EMB_PUBLIC EmbFormatList* EMB_CALL embFormatList_create();
+extern EMB_PRIVATE EmbFormatList* EMB_CALL embFormatList_add(EmbFormatList* pointer, char* extension, char* description, char reader, char writer, int type);
+extern EMB_PUBLIC int EMB_CALL embFormatList_count(EmbFormatList* pointer);
+extern EMB_PUBLIC int EMB_CALL embFormatList_empty(EmbFormatList* pointer);
+extern EMB_PUBLIC void EMB_CALL embFormatList_free(EmbFormatList* pointer);
+
+extern EMB_PUBLIC const char* EMB_CALL embFormat_extension(EmbFormatList* pointer);
+extern EMB_PUBLIC const char* EMB_CALL embFormat_description(EmbFormatList* pointer);
+extern EMB_PUBLIC char EMB_CALL embFormat_readerState(EmbFormatList* pointer);
+extern EMB_PUBLIC char EMB_CALL embFormat_writerState(EmbFormatList* pointer);
+extern EMB_PUBLIC int EMB_CALL embFormat_type(EmbFormatList* pointer);
+
+extern EMB_PUBLIC const char* EMB_CALL embFormat_extensionFromName(const char* fileName);
+extern EMB_PUBLIC const char* EMB_CALL embFormat_descriptionFromName(const char* fileName);
+extern EMB_PUBLIC char EMB_CALL embFormat_readerStateFromName(const char* fileName);
+extern EMB_PUBLIC char EMB_CALL embFormat_writerStateFromName(const char* fileName);
+extern EMB_PUBLIC int EMB_CALL embFormat_typeFromName(const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_FORMAT_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-hash.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-hash.c
new file mode 100644
index 000000000..41181a8c5
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-hash.c
@@ -0,0 +1,17 @@
+#include "emb-hash.h"
+
+/* This file contains wrapper functions around Keith Pomakis' HashTable Library */
+
+EmbHash* embHash_create(void) { return HashTableCreate(1); }
+void embHash_free(EmbHash* hash) { HashTableDestroy(hash); hash = 0; }
+
+int embHash_contains(const EmbHash* hash, const void* key) { return HashTableContainsKey(hash, key); }
+int embHash_insert(EmbHash* hash, const void* key, void* value) { return HashTablePut(hash, key, value); }
+void* embHash_value(const EmbHash* hash, const void* key) { return HashTableGet(hash, key); }
+void embHash_remove(EmbHash* hash, const void *key) { HashTableRemove(hash, key); }
+void embHash_clear(EmbHash* hash) { HashTableRemoveAll(hash); }
+int embHash_empty(const EmbHash* hash) { return HashTableIsEmpty(hash); }
+long embHash_count(const EmbHash* hash) { return HashTableSize(hash); }
+void embHash_rehash(EmbHash* hash, long numOfBuckets) { HashTableRehash(hash, numOfBuckets); }
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-hash.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-hash.h
new file mode 100644
index 000000000..8ed347188
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-hash.h
@@ -0,0 +1,34 @@
+/*! @file emb-hash.h */
+#ifndef EMB_HASH_H
+#define EMB_HASH_H
+
+/* This file contains wrapper functions around Keith Pomakis' HashTable Library */
+#include "hashtable.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef HashTable EmbHash;
+
+extern EMB_PUBLIC EmbHash* EMB_CALL embHash_create(void);
+extern EMB_PUBLIC void EMB_CALL embHash_free(EmbHash* hash);
+
+extern EMB_PUBLIC int EMB_CALL embHash_contains(const EmbHash* hash, const void* key);
+extern EMB_PUBLIC int EMB_CALL embHash_insert(EmbHash* hash, const void* key, void* value);
+extern EMB_PUBLIC void* EMB_CALL embHash_value(const EmbHash* hash, const void* key);
+extern EMB_PUBLIC void EMB_CALL embHash_remove(EmbHash* hash, const void *key);
+extern EMB_PUBLIC void EMB_CALL embHash_clear(EmbHash* hash);
+extern EMB_PUBLIC int EMB_CALL embHash_empty(const EmbHash* hash);
+extern EMB_PUBLIC long EMB_CALL embHash_count(const EmbHash* hash);
+extern EMB_PUBLIC void EMB_CALL embHash_rehash(EmbHash* hash, long numOfBuckets);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_HASH_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-hoop.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-hoop.c
new file mode 100644
index 000000000..7dfcf863b
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-hoop.c
@@ -0,0 +1,17 @@
+#include "emb-hoop.h"
+
+/**************************************************/
+/* EmbHoop */
+/**************************************************/
+
+double embHoop_width(EmbHoop hoop)
+{
+ return hoop.width;
+}
+
+double embHoop_height(EmbHoop hoop)
+{
+ return hoop.height;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-hoop.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-hoop.h
new file mode 100644
index 000000000..652de8a89
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-hoop.h
@@ -0,0 +1,26 @@
+/*! @file emb-hoop.h */
+#ifndef EMB_HOOP_H
+#define EMB_HOOP_H
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct EmbHoop_
+{
+ double width;
+ double height;
+} EmbHoop;
+
+extern EMB_PUBLIC double EMB_CALL embHoop_width(EmbHoop hoop);
+extern EMB_PUBLIC double EMB_CALL embHoop_height(EmbHoop hoop);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_HOOP_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-layer.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-layer.c
new file mode 100644
index 000000000..515f62927
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-layer.c
@@ -0,0 +1,3 @@
+#include "emb-layer.h"
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-layer.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-layer.h
new file mode 100644
index 000000000..fdeaf36ce
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-layer.h
@@ -0,0 +1,25 @@
+/*! @file emb-layer.h */
+#ifndef EMB_LAYER_H
+#define EMB_LAYER_H
+
+#include "emb-color.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct EmbLayer_
+{
+ EmbColor color;
+ const char* name;
+} EmbLayer;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_LAYER_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-line.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-line.c
new file mode 100644
index 000000000..ad5312d36
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-line.c
@@ -0,0 +1,163 @@
+#include "emb-line.h"
+#include "emb-logging.h"
+#include "emb-vector.h"
+#include <stdlib.h>
+
+/**************************************************/
+/* EmbLine */
+/**************************************************/
+
+double embLine_x1(EmbLine line)
+{
+ return line.x1;
+}
+
+double embLine_y1(EmbLine line)
+{
+ return line.y1;
+}
+
+double embLine_x2(EmbLine line)
+{
+ return line.x2;
+}
+
+double embLine_y2(EmbLine line)
+{
+ return line.y2;
+}
+
+/**************************************************/
+/* EmbLineObject */
+/**************************************************/
+
+/* Returns an EmbLineObject. It is created on the stack. */
+EmbLineObject embLineObject_make(double x1, double y1, double x2, double y2)
+{
+ EmbLineObject stackLineObj;
+ stackLineObj.line.x1 = x1;
+ stackLineObj.line.y1 = y1;
+ stackLineObj.line.x2 = x2;
+ stackLineObj.line.y2 = y2;
+ return stackLineObj;
+}
+
+/* Returns a pointer to an EmbLineObject. It is created on the heap. The caller is responsible for freeing the allocated memory. */
+EmbLineObject* embLineObject_create(double x1, double y1, double x2, double y2)
+{
+ EmbLineObject* heapLineObj = (EmbLineObject*)malloc(sizeof(EmbLineObject));
+ if(!heapLineObj) { embLog_error("emb-line.c embLineObject_create(), cannot allocate memory for heapLineObj\n"); return 0; }
+ heapLineObj->line.x1 = x1;
+ heapLineObj->line.y1 = y1;
+ heapLineObj->line.x2 = x2;
+ heapLineObj->line.y2 = y2;
+ return heapLineObj;
+}
+
+/**************************************************/
+/* EmbLineObjectList */
+/**************************************************/
+
+EmbLineObjectList* embLineObjectList_create(EmbLineObject data)
+{
+ EmbLineObjectList* heapLineObjList = (EmbLineObjectList*)malloc(sizeof(EmbLineObjectList));
+ if(!heapLineObjList) { embLog_error("emb-line.c embLineObjectList_create(), cannot allocate memory for heapLineObjList\n"); return 0; }
+ heapLineObjList->lineObj = data;
+ heapLineObjList->next = 0;
+ return heapLineObjList;
+}
+
+EmbLineObjectList* embLineObjectList_add(EmbLineObjectList* pointer, EmbLineObject data)
+{
+ if(!pointer) { embLog_error("emb-line.c embLineObjectList_add(), pointer argument is null\n"); return 0; }
+ if(pointer->next) { embLog_error("emb-line.c embLineObjectList_add(), pointer->next should be null\n"); return 0; }
+ pointer->next = (EmbLineObjectList*)malloc(sizeof(EmbLineObjectList));
+ if(!pointer->next) { embLog_error("emb-line.c embLineObjectList_add(), cannot allocate memory for pointer->next\n"); return 0; }
+ pointer = pointer->next;
+ pointer->lineObj = data;
+ pointer->next = 0;
+ return pointer;
+}
+
+int embLineObjectList_count(EmbLineObjectList* pointer)
+{
+ int i = 1;
+ if(!pointer) return 0;
+ while(pointer->next)
+ {
+ pointer = pointer->next;
+ i++;
+ }
+ return i;
+}
+
+int embLineObjectList_empty(EmbLineObjectList* pointer)
+{
+ if(!pointer)
+ return 1;
+ return 0;
+}
+
+void embLineObjectList_free(EmbLineObjectList* pointer)
+{
+ EmbLineObjectList* tempPointer = pointer;
+ EmbLineObjectList* nextPointer = 0;
+ while(tempPointer)
+ {
+ nextPointer = tempPointer->next;
+ free(tempPointer);
+ tempPointer = nextPointer;
+ }
+ pointer = 0;
+}
+
+/* TODO: API Cleanup: This function should use an embLine parameter, not vector1/vector2, and look like this:
+ embLine_normalVector(EmbLine line, EmbVector* result, int clockwise) */
+/*! Finds the normalized vector perpendicular (clockwise) to the line given by v1->v2 (normal to the line) */
+void embLine_normalVector(EmbVector vector1, EmbVector vector2, EmbVector* result, int clockwise)
+{
+ double temp;
+ if(!result) { embLog_error("emb-line.c embLine_normalVector(), result argument is null\n"); return; }
+ result->X = vector2.X - vector1.X;
+ result->Y = vector2.Y - vector1.Y;
+ embVector_normalize(*result, result);
+ temp = result->X;
+ result->X = result->Y;
+ result->Y = -temp;
+ if(!clockwise)
+ {
+ result->X = -result->X;
+ result->Y = -result->Y;
+ }
+}
+
+/* TODO: API Cleanup: This is similar to the code we already have in geom-line.c, but may work well here.
+ Also the result has NOTHING to do with vectors. It sets a point, not a vector, even though
+ vector math is used internally inside this function. The function should look like this:
+ embLine_intersectionPoint(EmbLine line1, EmbLine line2, EmbPoint* result)
+ */
+/*! Finds the intersection of two lines given by v1->v2 and v3->v4 and sets the value in the result variable */
+void embLine_intersectionPoint(EmbVector v1, EmbVector v2, EmbVector v3, EmbVector v4, EmbVector* result)
+{
+ double A2 = v2.Y - v1.Y;
+ double B2 = v1.X - v2.X;
+ double C2 = A2 * v1.X + B2 * v1.Y;
+
+ double A1 = v4.Y - v3.Y;
+ double B1 = v3.X - v4.X;
+ double C1 = A1 * v3.X + B1 * v3.Y;
+
+ double det = A1 * B2 - A2 * B1;
+
+ if(!result) { embLog_error("emb-line.c embLine_intersectionPoint(), result argument is null\n"); return; }
+ /*TODO: The code below needs revised since division by zero can still occur */
+ if(det < 1e-10 && det > -1e-10)
+ {
+ result->X = -10000; /* TODO: What is significant about these numbers? Leave the point, undefined */
+ result->Y = -10000; /* TODO: A better solution would be to return an unsigned char(0 parallel, 1 intersecting, 2 not-intersecting) */
+ }
+ result->X = (B2 * C1 - B1 * C2) / det;
+ result->Y = (A1 * C2 - A2 * C1) / det;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-line.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-line.h
new file mode 100644
index 000000000..e7c0b48d3
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-line.h
@@ -0,0 +1,60 @@
+/*! @file emb-line.h */
+#ifndef EMB_LINE_H
+#define EMB_LINE_H
+
+#include "emb-color.h"
+#include "emb-vector.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct EmbLine_
+{
+ double x1;
+ double y1;
+ double x2;
+ double y2;
+} EmbLine;
+
+extern EMB_PUBLIC double EMB_CALL embLine_x1(EmbLine line);
+extern EMB_PUBLIC double EMB_CALL embLine_y1(EmbLine line);
+extern EMB_PUBLIC double EMB_CALL embLine_x2(EmbLine line);
+extern EMB_PUBLIC double EMB_CALL embLine_y2(EmbLine line);
+
+typedef struct EmbLineObject_
+{
+ EmbLine line;
+
+ /* Properties */
+ int lineType;
+ EmbColor color;
+} EmbLineObject;
+
+extern EMB_PUBLIC EmbLineObject EMB_CALL embLineObject_make(double x1, double y1, double x2, double y2);
+extern EMB_PUBLIC EmbLineObject* EMB_CALL embLineObject_create(double x1, double y1, double x2, double y2);
+
+typedef struct EmbLineObjectList_
+{
+ EmbLineObject lineObj;
+ struct EmbLineObjectList_* next;
+} EmbLineObjectList;
+
+extern EMB_PUBLIC EmbLineObjectList* EMB_CALL embLineObjectList_create(EmbLineObject data);
+extern EMB_PUBLIC EmbLineObjectList* EMB_CALL embLineObjectList_add(EmbLineObjectList* pointer, EmbLineObject data);
+extern EMB_PUBLIC int EMB_CALL embLineObjectList_count(EmbLineObjectList* pointer);
+extern EMB_PUBLIC int EMB_CALL embLineObjectList_empty(EmbLineObjectList* pointer);
+extern EMB_PUBLIC void EMB_CALL embLineObjectList_free(EmbLineObjectList* pointer);
+
+extern EMB_PUBLIC void EMB_CALL embLine_normalVector(EmbVector vector1, EmbVector vector2, EmbVector* result, int clockwise);
+extern EMB_PUBLIC void EMB_CALL embLine_intersectionPoint(EmbVector v1, EmbVector v2, EmbVector v3, EmbVector v4, EmbVector* result);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_LINE_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-logging.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-logging.c
new file mode 100644
index 000000000..9a8b52256
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-logging.c
@@ -0,0 +1,47 @@
+#include "emb-logging.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+
+/* printf() abstraction. Uses Serial.print() on ARDUINO */
+void embLog_print(const char* format, ...)
+{
+ /* TODO: log debug message in struct for later use */
+
+#ifdef ARDUINO /* ARDUINO */
+ char buff[256];
+ va_list args;
+ va_start(args, format);
+ vsprintf(buff, format, args);
+ va_end(args);
+ inoLog_serial(buff);
+#else /* ARDUINO */
+ va_list args;
+ va_start(args, format);
+ vprintf(format, args);
+ va_end(args);
+#endif /* ARDUINO */
+}
+
+/* serious errors */
+void embLog_error(const char* format, ...)
+{
+ /* TODO: log debug message in struct for later use */
+
+#ifdef ARDUINO /* ARDUINO */
+ char buff[256];
+ va_list args;
+ va_start(args, format);
+ vsprintf(buff, format, args);
+ va_end(args);
+ inoLog_serial(strcat("ERROR: ", buff));
+#else /* ARDUINO */
+ va_list args;
+ va_start(args, format);
+ printf("ERROR: ");
+ vprintf(format, args);
+ va_end(args);
+#endif /* ARDUINO */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-logging.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-logging.h
new file mode 100644
index 000000000..614809267
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-logging.h
@@ -0,0 +1,24 @@
+/*! @file emb-logging.h */
+#ifndef EMB_LOGGING_H
+#define EMB_LOGGING_H
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef ARDUINO
+#include "utility/ino-logging.h"
+#endif
+
+extern EMB_PUBLIC void EMB_CALL embLog_print(const char* format, ...);
+extern EMB_PUBLIC void EMB_CALL embLog_error(const char* format, ...);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_LOGGING_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-outline.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-outline.c
new file mode 100644
index 000000000..c9092cf15
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-outline.c
@@ -0,0 +1,551 @@
+#include "emb-outline.h"
+#include "emb-pattern.h"
+
+#ifdef ARDUINO /* ARDUINO TODO: remove this line when emb-outline is C89 complete. This is a temporary arduino build fix. */
+#else /* ARDUINO TODO: remove this line when emb-outline is C89 complete. This is a temporary arduino build fix. */
+
+struct StitchBlock
+{
+ IThread Thread { get; set; }
+ double Angle { get; set; }
+ List<VectorStitch> Stitches { get; set; }
+}
+
+double LineLength(EmbPoint a1, EmbPoint a2)
+{
+ return sqrt(pow(a2.X - a1.X, 2) + pow(a2.Y - a1.Y, 2));
+}
+
+double DistancePointPoint(Vector2 p, Vector2 p2)
+{
+ double dx = p.X - p2.X;
+ double dy = p.Y - p2.X;
+ return sqrt(dx * dx + dy * dy);
+}
+
+float GetRelativeX(EmbPoint a1, EmbPoint a2, Point a3)
+{
+ return ((a1.X - a2.X) * (a3.X - a2.X) + (a1.Y - a2.Y) * (a3.Y - a2.Y));
+}
+
+float GetRelativeY(EmbPoint a1, EmbPoint a2, EmbPoint a3)
+{
+ return ((a1.X - a2.X) * (a3.Y - a2.Y) - (a1.Y - a2.Y) * (a3.X - a2.X));
+}
+
+double GetAngle(VectorStitch vs, VectorStitch vs2)
+{
+ return atan((vs2.Xy.X - vs.Xy.X)/(vs2.Xy.Y - vs.Xy.Y));
+}
+
+StitchBlock* BreakIntoColorBlocks(EmbPattern pattern)
+{
+ var sa2 = new StitchBlock();
+ int oldColor = pattern.StitchList[0].ColorIndex;
+ var color = pattern.ColorList[oldColor];
+ sa2.Thread = new Thread(color.Red, color.Blue, color.Green);
+ foreach (Stitch s in pattern.stitchList)
+ {
+ if (s.ColorIndex != oldColor)
+ {
+ yield return sa2;
+ sa2 = new StitchBlock();
+ color = pattern.ColorList[s.ColorIndex];
+ sa2.Thread = new Thread(color.Red, color.Blue, color.Green);
+ oldColor = s.ColorIndex;
+ }
+ var vs = new VectorStitch { Xy = new Point(s.X, s.Y), Color = s.ColorIndex };
+ sa2.Stitches.Add(vs);
+ }
+ yield return sa2;
+}
+
+
+
+StitchBlock * BreakIntoSeparateObjects(EmbStitchBlock* blocks)
+{
+ double previousAngle = 0.0;
+ foreach (var block in blocks)
+ {
+ var stitches = new List<VectorStitch>();
+ block.Stitches[0].Type = VectorStitchType.Contour;
+ block.Stitches[block.Stitches.Count - 1].Type = VectorStitchType.Contour;
+
+ for (int i = 0; i < block.Stitches.Count - 2; i++) // step 0
+ {
+ double dx = (GetRelativeX(block.Stitches[i].Xy, block.Stitches[i + 1].Xy, block.Stitches[i + 2].Xy));
+ block.Stitches[i + 1].Type = dx <= 0 ? VectorStitchType.Run : VectorStitchType.Contour;
+ block.Stitches[i].Angle = GetAngle(block.Stitches[i], block.Stitches[i + 1]);
+ stitches.Add(block.Stitches[i].Clone());
+ if (i > 0)
+ {
+ if ((block.Stitches[i].Type == VectorStitchType.Contour) && Math.Abs(block.Stitches[i].Angle - previousAngle) > (20/180*Math.PI))
+ {
+ yield return
+ new StitchBlock
+ {
+ Stitches = stitches,
+ Angle = stitches.Average(x => x.Angle),
+ Thread = new Thread(block.Thread.Red, block.Thread.Blue, block.Thread.Green)
+ };
+ stitches = new List<VectorStitch>();
+
+ }
+ }
+ }
+
+ //for (int i = 1; i < sa.Stitches.Count - 3; i++) // step 1
+ //{
+ // if (sa.Stitches[i + 1].Type == VectorStitchType.Contour)
+ // {
+ // //float dy = GetRelativeY(sa[i + 1].XY, sa[i + 2].XY, sa[i + 3].XY);
+ // //float dy2 = GetRelativeY(sa[i].XY, sa[i + 1].XY, sa[i + 2].XY);
+ // //float dy3 = GetRelativeY(sa[i + 2].XY, sa[i + 3].XY, sa[i + 4].XY);
+ // //if(dy)
+ // if (sa.Stitches[i - 1].Type == VectorStitchType.Run || sa.Stitches[i + 1].Type == VectorStitchType.Run)
+ // {
+ // sa.Stitches[i].Type = VectorStitchType.Tatami;
+ // }
+ // else
+ // {
+ // sa.Stitches[i].Type = VectorStitchType.Satin;
+ // }
+ // }
+ //}
+ }
+}
+
+StitchObject * FindOutline(EmbStitchBlock* stitchData)
+{
+ int currColorIndex = 0;
+ var pOdd = new List<Point>();
+ var pEven = new List<Point>();
+ foreach (StitchBlock sa in stitchData)
+ {
+ if (sa.Stitches.Count > 0)
+ {
+ sa.Stitches[0].Type = VectorStitchType.Contour;
+ sa.Stitches[sa.Stitches.Count - 1].Type = VectorStitchType.Contour;
+ for (int i = 0; i < sa.Stitches.Count - 2; i++) // step 0
+ {
+ float dx = (GetRelativeX(sa.Stitches[i].Xy, sa.Stitches[i + 1].Xy, sa.Stitches[i + 2].Xy));
+ sa.Stitches[i + 1].Type = dx <= 0 ? VectorStitchType.Run : VectorStitchType.Contour;
+ sa.Stitches[i].Angle = GetAngle(sa.Stitches[i], sa.Stitches[i + 1]);
+ }
+ //for (int i = 1; i < sa.Stitches.Count - 3; i++) // step 1
+ //{
+ // if (sa.Stitches[i + 1].Type == VectorStitchType.Contour)
+ // {
+ // //float dy = GetRelativeY(sa[i + 1].XY, sa[i + 2].XY, sa[i + 3].XY);
+ // //float dy2 = GetRelativeY(sa[i].XY, sa[i + 1].XY, sa[i + 2].XY);
+ // //float dy3 = GetRelativeY(sa[i + 2].XY, sa[i + 3].XY, sa[i + 4].XY);
+ // //if(dy)
+ // if (sa.Stitches[i - 1].Type == VectorStitchType.Run || sa.Stitches[i + 1].Type == VectorStitchType.Run)
+ // {
+ // sa.Stitches[i].Type = VectorStitchType.Tatami;
+ // }
+ // else
+ // {
+ // sa.Stitches[i].Type = VectorStitchType.Satin;
+ // }
+ // }
+ //}
+ }
+
+
+ int oddEven = 0;
+ foreach (VectorStitch t in sa.Stitches)
+ {
+ if ((t.Type == VectorStitchType.Contour) && (oddEven % 2) == 0)
+ {
+ pEven.Add(t.Xy);
+
+ oddEven++;
+ }
+ else if ((t.Type == VectorStitchType.Contour) && (oddEven % 2) == 1)
+ {
+ pOdd.Add(t.Xy);
+ oddEven++;
+ }
+ }
+ currColorIndex++;
+ var so = new StitchObject { SideOne = pEven, SideTwo = pOdd, ColorIndex = currColorIndex };
+ yield return so;
+ pEven = new List<Point>();
+ pOdd = new List<Point>();
+ //break;
+ }
+}
+
+EmbPattern DrawGraphics(EmbPattern p)
+{
+ var stitchData = BreakIntoColorBlocks(p);
+
+
+ //var outBlock = new List<StitchBlock>(BreakIntoSeparateObjects(stitchData));
+ //foreach(var block in stitchData)
+ //{
+ // foreach (var stitch in block.Stitches)
+ // {
+ // if(stitch.Angle != 0)
+ // {
+ // int aaa = 1;
+ // }
+ // }
+ //}
+ //var xxxxx = outBlock;
+ var objectsFound = FindOutline(stitchData);
+ var outPattern = new Pattern();
+ outPattern.AddColor(new Thread(255, 0, 0, "none", "None"));
+ int colorIndex = outPattern.ColorList.Count - 1;
+ var r = new Random();
+ foreach (StitchObject stitchObject in objectsFound)
+ {
+ if (stitchObject.SideOne.Count > 1 && stitchObject.SideTwo.Count > 1)
+ {
+ outPattern.AddColor(new Thread((byte) (r.Next()%256), (byte) (r.Next()%256), (byte) (r.Next()%256),
+ "none", "None"));
+ colorIndex++;
+ outPattern.AddStitchRelative(0, 0, StitchTypes.Stop);
+ var points = stitchObject.Generate2(75);
+ foreach (var point in points)
+ {
+ outPattern.AddStitchAbsolute(point.X, point.Y, StitchTypes.Normal);
+ }
+ //break;
+ //StitchObject stitchObject = objectsFound[1];))
+ //////if (stitchObject.SideOne.Count > 0)
+ //////{
+ ////// outPattern.StitchList.Add(new Stitch(stitchObject.SideOne[0].X, stitchObject.SideOne[0].Y,
+ ////// StitchType.Jump, colorIndex));
+ //////}
+ //////foreach (Point t in stitchObject.SideOne)
+ //////{
+ ////// outPattern.StitchList.Add(new Stitch(t.X, t.Y,
+ ////// StitchType.Normal, colorIndex));
+ //////}
+ //////foreach (Point t in stitchObject.SideTwo)
+ //////{
+ ////// outPattern.StitchList.Add(new Stitch(t.X, t.Y,
+ ////// StitchType.Normal, colorIndex));
+ //////}
+ //break;
+ }
+ }
+ outPattern.AddStitchRelative(0, 0, StitchTypes.End);
+ return outPattern;
+ //return (SimplifyOutline(outPattern));
+}
+
+EmbPattern SimplifyOutline(EmbPattern pattern)
+{
+ var v = new Vertices();
+ v.AddRange(pattern.StitchList.Select(point => new Vector2(point.X, point.Y)));
+ var output = SimplifyTools.DouglasPeuckerSimplify(v, 10);
+ var patternOut = new Pattern();
+ foreach (var color in pattern.ColorList)
+ {
+ patternOut.AddColor(color);
+ }
+
+ foreach (var vertex in output)
+ {
+ patternOut.AddStitchAbsolute(vertex.X, vertex.Y, StitchTypes.Normal);
+ }
+ patternOut.AddStitchRelative(0, 0, StitchTypes.End);
+ return patternOut;
+}
+
+bool[] _usePt;
+double _distanceTolerance;
+
+/* Removes all collinear points on the polygon. */
+Vertices CollinearSimplify(Vertices vertices, float collinearityTolerance)
+{
+ /* We can't simplify polygons under 3 vertices */
+ if (vertices.Count < 3)
+ return vertices;
+
+ var simplified = new Vertices();
+
+ for (int i = 0; i < vertices.Count; i++)
+ {
+ int prevId = vertices.PreviousIndex(i);
+ int nextId = vertices.NextIndex(i);
+
+ Vector2 prev = vertices[prevId];
+ Vector2 current = vertices[i];
+ Vector2 next = vertices[nextId];
+
+ /* If they collinear, continue */
+ if (MathUtils.Collinear(ref prev, ref current, ref next, collinearityTolerance))
+ continue;
+
+ simplified.Add(current);
+ }
+
+ return simplified;
+}
+
+/// <summary>
+/// Removes all collinear points on the polygon.
+/// Has a default bias of 0
+/// </summary>
+/// <param name="vertices">The polygon that needs simplification.</param>
+/// <returns>A simplified polygon.</returns>
+Vertices CollinearSimplify(Vertices vertices)
+{
+ return CollinearSimplify(vertices, 0);
+}
+
+/// Ramer-Douglas-Peucker polygon simplification algorithm. This is the general recursive version that does not use the
+/// speed-up technique by using the Melkman convex hull.
+/// If you pass in 0, it will remove all collinear points
+Vertices DouglasPeuckerSimplify(Vertices vertices, float distanceTolerance)
+{
+ _distanceTolerance = distanceTolerance;
+
+ _usePt = new bool[vertices.Count];
+ for (int i = 0; i < vertices.Count; i++)
+ {
+ _usePt[i] = true;
+ }
+ SimplifySection(vertices, 0, vertices.Count - 1);
+ var result = new Vertices();
+ result.AddRange(vertices.Where((t, i) => _usePt[i]));
+ return result;
+}
+
+void SimplifySection(Vertices vertices, int i, int j)
+{
+ if ((i + 1) == j)
+ return;
+
+ Vector2 a = vertices[i];
+ Vector2 b = vertices[j];
+ double maxDistance = -1.0;
+ int maxIndex = i;
+ for (int k = i + 1; k < j; k++)
+ {
+ double distance = DistancePointLine(vertices[k], a, b);
+
+ if (distance > maxDistance)
+ {
+ maxDistance = distance;
+ maxIndex = k;
+ }
+ }
+ if (maxDistance <= _distanceTolerance)
+ {
+ for (int k = i + 1; k < j; k++)
+ {
+ _usePt[k] = false;
+ }
+ }
+ else
+ {
+ SimplifySection(vertices, i, maxIndex);
+ SimplifySection(vertices, maxIndex, j);
+ }
+}
+
+double DistancePointLine(EmbPoint p, EmbPoint a, EmbPoint b)
+{
+ /* if start == end, then use point-to-point distance */
+ if (a.X == b.X && a.Y == b.Y)
+ return DistancePointPoint(p, a);
+
+ // otherwise use comp.graphics.algorithms Frequently Asked Questions method
+ /*(1) AC dot AB
+ r = ---------
+ ||AB||^2
+
+ r has the following meaning:
+ r=0 Point = A
+ r=1 Point = B
+ r<0 Point is on the backward extension of AB
+ r>1 Point is on the forward extension of AB
+ 0<r<1 Point is interior to AB
+ */
+
+ double r = ((p.X - a.X) * (b.X - a.X) + (p.Y - a.Y) * (b.Y - a.Y))
+ /
+ ((b.X - a.X) * (b.X - a.X) + (b.Y - a.Y) * (b.Y - a.Y));
+
+ if (r <= 0.0) return DistancePointPoint(p, a);
+ if (r >= 1.0) return DistancePointPoint(p, b);
+
+
+ /*(2)
+ (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay)
+ s = -----------------------------
+ Curve^2
+
+ Then the distance from C to Point = |s|*Curve.
+ */
+
+ double s = ((a.Y - p.Y) * (b.X - a.X) - (a.X - p.X) * (b.Y - a.Y))
+ /
+ ((b.X - a.X) * (b.X - a.X) + (b.Y - a.Y) * (b.Y - a.Y));
+
+ return Math.Abs(s) * Math.Sqrt(((b.X - a.X) * (b.X - a.X) + (b.Y - a.Y) * (b.Y - a.Y)));
+}
+
+/* From physics2d.net */
+public static Vertices ReduceByArea(Vertices vertices, float areaTolerance)
+{
+ if (vertices.Count <= 3)
+ return vertices;
+
+ if (areaTolerance < 0)
+ {
+ throw new ArgumentOutOfRangeException("areaTolerance", "must be equal to or greater then zero.");
+ }
+
+ var result = new Vertices();
+ Vector2 v3;
+ Vector2 v1 = vertices[vertices.Count - 2];
+ Vector2 v2 = vertices[vertices.Count - 1];
+ areaTolerance *= 2;
+ for (int index = 0; index < vertices.Count; ++index, v2 = v3)
+ {
+ if (index == vertices.Count - 1)
+ {
+ if (result.Count == 0)
+ {
+ throw new ArgumentOutOfRangeException("areaTolerance", "The tolerance is too high!");
+ }
+ v3 = result[0];
+ }
+ else
+ {
+ v3 = vertices[index];
+ }
+ float old1;
+ MathUtils.Cross(ref v1, ref v2, out old1);
+ float old2;
+ MathUtils.Cross(ref v2, ref v3, out old2);
+ float new1;
+ MathUtils.Cross(ref v1, ref v3, out new1);
+ if (Math.Abs(new1 - (old1 + old2)) > areaTolerance)
+ {
+ result.Add(v2);
+ v1 = v2;
+ }
+ }
+ return result;
+}
+
+/* From Eric Jordan's convex decomposition library */
+/* Merges all parallel edges in the list of vertices */
+public static void MergeParallelEdges(Vertices vertices, float tolerance)
+{
+ if (vertices.Count <= 3)
+ return; /* Can't do anything useful here to a triangle */
+
+ var mergeMe = new bool[vertices.Count];
+ int newNVertices = vertices.Count;
+
+ /* Gather points to process */
+ for (int i = 0; i < vertices.Count; ++i)
+ {
+ int lower = (i == 0) ? (vertices.Count - 1) : (i - 1);
+ int middle = i;
+ int upper = (i == vertices.Count - 1) ? (0) : (i + 1);
+
+ float dx0 = vertices[middle].X - vertices[lower].X;
+ float dy0 = vertices[middle].Y - vertices[lower].Y;
+ float dx1 = vertices[upper].Y - vertices[middle].X;
+ float dy1 = vertices[upper].Y - vertices[middle].Y;
+ var norm0 = (float)Math.Sqrt(dx0 * dx0 + dy0 * dy0);
+ var norm1 = (float)Math.Sqrt(dx1 * dx1 + dy1 * dy1);
+
+ if (!(norm0 > 0.0f && norm1 > 0.0f) && newNVertices > 3)
+ {
+ /* Merge identical points */
+ mergeMe[i] = true;
+ --newNVertices;
+ }
+
+ dx0 /= norm0;
+ dy0 /= norm0;
+ dx1 /= norm1;
+ dy1 /= norm1;
+ float cross = dx0 * dy1 - dx1 * dy0;
+ float dot = dx0 * dx1 + dy0 * dy1;
+
+ if (Math.Abs(cross) < tolerance && dot > 0 && newNVertices > 3)
+ {
+ mergeMe[i] = true;
+ --newNVertices;
+ }
+ else
+ mergeMe[i] = false;
+ }
+
+ if (newNVertices == vertices.Count || newNVertices == 0)
+ return;
+
+ int currIndex = 0;
+
+ /* Copy the vertices to a new list and clear the old */
+ var oldVertices = new Vertices(vertices);
+ vertices.Clear();
+
+ for (int i = 0; i < oldVertices.Count; ++i)
+ {
+ if (mergeMe[i] || newNVertices == 0 || currIndex == newNVertices)
+ continue;
+
+ vertices.Add(oldVertices[i]);
+ ++currIndex;
+ }
+}
+
+/* Reduces the polygon by distance. */
+Vertices ReduceByDistance(Vertices vertices, float distance)
+{
+ /* We can't simplify polygons under 3 vertices */
+ if (vertices.Count < 3)
+ return vertices;
+
+ distance *= distance;
+
+ var simplified = new Vertices();
+
+ for (int i = 0; i < vertices.Count; i++)
+ {
+ int nextId = vertices.NextIndex(i);
+
+ Vector2 current = vertices[i];
+ Vector2 next = vertices[nextId];
+
+ /* If they are closer than the distance, continue */
+ if ((next - current).LengthSquared() <= distance)
+ continue;
+
+ simplified.Add(current);
+ }
+
+ return simplified;
+}
+
+/* Reduces the polygon by removing the Nth vertex in the vertices list. */
+Vertices ReduceByNth(Vertices vertices, int nth)
+{
+ /* We can't simplify polygons under 3 vertices */
+ if (vertices.Count < 3)
+ return vertices;
+
+ if (nth == 0)
+ return vertices;
+
+ var result = new Vertices(vertices.Count);
+ result.AddRange(vertices.Where((t, i) => i%nth != 0));
+
+ return result;
+}
+
+#endif /* ARDUINO TODO: remove this line when emb-outline is C89 complete. This is a temporary arduino build fix. */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-outline.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-outline.h
new file mode 100644
index 000000000..cb4467fc5
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-outline.h
@@ -0,0 +1,18 @@
+/*! @file emb-outline.h */
+#ifndef EMB_OUTLINE_H
+#define EMB_OUTLINE_H
+
+#ifdef ARDUINO /* ARDUINO TODO: remove this line when emb-outline is C89 complete. This is a temporary arduino build fix. */
+#else /* ARDUINO TODO: remove this line when emb-outline is C89 complete. This is a temporary arduino build fix. */
+
+class embOutline
+{
+public:
+ embOutline();
+};
+#endif /* ARDUINO TODO: remove this line when emb-outline is C89 complete. This is a temporary arduino build fix. */
+
+
+#endif // EMB_OUTLINE_H
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-path.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-path.c
new file mode 100644
index 000000000..7c9050e7a
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-path.c
@@ -0,0 +1,96 @@
+#include "emb-path.h"
+#include "emb-logging.h"
+#include <stdlib.h>
+
+/**************************************************/
+/* EmbPathObject */
+/**************************************************/
+
+EmbPathObject* embPathObject_create(EmbPointList* pointList, EmbFlagList* flagList, EmbColor color, int lineType)
+{
+ EmbPathObject* heapPathObj = 0;
+ if(!pointList) { embLog_error("emb-path.c embPathObject_create(), pointList argument is null\n"); return 0; }
+ if(!flagList) { embLog_error("emb-path.c embPathObject_create(), flagList argument is null\n"); return 0; }
+ heapPathObj = (EmbPathObject*)malloc(sizeof(EmbPathObject));
+ if(!heapPathObj) { embLog_error("emb-path.c embPathObject_create(), cannot allocate memory for heapPathObj\n"); return 0; }
+ heapPathObj->pointList = pointList;
+ heapPathObj->flagList = flagList;
+ /* TODO: layer */
+ heapPathObj->color = color;
+ heapPathObj->lineType = lineType;
+ return heapPathObj;
+}
+
+void embPathObject_free(EmbPathObject* pointer)
+{
+ embPointList_free(pointer->pointList);
+ pointer->pointList = 0;
+ embFlagList_free(pointer->flagList);
+ pointer->flagList = 0;
+ free(pointer);
+ pointer = 0;
+}
+
+/**************************************************/
+/* EmbPathObjectList */
+/**************************************************/
+
+EmbPathObjectList* embPathObjectList_create(EmbPathObject* data)
+{
+ EmbPathObjectList* heapPathObjList = 0;
+ if(!data) { embLog_error("emb-path.c embPathObjectList_create(), data argument is null\n"); return 0; }
+ heapPathObjList = (EmbPathObjectList*)malloc(sizeof(EmbPathObjectList));
+ if(!heapPathObjList) { embLog_error("emb-path.c embPathObjectList_create(), cannot allocate memory for heapPathObjList\n"); return 0; }
+ heapPathObjList->pathObj = data;
+ heapPathObjList->next = 0;
+ return heapPathObjList;
+}
+
+EmbPathObjectList* embPathObjectList_add(EmbPathObjectList* pointer, EmbPathObject* data)
+{
+ if(!pointer) { embLog_error("emb-path.c embPathObjectList_add(), pointer argument is null\n"); return 0; }
+ if(!data) { embLog_error("emb-path.c embPathObjectList_add(), data argument is null\n"); return 0; }
+ if(pointer->next) { embLog_error("emb-path.c embPathObjectList_add(), pointer->next should be null\n"); return 0; }
+ pointer->next = (EmbPathObjectList*)malloc(sizeof(EmbPathObjectList));
+ if(!pointer->next) { embLog_error("emb-path.c embPathObjectList_add(), cannot allocate memory for pointer->next\n"); return 0; }
+ pointer = pointer->next;
+ pointer->pathObj = data;
+ pointer->next = 0;
+ return pointer;
+}
+
+int embPathObjectList_count(EmbPathObjectList* pointer)
+{
+ int i = 1;
+ if(!pointer) return 0;
+ while(pointer->next)
+ {
+ pointer = pointer->next;
+ i++;
+ }
+ return i;
+}
+
+int embPathObjectList_empty(EmbPathObjectList* pointer)
+{
+ if(!pointer)
+ return 1;
+ return 0;
+}
+
+void embPathObjectList_free(EmbPathObjectList* pointer)
+{
+ EmbPathObjectList* tempPointer = pointer;
+ EmbPathObjectList* nextPointer = 0;
+ while(tempPointer)
+ {
+ nextPointer = tempPointer->next;
+ embPathObject_free(tempPointer->pathObj);
+ tempPointer->pathObj = 0;
+ free(tempPointer);
+ tempPointer = nextPointer;
+ }
+ pointer = 0;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-path.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-path.h
new file mode 100644
index 000000000..2180459ec
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-path.h
@@ -0,0 +1,59 @@
+/*! @file emb-path.h */
+#ifndef EMB_PATH_H
+#define EMB_PATH_H
+
+#include "emb-color.h"
+#include "emb-point.h"
+#include "emb-flag.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* path flag codes */
+#define LINETO 0
+#define MOVETO 1
+#define BULGETOCONTROL 2
+#define BULGETOEND 4
+#define ELLIPSETORAD 8
+#define ELLIPSETOEND 16
+#define CUBICTOCONTROL1 32
+#define CUBICTOCONTROL2 64
+#define CUBICTOEND 128
+#define QUADTOCONTROL 256
+#define QUADTOEND 512
+
+typedef struct EmbPathObject_
+{
+ EmbPointList* pointList;
+ EmbFlagList* flagList;
+
+ /* Properties */
+ int lineType;
+ EmbColor color;
+} EmbPathObject;
+
+extern EMB_PUBLIC EmbPathObject* EMB_CALL embPathObject_create(EmbPointList* pointList, EmbFlagList* flagList, EmbColor color, int lineType);
+extern EMB_PUBLIC void EMB_CALL embPathObject_free(EmbPathObject* pointer);
+
+typedef struct EmbPathObjectList_
+{
+ EmbPathObject* pathObj;
+ struct EmbPathObjectList_* next;
+} EmbPathObjectList;
+
+extern EMB_PUBLIC EmbPathObjectList* EMB_CALL embPathObjectList_create(EmbPathObject* data);
+extern EMB_PUBLIC EmbPathObjectList* EMB_CALL embPathObjectList_add(EmbPathObjectList* pointer, EmbPathObject* data);
+extern EMB_PUBLIC int EMB_CALL embPathObjectList_count(EmbPathObjectList* pointer);
+extern EMB_PUBLIC int EMB_CALL embPathObjectList_empty(EmbPathObjectList* pointer);
+extern EMB_PUBLIC void EMB_CALL embPathObjectList_free(EmbPathObjectList* pointer);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_PATH_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-pattern.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-pattern.c
new file mode 100644
index 000000000..6a4d2e0d0
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-pattern.c
@@ -0,0 +1,1068 @@
+#include "emb-pattern.h"
+#include "emb-reader-writer.h"
+#include "emb-settings.h"
+#include "emb-logging.h"
+#include "helpers-misc.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+
+#ifdef ARDUINO
+#include "utility/ino-event.h"
+#endif
+
+/*! Returns a pointer to an EmbPattern. It is created on the heap. The caller is responsible for freeing the allocated memory with embPattern_free(). */
+EmbPattern* embPattern_create(void)
+{
+ EmbPattern* p = 0;
+ p = (EmbPattern*)malloc(sizeof(EmbPattern));
+ if(!p) { embLog_error("emb-pattern.c embPattern_create(), unable to allocate memory for p\n"); return 0; }
+
+ p->settings = embSettings_init();
+ p->currentColorIndex = 0;
+ p->stitchList = 0;
+ p->threadList = 0;
+
+ p->hoop.height = 0.0;
+ p->hoop.width = 0.0;
+ p->arcObjList = 0;
+ p->circleObjList = 0;
+ p->ellipseObjList = 0;
+ p->lineObjList = 0;
+ p->pathObjList = 0;
+ p->pointObjList = 0;
+ p->polygonObjList = 0;
+ p->polylineObjList = 0;
+ p->rectObjList = 0;
+ p->splineObjList = 0;
+
+ p->lastStitch = 0;
+ p->lastThread = 0;
+
+ p->lastArcObj = 0;
+ p->lastCircleObj = 0;
+ p->lastLineObj = 0;
+ p->lastEllipseObj = 0;
+ p->lastPathObj = 0;
+ p->lastPointObj = 0;
+ p->lastPolygonObj = 0;
+ p->lastPolylineObj = 0;
+ p->lastRectObj = 0;
+ p->lastSplineObj = 0;
+
+ p->lastX = 0.0;
+ p->lastY = 0.0;
+
+ return p;
+}
+
+void embPattern_hideStitchesOverLength(EmbPattern* p, int length)
+{
+ double prevX = 0;
+ double prevY = 0;
+ EmbStitchList* pointer = 0;
+
+ if(!p) { embLog_error("emb-pattern.c embPattern_hideStitchesOverLength(), p argument is null\n"); return; }
+ pointer = p->stitchList;
+ while(pointer)
+ {
+ if((fabs(pointer->stitch.xx - prevX) > length) || (fabs(pointer->stitch.yy - prevY) > length))
+ {
+ pointer->stitch.flags |= TRIM;
+ pointer->stitch.flags &= ~NORMAL;
+ }
+ prevX = pointer->stitch.xx;
+ prevY = pointer->stitch.yy;
+ pointer = pointer->next;
+ }
+}
+
+int embPattern_addThread(EmbPattern* p, EmbThread thread)
+{
+ if(!p) { embLog_error("emb-pattern.c embPattern_addThread(), p argument is null\n"); return 0; }
+ if(embThreadList_empty(p->threadList))
+ {
+ p->threadList = p->lastThread = embThreadList_create(thread);
+ }
+ else
+ {
+ p->lastThread = embThreadList_add(p->lastThread, thread);
+ }
+ return 1;
+}
+
+void embPattern_fixColorCount(EmbPattern* p)
+{
+ /* fix color count to be max of color index. */
+ int maxColorIndex = 0;
+ EmbStitchList* list = 0;
+
+ if(!p) { embLog_error("emb-pattern.c embPattern_fixColorCount(), p argument is null\n"); return; }
+ list = p->stitchList;
+ while(list)
+ {
+ maxColorIndex = max(maxColorIndex, list->stitch.color);
+ list = list->next;
+ }
+#ifndef ARDUINO
+ /* ARDUINO TODO: The while loop below never ends because memory cannot be allocated in the addThread
+ * function and thus the thread count is never incremented. Arduino or not, it's wrong.
+ */
+ while((int)embThreadList_count(p->threadList) <= maxColorIndex)
+ {
+ embPattern_addThread(p, embThread_getRandom());
+ }
+#endif
+ /*
+ while(embThreadList_count(p->threadList) > (maxColorIndex + 1))
+ {
+ TODO: erase last color p->threadList.pop_back();
+ }
+ */
+}
+
+/*! Copies all of the EmbStitchList data to EmbPolylineObjectList data for pattern (\a p). */
+void embPattern_copyStitchListToPolylines(EmbPattern* p)
+{
+ EmbStitchList* stList = 0;
+ int breakAtFlags;
+
+ if(!p) { embLog_error("emb-pattern.c embPattern_copyStitchListToPolylines(), p argument is null\n"); return; }
+
+#ifdef EMB_DEBUG_JUMP
+ breakAtFlags = (STOP | TRIM);
+#else /* EMB_DEBUG_JUMP */
+ breakAtFlags = (STOP | JUMP | TRIM);
+#endif /* EMB_DEBUG_JUMP */
+
+ stList = p->stitchList;
+ while(stList)
+ {
+ EmbPointList* pointList = 0;
+ EmbPointList* lastPoint = 0;
+ EmbColor color;
+ while(stList)
+ {
+ if(stList->stitch.flags & breakAtFlags)
+ {
+ break;
+ }
+ if(!(stList->stitch.flags & JUMP))
+ {
+ if(!pointList)
+ {
+ pointList = lastPoint = embPointList_create(stList->stitch.xx, stList->stitch.yy);
+ color = embThreadList_getAt(p->threadList, stList->stitch.color).color;
+ }
+ else
+ {
+ lastPoint = embPointList_add(lastPoint, embPoint_make(stList->stitch.xx, stList->stitch.yy));
+ }
+ }
+ stList = stList->next;
+ }
+
+ /* NOTE: Ensure empty polylines are not created. This is critical. */
+ if(pointList)
+ {
+ EmbPolylineObject* currentPolyline = (EmbPolylineObject*)malloc(sizeof(EmbPolylineObject));
+ if(!currentPolyline) { embLog_error("emb-pattern.c embPattern_copyStitchListToPolylines(), cannot allocate memory for currentPolyline\n"); return; }
+ currentPolyline->pointList = pointList;
+ currentPolyline->color = color;
+ currentPolyline->lineType = 1; /* TODO: Determine what the correct value should be */
+
+ if(embPolylineObjectList_empty(p->polylineObjList))
+ {
+ p->polylineObjList = p->lastPolylineObj = embPolylineObjectList_create(currentPolyline);
+ }
+ else
+ {
+ p->lastPolylineObj = embPolylineObjectList_add(p->lastPolylineObj, currentPolyline);
+ }
+ }
+ if(stList)
+ {
+ stList = stList->next;
+ }
+ }
+}
+
+/*! Copies all of the EmbPolylineObjectList data to EmbStitchList data for pattern (\a p). */
+void embPattern_copyPolylinesToStitchList(EmbPattern* p)
+{
+ EmbPolylineObjectList* polyList = 0;
+ int firstObject = 1;
+ /*int currentColor = polyList->polylineObj->color TODO: polyline color */
+
+ if(!p) { embLog_error("emb-pattern.c embPattern_copyPolylinesToStitchList(), p argument is null\n"); return; }
+ polyList = p->polylineObjList;
+ while(polyList)
+ {
+ EmbPolylineObject* currentPoly = 0;
+ EmbPointList* currentPointList = 0;
+ EmbThread thread;
+
+ currentPoly = polyList->polylineObj;
+ if(!currentPoly) { embLog_error("emb-pattern.c embPattern_copyPolylinesToStitchList(), currentPoly is null\n"); return; }
+ currentPointList = currentPoly->pointList;
+ if(!currentPointList) { embLog_error("emb-pattern.c embPattern_copyPolylinesToStitchList(), currentPointList is null\n"); return; }
+
+ thread.catalogNumber = 0;
+ thread.color = currentPoly->color;
+ thread.description = 0;
+ embPattern_addThread(p, thread);
+
+ if(!firstObject)
+ {
+ embPattern_addStitchAbs(p, currentPointList->point.xx, currentPointList->point.yy, TRIM, 1);
+ embPattern_addStitchRel(p, 0.0, 0.0, STOP, 1);
+ }
+
+ embPattern_addStitchAbs(p, currentPointList->point.xx, currentPointList->point.yy, JUMP, 1);
+ while(currentPointList)
+ {
+ embPattern_addStitchAbs(p, currentPointList->point.xx, currentPointList->point.yy, NORMAL, 1);
+ currentPointList = currentPointList->next;
+ }
+ firstObject = 0;
+ polyList = polyList->next;
+ }
+ embPattern_addStitchRel(p, 0.0, 0.0, END, 1);
+}
+
+/*! Moves all of the EmbStitchList data to EmbPolylineObjectList data for pattern (\a p). */
+void embPattern_moveStitchListToPolylines(EmbPattern* p)
+{
+ if(!p) { embLog_error("emb-pattern.c embPattern_moveStitchListToPolylines(), p argument is null\n"); return; }
+ embPattern_copyStitchListToPolylines(p);
+ /* Free the stitchList and threadList since their data has now been transferred to polylines */
+ embStitchList_free(p->stitchList);
+ p->stitchList = 0;
+ p->lastStitch = 0;
+ embThreadList_free(p->threadList);
+ p->threadList = 0;
+ p->lastThread = 0;
+}
+
+/*! Moves all of the EmbPolylineObjectList data to EmbStitchList data for pattern (\a p). */
+void embPattern_movePolylinesToStitchList(EmbPattern* p)
+{
+ if(!p) { embLog_error("emb-pattern.c embPattern_movePolylinesToStitchList(), p argument is null\n"); return; }
+ embPattern_copyPolylinesToStitchList(p);
+ embPolylineObjectList_free(p->polylineObjList);
+ p->polylineObjList = 0;
+ p->lastPolylineObj = 0;
+}
+
+/*! Adds a stitch to the pattern (\a p) at the absolute position (\a x,\a y). Positive y is up. Units are in millimeters. */
+void embPattern_addStitchAbs(EmbPattern* p, double x, double y, int flags, int isAutoColorIndex)
+{
+ EmbStitch s;
+
+ if(!p) { embLog_error("emb-pattern.c embPattern_addStitchAbs(), p argument is null\n"); return; }
+
+ if(flags & END)
+ {
+ if(embStitchList_empty(p->stitchList))
+ return;
+ /* Prevent unnecessary multiple END stitches */
+ if(p->lastStitch->stitch.flags & END)
+ {
+ embLog_error("emb-pattern.c embPattern_addStitchAbs(), found multiple END stitches\n");
+ return;
+ }
+
+ embPattern_fixColorCount(p);
+
+ /* HideStitchesOverLength(127); TODO: fix or remove this */
+ }
+
+ if(flags & STOP)
+ {
+ if(embStitchList_empty(p->stitchList))
+ return;
+ if(isAutoColorIndex)
+ p->currentColorIndex++;
+ }
+
+ /* NOTE: If the stitchList is empty, we will create it before adding stitches to it. The first coordinate will be the HOME position. */
+ if(embStitchList_empty(p->stitchList))
+ {
+ /* NOTE: Always HOME the machine before starting any stitching */
+ EmbPoint home = embSettings_home(&(p->settings));
+ EmbStitch h;
+ h.xx = home.xx;
+ h.yy = home.yy;
+ h.flags = JUMP;
+ h.color = p->currentColorIndex;
+ p->stitchList = p->lastStitch = embStitchList_create(h);
+ }
+
+ s.xx = x;
+ s.yy = y;
+ s.flags = flags;
+ s.color = p->currentColorIndex;
+#ifdef ARDUINO
+ inoEvent_addStitchAbs(p, s.xx, s.yy, s.flags, s.color);
+#else /* ARDUINO */
+ p->lastStitch = embStitchList_add(p->lastStitch, s);
+#endif /* ARDUINO */
+ p->lastX = s.xx;
+ p->lastY = s.yy;
+}
+
+/*! Adds a stitch to the pattern (\a p) at the relative position (\a dx,\a dy) to the previous stitch. Positive y is up. Units are in millimeters. */
+void embPattern_addStitchRel(EmbPattern* p, double dx, double dy, int flags, int isAutoColorIndex)
+{
+ double x,y;
+
+ if(!p) { embLog_error("emb-pattern.c embPattern_addStitchRel(), p argument is null\n"); return; }
+ if(!embStitchList_empty(p->stitchList))
+ {
+ x = p->lastX + dx;
+ y = p->lastY + dy;
+ }
+ else
+ {
+ /* NOTE: The stitchList is empty, so add it to the HOME position. The embStitchList_create function will ensure the first coordinate is at the HOME position. */
+ EmbPoint home = embSettings_home(&(p->settings));
+ x = home.xx + dx;
+ y = home.yy + dy;
+ }
+ embPattern_addStitchAbs(p, x, y, flags, isAutoColorIndex);
+}
+
+void embPattern_changeColor(EmbPattern* p, int index)
+{
+ if(!p) { embLog_error("emb-pattern.c embPattern_changeColor(), p argument is null\n"); return; }
+ p->currentColorIndex = index;
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int embPattern_read(EmbPattern* pattern, const char* fileName) /* TODO: Write test case using this convenience function. */
+{
+ EmbReaderWriter* reader = 0;
+ int result = 0;
+
+ if(!pattern) { embLog_error("emb-pattern.c embPattern_read(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("emb-pattern.c embPattern_read(), fileName argument is null\n"); return 0; }
+
+ reader = embReaderWriter_getByFileName(fileName);
+ if(!reader) { embLog_error("emb-pattern.c embPattern_read(), unsupported read file type: %s\n", fileName); return 0; }
+ result = reader->reader(pattern, fileName);
+ free(reader);
+ reader = 0;
+ return result;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int embPattern_write(EmbPattern* pattern, const char* fileName) /* TODO: Write test case using this convenience function. */
+{
+ EmbReaderWriter* writer = 0;
+ int result = 0;
+
+ if(!pattern) { embLog_error("emb-pattern.c embPattern_write(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("emb-pattern.c embPattern_write(), fileName argument is null\n"); return 0; }
+
+ writer = embReaderWriter_getByFileName(fileName);
+ if(!writer) { embLog_error("emb-pattern.c embPattern_write(), unsupported write file type: %s\n", fileName); return 0; }
+ result = writer->writer(pattern, fileName);
+ free(writer);
+ writer = 0;
+ return result;
+}
+
+/* Very simple scaling of the x and y axis for every point.
+* Doesn't insert or delete stitches to preserve density. */
+void embPattern_scale(EmbPattern* p, double scale)
+{
+ EmbStitchList* pointer = 0;
+
+ if(!p) { embLog_error("emb-pattern.c embPattern_scale(), p argument is null\n"); return; }
+ pointer = p->stitchList;
+ while(pointer)
+ {
+ pointer->stitch.xx *= scale;
+ pointer->stitch.yy *= scale;
+ pointer = pointer->next;
+ }
+}
+
+/*! Returns an EmbRect that encapsulates all stitches and objects in the pattern (\a p). */
+EmbRect embPattern_calcBoundingBox(EmbPattern* p)
+{
+ EmbStitchList* pointer = 0;
+ EmbRect boundingRect;
+ EmbStitch pt;
+ EmbArcObjectList* aObjList = 0;
+ EmbArc arc;
+ EmbCircleObjectList* cObjList = 0;
+ EmbCircle circle;
+ EmbEllipseObjectList* eObjList = 0;
+ EmbEllipse ellipse;
+ EmbLineObjectList* liObjList = 0;
+ EmbLine line;
+ EmbPointObjectList* pObjList = 0;
+ EmbPoint point;
+ EmbPolygonObjectList* pogObjList = 0;
+ EmbPointList* pogPointList = 0;
+ EmbPoint pogPoint;
+ EmbPolylineObjectList* polObjList = 0;
+ EmbPointList* polPointList = 0;
+ EmbPoint polPoint;
+ EmbRectObjectList* rObjList = 0;
+ EmbRect rect;
+ EmbSplineObjectList* sObjList = 0;
+ EmbBezier bezier;
+
+ boundingRect.left = 0;
+ boundingRect.right = 0;
+ boundingRect.top = 0;
+ boundingRect.bottom = 0;
+
+ if(!p) { embLog_error("emb-pattern.c embPattern_calcBoundingBox(), p argument is null\n"); return boundingRect; }
+
+ /* Calculate the bounding rectangle. It's needed for smart repainting. */
+ /* TODO: Come back and optimize this mess so that after going thru all objects
+ and stitches, if the rectangle isn't reasonable, then return a default rect */
+ if(embStitchList_empty(p->stitchList) &&
+ embArcObjectList_empty(p->arcObjList) &&
+ embCircleObjectList_empty(p->circleObjList) &&
+ embEllipseObjectList_empty(p->ellipseObjList) &&
+ embLineObjectList_empty(p->lineObjList) &&
+ embPointObjectList_empty(p->pointObjList) &&
+ embPolygonObjectList_empty(p->polygonObjList) &&
+ embPolylineObjectList_empty(p->polylineObjList) &&
+ embRectObjectList_empty(p->rectObjList) &&
+ embSplineObjectList_empty(p->splineObjList))
+ {
+ boundingRect.top = 0.0;
+ boundingRect.left = 0.0;
+ boundingRect.bottom = 1.0;
+ boundingRect.right = 1.0;
+ return boundingRect;
+ }
+ boundingRect.left = 99999.0;
+ boundingRect.top = 99999.0;
+ boundingRect.right = -99999.0;
+ boundingRect.bottom = -99999.0;
+
+ pointer = p->stitchList;
+ while(pointer)
+ {
+ /* If the point lies outside of the accumulated bounding
+ * rectangle, then inflate the bounding rect to include it. */
+ pt = pointer->stitch;
+ if(!(pt.flags & TRIM))
+ {
+ boundingRect.left = (double)min(boundingRect.left, pt.xx);
+ boundingRect.top = (double)min(boundingRect.top, pt.yy);
+ boundingRect.right = (double)max(boundingRect.right, pt.xx);
+ boundingRect.bottom = (double)max(boundingRect.bottom, pt.yy);
+ }
+ pointer = pointer->next;
+ }
+
+ aObjList = p->arcObjList;
+ while(aObjList)
+ {
+ arc = aObjList->arcObj.arc;
+ /* TODO: embPattern_calcBoundingBox for arcs */
+
+ aObjList = aObjList->next;
+ }
+
+ cObjList = p->circleObjList;
+ while(cObjList)
+ {
+ circle = cObjList->circleObj.circle;
+ boundingRect.left = (double)min(boundingRect.left, circle.centerX - circle.radius);
+ boundingRect.top = (double)min(boundingRect.top, circle.centerY - circle.radius);
+ boundingRect.right = (double)max(boundingRect.right, circle.centerX + circle.radius);
+ boundingRect.bottom = (double)max(boundingRect.bottom, circle.centerY + circle.radius);
+
+ cObjList = cObjList->next;
+ }
+
+ eObjList = p->ellipseObjList;
+ while(eObjList)
+ {
+ ellipse = eObjList->ellipseObj.ellipse;
+ /* TODO: embPattern_calcBoundingBox for ellipses */
+
+ eObjList = eObjList->next;
+ }
+
+ liObjList = p->lineObjList;
+ while(liObjList)
+ {
+ line = liObjList->lineObj.line;
+ /* TODO: embPattern_calcBoundingBox for lines */
+
+ liObjList = liObjList->next;
+ }
+
+ pObjList = p->pointObjList;
+ while(pObjList)
+ {
+ point = pObjList->pointObj.point;
+ /* TODO: embPattern_calcBoundingBox for points */
+
+ pObjList = pObjList->next;
+ }
+
+ pogObjList = p->polygonObjList;
+ while(pogObjList)
+ {
+ pogPointList = pogObjList->polygonObj->pointList;
+ while(pogPointList)
+ {
+ pogPoint = pogPointList->point;
+ /* TODO: embPattern_calcBoundingBox for polygons */
+
+ pogPointList = pogPointList->next;
+ }
+ pogObjList = pogObjList->next;
+ }
+
+ polObjList = p->polylineObjList;
+ while(polObjList)
+ {
+ polPointList = polObjList->polylineObj->pointList;
+ while(polPointList)
+ {
+ polPoint = polPointList->point;
+ /* TODO: embPattern_calcBoundingBox for polylines */
+
+ polPointList = polPointList->next;
+ }
+ polObjList = polObjList->next;
+ }
+
+ rObjList = p->rectObjList;
+ while(rObjList)
+ {
+ rect = rObjList->rectObj.rect;
+ /* TODO: embPattern_calcBoundingBox for rectangles */
+
+ rObjList = rObjList->next;
+ }
+
+ sObjList = p->splineObjList;
+ while(sObjList)
+ {
+ bezier = sObjList->splineObj.bezier;
+ /* TODO: embPattern_calcBoundingBox for splines */
+
+ sObjList = sObjList->next;
+ }
+
+ return boundingRect;
+}
+
+/*! Flips the entire pattern (\a p) horizontally about the y-axis. */
+void embPattern_flipHorizontal(EmbPattern* p)
+{
+ if(!p) { embLog_error("emb-pattern.c embPattern_flipHorizontal(), p argument is null\n"); return; }
+ embPattern_flip(p, 1, 0);
+}
+
+/*! Flips the entire pattern (\a p) vertically about the x-axis. */
+void embPattern_flipVertical(EmbPattern* p)
+{
+ if(!p) { embLog_error("emb-pattern.c embPattern_flipVertical(), p argument is null\n"); return; }
+ embPattern_flip(p, 0, 1);
+}
+
+/*! Flips the entire pattern (\a p) horizontally about the x-axis if (\a horz) is true.
+ * Flips the entire pattern (\a p) vertically about the y-axis if (\a vert) is true. */
+void embPattern_flip(EmbPattern* p, int horz, int vert)
+{
+ EmbStitchList* stList = 0;
+ EmbArcObjectList* aObjList = 0;
+ EmbCircleObjectList* cObjList = 0;
+ EmbEllipseObjectList* eObjList = 0;
+ EmbLineObjectList* liObjList = 0;
+ EmbPathObjectList* paObjList = 0;
+ EmbPointList* paPointList = 0;
+ EmbPointObjectList* pObjList = 0;
+ EmbPolygonObjectList* pogObjList = 0;
+ EmbPointList* pogPointList = 0;
+ EmbPolylineObjectList* polObjList = 0;
+ EmbPointList* polPointList = 0;
+ EmbRectObjectList* rObjList = 0;
+ EmbSplineObjectList* sObjList = 0;
+
+ if(!p) { embLog_error("emb-pattern.c embPattern_flip(), p argument is null\n"); return; }
+
+ stList = p->stitchList;
+ while(stList)
+ {
+ if(horz) { stList->stitch.xx = -stList->stitch.xx; }
+ if(vert) { stList->stitch.yy = -stList->stitch.yy; }
+ stList = stList->next;
+ }
+
+ aObjList = p->arcObjList;
+ while(aObjList)
+ {
+ /* TODO: embPattern_flip for arcs */
+ aObjList = aObjList->next;
+ }
+
+ cObjList = p->circleObjList;
+ while(cObjList)
+ {
+ if(horz) { cObjList->circleObj.circle.centerX = -cObjList->circleObj.circle.centerX; }
+ if(vert) { cObjList->circleObj.circle.centerY = -cObjList->circleObj.circle.centerY; }
+ cObjList = cObjList->next;
+ }
+
+ eObjList = p->ellipseObjList;
+ while(eObjList)
+ {
+ if(horz) { eObjList->ellipseObj.ellipse.centerX = -eObjList->ellipseObj.ellipse.centerX; }
+ if(vert) { eObjList->ellipseObj.ellipse.centerY = -eObjList->ellipseObj.ellipse.centerY; }
+ eObjList = eObjList->next;
+ }
+
+ liObjList = p->lineObjList;
+ while(liObjList)
+ {
+ if(horz)
+ {
+ liObjList->lineObj.line.x1 = -liObjList->lineObj.line.x1;
+ liObjList->lineObj.line.x2 = -liObjList->lineObj.line.x2;
+ }
+ if(vert)
+ {
+ liObjList->lineObj.line.y1 = -liObjList->lineObj.line.y1;
+ liObjList->lineObj.line.y2 = -liObjList->lineObj.line.y2;
+ }
+ liObjList = liObjList->next;
+ }
+
+ paObjList = p->pathObjList;
+ while(paObjList)
+ {
+ paPointList = paObjList->pathObj->pointList;
+ while(paPointList)
+ {
+ if(horz) { paPointList->point.xx = -paPointList->point.xx; }
+ if(vert) { paPointList->point.yy = -paPointList->point.yy; }
+ paPointList = paPointList->next;
+ }
+ paObjList = paObjList->next;
+ }
+
+ pObjList = p->pointObjList;
+ while(pObjList)
+ {
+ if(horz) { pObjList->pointObj.point.xx = -pObjList->pointObj.point.xx; }
+ if(vert) { pObjList->pointObj.point.yy = -pObjList->pointObj.point.yy; }
+ pObjList = pObjList->next;
+ }
+
+ pogObjList = p->polygonObjList;
+ while(pogObjList)
+ {
+ pogPointList = pogObjList->polygonObj->pointList;
+ while(pogPointList)
+ {
+ if(horz) { pogPointList->point.xx = -pogPointList->point.xx; }
+ if(vert) { pogPointList->point.yy = -pogPointList->point.yy; }
+ pogPointList = pogPointList->next;
+ }
+ pogObjList = pogObjList->next;
+ }
+
+ polObjList = p->polylineObjList;
+ while(polObjList)
+ {
+ polPointList = polObjList->polylineObj->pointList;
+ while(polPointList)
+ {
+ if(horz) { polPointList->point.xx = -polPointList->point.xx; }
+ if(vert) { polPointList->point.yy = -polPointList->point.yy; }
+ polPointList = polPointList->next;
+ }
+ polObjList = polObjList->next;
+ }
+
+ rObjList = p->rectObjList;
+ while(rObjList)
+ {
+ if(horz)
+ {
+ rObjList->rectObj.rect.left = -rObjList->rectObj.rect.left;
+ rObjList->rectObj.rect.right = -rObjList->rectObj.rect.right;
+ }
+ if(vert)
+ {
+ rObjList->rectObj.rect.top = -rObjList->rectObj.rect.top;
+ rObjList->rectObj.rect.bottom = -rObjList->rectObj.rect.bottom;
+ }
+ rObjList = rObjList->next;
+ }
+
+ sObjList = p->splineObjList;
+ while(sObjList)
+ {
+ /* TODO: embPattern_flip for splines */
+ sObjList = sObjList->next;
+ }
+}
+
+void embPattern_combineJumpStitches(EmbPattern* p)
+{
+ EmbStitchList* pointer = 0;
+ int jumpCount = 0;
+ EmbStitchList* jumpListStart = 0;
+
+ if(!p) { embLog_error("emb-pattern.c embPattern_combineJumpStitches(), p argument is null\n"); return; }
+ pointer = p->stitchList;
+ while(pointer)
+ {
+ if(pointer->stitch.flags & JUMP)
+ {
+ if(jumpCount == 0)
+ {
+ jumpListStart = pointer;
+ }
+ jumpCount++;
+ }
+ else
+ {
+ if(jumpCount > 0)
+ {
+ EmbStitchList* removePointer = jumpListStart->next;
+ jumpListStart->stitch.xx = pointer->stitch.xx;
+ jumpListStart->stitch.yy = pointer->stitch.yy;
+ jumpListStart->next = pointer;
+
+ for(; jumpCount > 0; jumpCount--)
+ {
+ EmbStitchList* tempPointer = removePointer->next;
+ free(removePointer);
+ removePointer = tempPointer;
+ }
+ jumpCount = 0;
+ }
+ }
+ pointer = pointer->next;
+ }
+}
+
+/*TODO: The params determine the max XY movement rather than the length. They need renamed or clarified further. */
+void embPattern_correctForMaxStitchLength(EmbPattern* p, double maxStitchLength, double maxJumpLength)
+{
+ int j = 0, splits;
+ double maxXY, maxLen, addX, addY;
+
+ if(!p) { embLog_error("emb-pattern.c embPattern_correctForMaxStitchLength(), p argument is null\n"); return; }
+ if(embStitchList_count(p->stitchList) > 1)
+ {
+ EmbStitchList* pointer = 0;
+ EmbStitchList* prev = 0;
+ prev = p->stitchList;
+ pointer = prev->next;
+
+ while(pointer)
+ {
+ double xx = prev->stitch.xx;
+ double yy = prev->stitch.yy;
+ double dx = pointer->stitch.xx - xx;
+ double dy = pointer->stitch.yy - yy;
+ if((fabs(dx) > maxStitchLength) || (fabs(dy) > maxStitchLength))
+ {
+ maxXY = max(fabs(dx), fabs(dy));
+ if(pointer->stitch.flags & (JUMP | TRIM)) maxLen = maxJumpLength;
+ else maxLen = maxStitchLength;
+
+ splits = (int)ceil((double)maxXY / maxLen);
+
+ if(splits > 1)
+ {
+ int flagsToUse = pointer->stitch.flags;
+ int colorToUse = pointer->stitch.color;
+ addX = (double)dx / splits;
+ addY = (double)dy / splits;
+
+ for(j = 1; j < splits; j++)
+ {
+ EmbStitchList* item = 0;
+ EmbStitch s;
+ s.xx = xx + addX * j;
+ s.yy = yy + addY * j;
+ s.flags = flagsToUse;
+ s.color = colorToUse;
+ item = (EmbStitchList*)malloc(sizeof(EmbStitchList));
+ if(!item) { embLog_error("emb-pattern.c embPattern_correctForMaxStitchLength(), cannot allocate memory for item\n"); return; }
+ item->stitch = s;
+ item->next = pointer;
+ prev->next = item;
+ prev = item;
+ }
+ }
+ }
+ prev = pointer;
+ if(pointer)
+ {
+ pointer = pointer->next;
+ }
+ }
+ }
+ if(p->lastStitch && p->lastStitch->stitch.flags != END)
+ {
+ embPattern_addStitchAbs(p, p->lastStitch->stitch.xx, p->lastStitch->stitch.yy, END, 1);
+ }
+}
+
+void embPattern_center(EmbPattern* p)
+{
+ /* TODO: review this. currently not used in anywhere. Also needs to handle various design objects */
+ int moveLeft, moveTop;
+ EmbRect boundingRect;
+ EmbStitchList* pointer = 0;
+
+ if(!p) { embLog_error("emb-pattern.c embPattern_center(), p argument is null\n"); return; }
+ boundingRect = embPattern_calcBoundingBox(p);
+
+ moveLeft = (int)(boundingRect.left - (embRect_width(boundingRect) / 2.0));
+ moveTop = (int)(boundingRect.top - (embRect_height(boundingRect) / 2.0));
+
+ pointer = p->stitchList;
+ while(pointer)
+ {
+ EmbStitch s;
+ s = pointer->stitch;
+ s.xx -= moveLeft;
+ s.yy -= moveTop;
+ }
+}
+
+/*TODO: Description needed. */
+void embPattern_loadExternalColorFile(EmbPattern* p, const char* fileName)
+{
+#ifdef ARDUINO
+ return; /* TODO ARDUINO: This function leaks memory. While it isn't crucial to running the machine, it would be nice use this function, so fix it up. */
+#endif /* ARDUINO */
+
+ char hasRead = 0;
+ EmbReaderWriter* colorFile = 0;
+ const char* dotPos = strrchr(fileName, '.');
+ char* extractName = 0;
+
+ if(!p) { embLog_error("emb-pattern.c embPattern_loadExternalColorFile(), p argument is null\n"); return; }
+ if(!fileName) { embLog_error("emb-pattern.c embPattern_loadExternalColorFile(), fileName argument is null\n"); return; }
+
+ extractName = (char*)malloc(dotPos - fileName + 5);
+ if(!extractName) { embLog_error("emb-pattern.c embPattern_loadExternalColorFile(), cannot allocate memory for extractName\n"); return; }
+ extractName = (char*)memcpy(extractName, fileName, dotPos - fileName);
+ extractName[dotPos - fileName] = '\0';
+ strcat(extractName,".edr");
+ colorFile = embReaderWriter_getByFileName(extractName);
+ if(colorFile)
+ {
+ hasRead = (char)colorFile->reader(p, extractName);
+ }
+ if(!hasRead)
+ {
+ free(colorFile);
+ colorFile = 0;
+ extractName = (char*)memcpy(extractName, fileName, dotPos - fileName);
+ extractName[dotPos - fileName] = '\0';
+ strcat(extractName,".rgb");
+ colorFile = embReaderWriter_getByFileName(extractName);
+ if(colorFile)
+ {
+ hasRead = (char)colorFile->reader(p, extractName);
+ }
+ }
+ if(!hasRead)
+ {
+ free(colorFile);
+ colorFile = 0;
+ extractName = (char*)memcpy(extractName, fileName, dotPos - fileName);
+ extractName[dotPos - fileName] = '\0';
+ strcat(extractName,".col");
+ colorFile = embReaderWriter_getByFileName(extractName);
+ if(colorFile)
+ {
+ hasRead = (char)colorFile->reader(p, extractName);
+ }
+ }
+ if(!hasRead)
+ {
+ free(colorFile);
+ colorFile = 0;
+ extractName = (char*)memcpy(extractName, fileName, dotPos - fileName);
+ extractName[dotPos - fileName] = '\0';
+ strcat(extractName,".inf");
+ colorFile = embReaderWriter_getByFileName(extractName);
+ if(colorFile)
+ {
+ hasRead = (char)colorFile->reader(p, extractName);
+ }
+ }
+ free(colorFile);
+ colorFile = 0;
+ free(extractName);
+ extractName = 0;
+}
+
+/*! Frees all memory allocated in the pattern (\a p). */
+void embPattern_free(EmbPattern* p)
+{
+ if(!p) { embLog_error("emb-pattern.c embPattern_free(), p argument is null\n"); return; }
+ embStitchList_free(p->stitchList); p->stitchList = 0; p->lastStitch = 0;
+ embThreadList_free(p->threadList); p->threadList = 0; p->lastThread = 0;
+
+ embArcObjectList_free(p->arcObjList); p->arcObjList = 0; p->lastArcObj = 0;
+ embCircleObjectList_free(p->circleObjList); p->circleObjList = 0; p->lastCircleObj = 0;
+ embEllipseObjectList_free(p->ellipseObjList); p->ellipseObjList = 0; p->lastEllipseObj = 0;
+ embLineObjectList_free(p->lineObjList); p->lineObjList = 0; p->lastLineObj = 0;
+ embPathObjectList_free(p->pathObjList); p->pathObjList = 0; p->lastPathObj = 0;
+ embPointObjectList_free(p->pointObjList); p->pointObjList = 0; p->lastPointObj = 0;
+ embPolygonObjectList_free(p->polygonObjList); p->polygonObjList = 0; p->lastPolygonObj = 0;
+ embPolylineObjectList_free(p->polylineObjList); p->polylineObjList = 0; p->lastPolylineObj = 0;
+ embRectObjectList_free(p->rectObjList); p->rectObjList = 0; p->lastRectObj = 0;
+ /* embSplineObjectList_free(p->splineObjList); p->splineObjList = 0; p->lastSplineObj = 0; TODO: finish this */
+
+ free(p);
+ p = 0;
+}
+
+/*! Adds a circle object to pattern (\a p) with its center at the absolute position (\a cx,\a cy) with a radius of (\a r). Positive y is up. Units are in millimeters. */
+void embPattern_addCircleObjectAbs(EmbPattern* p, double cx, double cy, double r)
+{
+ EmbCircleObject circleObj = embCircleObject_make(cx, cy, r);
+
+ if(!p) { embLog_error("emb-pattern.c embPattern_addCircleObjectAbs(), p argument is null\n"); return; }
+ if(embCircleObjectList_empty(p->circleObjList))
+ {
+ p->circleObjList = p->lastCircleObj = embCircleObjectList_create(circleObj);
+ }
+ else
+ {
+ p->lastCircleObj = embCircleObjectList_add(p->lastCircleObj, circleObj);
+ }
+}
+
+/*! Adds an ellipse object to pattern (\a p) with its center at the absolute position (\a cx,\a cy) with radii of (\a rx,\a ry). Positive y is up. Units are in millimeters. */
+void embPattern_addEllipseObjectAbs(EmbPattern* p, double cx, double cy, double rx, double ry)
+{
+ EmbEllipseObject ellipseObj = embEllipseObject_make(cx, cy, rx, ry);
+
+ if(!p) { embLog_error("emb-pattern.c embPattern_addEllipseObjectAbs(), p argument is null\n"); return; }
+ if(embEllipseObjectList_empty(p->ellipseObjList))
+ {
+ p->ellipseObjList = p->lastEllipseObj = embEllipseObjectList_create(ellipseObj);
+ }
+ else
+ {
+ p->lastEllipseObj = embEllipseObjectList_add(p->lastEllipseObj, ellipseObj);
+ }
+}
+
+/*! Adds a line object to pattern (\a p) starting at the absolute position (\a x1,\a y1) and ending at the absolute position (\a x2,\a y2). Positive y is up. Units are in millimeters. */
+void embPattern_addLineObjectAbs(EmbPattern* p, double x1, double y1, double x2, double y2)
+{
+ EmbLineObject lineObj = embLineObject_make(x1, y1, x2, y2);
+
+ if(!p) { embLog_error("emb-pattern.c embPattern_addLineObjectAbs(), p argument is null\n"); return; }
+ if(embLineObjectList_empty(p->lineObjList))
+ {
+ p->lineObjList = p->lastLineObj = embLineObjectList_create(lineObj);
+ }
+ else
+ {
+ p->lastLineObj = embLineObjectList_add(p->lastLineObj, lineObj);
+ }
+}
+
+void embPattern_addPathObjectAbs(EmbPattern* p, EmbPathObject* obj)
+{
+ if(!p) { embLog_error("emb-pattern.c embPattern_addPathObjectAbs(), p argument is null\n"); return; }
+ if(!obj) { embLog_error("emb-pattern.c embPattern_addPathObjectAbs(), obj argument is null\n"); return; }
+ if(embPointList_empty(obj->pointList)) { embLog_error("emb-pattern.c embPattern_addPathObjectAbs(), obj->pointList is empty\n"); return; }
+
+ if(embPathObjectList_empty(p->pathObjList))
+ {
+ p->pathObjList = p->lastPathObj = embPathObjectList_create(obj);
+ }
+ else
+ {
+ p->lastPathObj = embPathObjectList_add(p->lastPathObj, obj);
+ }
+}
+
+/*! Adds a point object to pattern (\a p) at the absolute position (\a x,\a y). Positive y is up. Units are in millimeters. */
+void embPattern_addPointObjectAbs(EmbPattern* p, double x, double y)
+{
+ EmbPointObject pointObj = embPointObject_make(x, y);
+
+ if(!p) { embLog_error("emb-pattern.c embPattern_addPointObjectAbs(), p argument is null\n"); return; }
+ if(embPointObjectList_empty(p->pointObjList))
+ {
+ p->pointObjList = p->lastPointObj = embPointObjectList_create(pointObj);
+ }
+ else
+ {
+ p->lastPointObj = embPointObjectList_add(p->lastPointObj, pointObj);
+ }
+}
+
+void embPattern_addPolygonObjectAbs(EmbPattern* p, EmbPolygonObject* obj)
+{
+ if(!p) { embLog_error("emb-pattern.c embPattern_addPolygonObjectAbs(), p argument is null\n"); return; }
+ if(!obj) { embLog_error("emb-pattern.c embPattern_addPolygonObjectAbs(), obj argument is null\n"); return; }
+ if(embPointList_empty(obj->pointList)) { embLog_error("emb-pattern.c embPattern_addPolygonObjectAbs(), obj->pointList is empty\n"); return; }
+
+ if(embPolygonObjectList_empty(p->polygonObjList))
+ {
+ p->polygonObjList = p->lastPolygonObj = embPolygonObjectList_create(obj);
+ }
+ else
+ {
+ p->lastPolygonObj = embPolygonObjectList_add(p->lastPolygonObj, obj);
+ }
+}
+
+void embPattern_addPolylineObjectAbs(EmbPattern* p, EmbPolylineObject* obj)
+{
+ if(!p) { embLog_error("emb-pattern.c embPattern_addPolylineObjectAbs(), p argument is null\n"); return; }
+ if(!obj) { embLog_error("emb-pattern.c embPattern_addPolylineObjectAbs(), obj argument is null\n"); return; }
+ if(embPointList_empty(obj->pointList)) { embLog_error("emb-pattern.c embPattern_addPolylineObjectAbs(), obj->pointList is empty\n"); return; }
+
+ if(embPolylineObjectList_empty(p->polylineObjList))
+ {
+ p->polylineObjList = p->lastPolylineObj = embPolylineObjectList_create(obj);
+ }
+ else
+ {
+ p->lastPolylineObj = embPolylineObjectList_add(p->lastPolylineObj, obj);
+ }
+}
+
+/*! Adds a rectangle object to pattern (\a p) at the absolute position (\a x,\a y) with a width of (\a w) and a height of (\a h). Positive y is up. Units are in millimeters. */
+void embPattern_addRectObjectAbs(EmbPattern* p, double x, double y, double w, double h)
+{
+ EmbRectObject rectObj = embRectObject_make(x, y, w, h);
+
+ if(!p) { embLog_error("emb-pattern.c embPattern_addRectObjectAbs(), p argument is null\n"); return; }
+ if(embRectObjectList_empty(p->rectObjList))
+ {
+ p->rectObjList = p->lastRectObj = embRectObjectList_create(rectObj);
+ }
+ else
+ {
+ p->lastRectObj = embRectObjectList_add(p->lastRectObj, rectObj);
+ }
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-pattern.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-pattern.h
new file mode 100644
index 000000000..993497b93
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-pattern.h
@@ -0,0 +1,104 @@
+/*! @file emb-pattern.h */
+#ifndef EMB_PATTERN_H
+#define EMB_PATTERN_H
+
+#include "emb-arc.h"
+#include "emb-circle.h"
+#include "emb-ellipse.h"
+#include "emb-hoop.h"
+#include "emb-line.h"
+#include "emb-path.h"
+#include "emb-point.h"
+#include "emb-polygon.h"
+#include "emb-polyline.h"
+#include "emb-rect.h"
+#include "emb-settings.h"
+#include "emb-spline.h"
+#include "emb-stitch.h"
+#include "emb-thread.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct EmbPattern_
+{
+ EmbSettings settings;
+ EmbHoop hoop;
+ EmbStitchList* stitchList;
+ EmbThreadList* threadList;
+
+ EmbArcObjectList* arcObjList;
+ EmbCircleObjectList* circleObjList;
+ EmbEllipseObjectList* ellipseObjList;
+ EmbLineObjectList* lineObjList;
+ EmbPathObjectList* pathObjList;
+ EmbPointObjectList* pointObjList;
+ EmbPolygonObjectList* polygonObjList;
+ EmbPolylineObjectList* polylineObjList;
+ EmbRectObjectList* rectObjList;
+ EmbSplineObjectList* splineObjList;
+
+ EmbStitchList* lastStitch;
+ EmbThreadList* lastThread;
+
+ EmbArcObjectList* lastArcObj;
+ EmbCircleObjectList* lastCircleObj;
+ EmbEllipseObjectList* lastEllipseObj;
+ EmbLineObjectList* lastLineObj;
+ EmbPathObjectList* lastPathObj;
+ EmbPointObjectList* lastPointObj;
+ EmbPolygonObjectList* lastPolygonObj;
+ EmbPolylineObjectList* lastPolylineObj;
+ EmbRectObjectList* lastRectObj;
+ EmbSplineObjectList* lastSplineObj;
+
+ int currentColorIndex;
+ double lastX;
+ double lastY;
+} EmbPattern;
+
+extern EMB_PUBLIC EmbPattern* EMB_CALL embPattern_create(void);
+extern EMB_PUBLIC void EMB_CALL embPattern_hideStitchesOverLength(EmbPattern* p, int length);
+extern EMB_PUBLIC void EMB_CALL embPattern_fixColorCount(EmbPattern* p);
+extern EMB_PUBLIC int EMB_CALL embPattern_addThread(EmbPattern* p, EmbThread thread);
+extern EMB_PUBLIC void EMB_CALL embPattern_addStitchAbs(EmbPattern* p, double x, double y, int flags, int isAutoColorIndex);
+extern EMB_PUBLIC void EMB_CALL embPattern_addStitchRel(EmbPattern* p, double dx, double dy, int flags, int isAutoColorIndex);
+extern EMB_PUBLIC void EMB_CALL embPattern_changeColor(EmbPattern* p, int index);
+extern EMB_PUBLIC void EMB_CALL embPattern_free(EmbPattern* p);
+extern EMB_PUBLIC void EMB_CALL embPattern_scale(EmbPattern* p, double scale);
+extern EMB_PUBLIC EmbRect EMB_CALL embPattern_calcBoundingBox(EmbPattern* p);
+extern EMB_PUBLIC void EMB_CALL embPattern_flipHorizontal(EmbPattern* p);
+extern EMB_PUBLIC void EMB_CALL embPattern_flipVertical(EmbPattern* p);
+extern EMB_PUBLIC void EMB_CALL embPattern_flip(EmbPattern* p, int horz, int vert);
+extern EMB_PUBLIC void EMB_CALL embPattern_combineJumpStitches(EmbPattern* p);
+extern EMB_PUBLIC void EMB_CALL embPattern_correctForMaxStitchLength(EmbPattern* p, double maxStitchLength, double maxJumpLength);
+extern EMB_PUBLIC void EMB_CALL embPattern_center(EmbPattern* p);
+extern EMB_PUBLIC void EMB_CALL embPattern_loadExternalColorFile(EmbPattern* p, const char* fileName);
+
+extern EMB_PUBLIC void EMB_CALL embPattern_addCircleObjectAbs(EmbPattern* p, double cx, double cy, double r);
+extern EMB_PUBLIC void EMB_CALL embPattern_addEllipseObjectAbs(EmbPattern* p, double cx, double cy, double rx, double ry); /* TODO: ellipse rotation */
+extern EMB_PUBLIC void EMB_CALL embPattern_addLineObjectAbs(EmbPattern* p, double x1, double y1, double x2, double y2);
+extern EMB_PUBLIC void EMB_CALL embPattern_addPathObjectAbs(EmbPattern* p, EmbPathObject* obj);
+extern EMB_PUBLIC void EMB_CALL embPattern_addPointObjectAbs(EmbPattern* p, double x, double y);
+extern EMB_PUBLIC void EMB_CALL embPattern_addPolygonObjectAbs(EmbPattern* p, EmbPolygonObject* obj);
+extern EMB_PUBLIC void EMB_CALL embPattern_addPolylineObjectAbs(EmbPattern* p, EmbPolylineObject* obj);
+extern EMB_PUBLIC void EMB_CALL embPattern_addRectObjectAbs(EmbPattern* p, double x, double y, double w, double h);
+
+extern EMB_PUBLIC void EMB_CALL embPattern_copyStitchListToPolylines(EmbPattern* pattern);
+extern EMB_PUBLIC void EMB_CALL embPattern_copyPolylinesToStitchList(EmbPattern* pattern);
+extern EMB_PUBLIC void EMB_CALL embPattern_moveStitchListToPolylines(EmbPattern* pattern);
+extern EMB_PUBLIC void EMB_CALL embPattern_movePolylinesToStitchList(EmbPattern* pattern);
+
+extern EMB_PUBLIC int EMB_CALL embPattern_read(EmbPattern* pattern, const char* fileName);
+extern EMB_PUBLIC int EMB_CALL embPattern_write(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_PATTERN_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-point.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-point.c
new file mode 100644
index 000000000..131ebae06
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-point.c
@@ -0,0 +1,166 @@
+#include "emb-point.h"
+#include "emb-logging.h"
+#include <stdlib.h>
+
+/**************************************************/
+/* EmbPoint */
+/**************************************************/
+
+double embPoint_x(EmbPoint point)
+{
+ return point.xx;
+}
+
+double embPoint_y(EmbPoint point)
+{
+ return point.yy;
+}
+
+/* Returns an EmbPointObject. It is created on the stack. */
+EmbPoint embPoint_make(double x, double y)
+{
+ EmbPoint stackPoint;
+ stackPoint.xx = x;
+ stackPoint.yy = y;
+ return stackPoint;
+}
+
+/**************************************************/
+/* EmbPointList */
+/**************************************************/
+
+EmbPointList* embPointList_create(double x, double y)
+{
+ EmbPointList* heapPointList = (EmbPointList*)malloc(sizeof(EmbPointList));
+ if(!heapPointList) { embLog_error("emb-point.c embPointList_create(), cannot allocate memory for heapPointList\n"); return 0; }
+ heapPointList->point.xx = x;
+ heapPointList->point.yy = y;
+ heapPointList->next = 0;
+ return heapPointList;
+}
+
+EmbPointList* embPointList_add(EmbPointList* pointer, EmbPoint data)
+{
+ if(!pointer) { embLog_error("emb-point.c embPointList_add(), pointer argument is null\n"); return 0; }
+ if(pointer->next) { embLog_error("emb-point.c embPointList_add(), pointer->next should be null\n"); return 0; }
+ pointer->next = (EmbPointList*)malloc(sizeof(EmbPointList));
+ if(!pointer->next) { embLog_error("emb-point.c embPointList_add(), cannot allocate memory for pointer->next\n"); return 0; }
+ pointer = pointer->next;
+ pointer->point = data;
+ pointer->next = 0;
+ return pointer;
+}
+
+int embPointList_count(EmbPointList* pointer)
+{
+ int i = 1;
+ if(!pointer) return 0;
+ while(pointer->next)
+ {
+ pointer = pointer->next;
+ i++;
+ }
+ return i;
+}
+
+int embPointList_empty(EmbPointList* pointer)
+{
+ if(!pointer)
+ return 1;
+ return 0;
+}
+
+void embPointList_free(EmbPointList* pointer)
+{
+ EmbPointList* tempPointer = pointer;
+ EmbPointList* nextPointer = 0;
+ while(tempPointer)
+ {
+ nextPointer = tempPointer->next;
+ free(tempPointer);
+ tempPointer = nextPointer;
+ }
+ pointer = 0;
+}
+
+/**************************************************/
+/* EmbPointObject */
+/**************************************************/
+
+/* Returns an EmbPointObject. It is created on the stack. */
+EmbPointObject embPointObject_make(double x, double y)
+{
+ EmbPointObject stackPointObj;
+ stackPointObj.point.xx = x;
+ stackPointObj.point.yy = y;
+ return stackPointObj;
+}
+
+/* Returns a pointer to an EmbPointObject. It is created on the heap. The caller is responsible for freeing the allocated memory. */
+EmbPointObject* embPointObject_create(double x, double y)
+{
+ EmbPointObject* heapPointObj = (EmbPointObject*)malloc(sizeof(EmbPointObject));
+ if(!heapPointObj) { embLog_error("emb-point.c embPointObject_create(), cannot allocate memory for heapPointObj\n"); return 0; }
+ heapPointObj->point.xx = x;
+ heapPointObj->point.yy = y;
+ return heapPointObj;
+}
+
+/**************************************************/
+/* EmbPointObjectList */
+/**************************************************/
+
+EmbPointObjectList* embPointObjectList_create(EmbPointObject data)
+{
+ EmbPointObjectList* heapPointObjList = (EmbPointObjectList*)malloc(sizeof(EmbPointObjectList));
+ if(!heapPointObjList) { embLog_error("emb-point.c embPointObjectList_create(), cannot allocate memory for heapPointObjList\n"); return 0; }
+ heapPointObjList->pointObj = data;
+ heapPointObjList->next = 0;
+ return heapPointObjList;
+}
+
+EmbPointObjectList* embPointObjectList_add(EmbPointObjectList* pointer, EmbPointObject data)
+{
+ if(!pointer) { embLog_error("emb-point.c embPointObjectList_add(), pointer argument is null\n"); return 0; }
+ if(pointer->next) { embLog_error("emb-point.c embPointObjectList_add(), pointer->next should be null\n"); return 0; }
+ pointer->next = (EmbPointObjectList*)malloc(sizeof(EmbPointObjectList));
+ if(!pointer->next) { embLog_error("emb-point.c embPointObjectList_add(), cannot allocate memory for pointer->next\n"); return 0; }
+ pointer = pointer->next;
+ pointer->pointObj = data;
+ pointer->next = 0;
+ return pointer;
+}
+
+int embPointObjectList_count(EmbPointObjectList* pointer)
+{
+ int i = 1;
+ if(!pointer) return 0;
+ while(pointer->next)
+ {
+ pointer = pointer->next;
+ i++;
+ }
+ return i;
+}
+
+int embPointObjectList_empty(EmbPointObjectList* pointer)
+{
+ if(!pointer)
+ return 1;
+ return 0;
+}
+
+void embPointObjectList_free(EmbPointObjectList* pointer)
+{
+ EmbPointObjectList* tempPointer = pointer;
+ EmbPointObjectList* nextPointer = 0;
+ while(tempPointer)
+ {
+ nextPointer = tempPointer->next;
+ free(tempPointer);
+ tempPointer = nextPointer;
+ }
+ pointer = 0;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-point.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-point.h
new file mode 100644
index 000000000..f75d93a76
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-point.h
@@ -0,0 +1,65 @@
+/*! @file emb-point.h */
+#ifndef EMB_POINT_H
+#define EMB_POINT_H
+
+#include "emb-color.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct EmbPoint_
+{
+ double xx; /* absolute position (not relative) */
+ double yy; /* positive is up, units are in mm */
+} EmbPoint;
+
+extern EMB_PUBLIC double EMB_CALL embPoint_x(EmbPoint point);
+extern EMB_PUBLIC double EMB_CALL embPoint_y(EmbPoint point);
+extern EMB_PUBLIC EmbPoint EMB_CALL embPoint_make(double x, double y);
+
+typedef struct EmbPointList_
+{
+ EmbPoint point;
+ struct EmbPointList_* next;
+} EmbPointList;
+
+extern EMB_PUBLIC EmbPointList* EMB_CALL embPointList_create(double x, double y);
+extern EMB_PUBLIC EmbPointList* EMB_CALL embPointList_add(EmbPointList* pointer, EmbPoint data);
+extern EMB_PUBLIC int EMB_CALL embPointList_count(EmbPointList* pointer);
+extern EMB_PUBLIC int EMB_CALL embPointList_empty(EmbPointList* pointer);
+extern EMB_PUBLIC void EMB_CALL embPointList_free(EmbPointList* pointer);
+
+typedef struct EmbPointObject_
+{
+ EmbPoint point;
+
+ /* Properties */
+ int lineType;
+ EmbColor color;
+} EmbPointObject;
+
+extern EMB_PUBLIC EmbPointObject EMB_CALL embPointObject_make(double x, double y);
+extern EMB_PUBLIC EmbPointObject* EMB_CALL embPointObject_create(double x, double y);
+
+typedef struct EmbPointObjectList_
+{
+ EmbPointObject pointObj;
+ struct EmbPointObjectList_* next;
+} EmbPointObjectList;
+
+extern EMB_PUBLIC EmbPointObjectList* EMB_CALL embPointObjectList_create(EmbPointObject data);
+extern EMB_PUBLIC EmbPointObjectList* EMB_CALL embPointObjectList_add(EmbPointObjectList* pointer, EmbPointObject data);
+extern EMB_PUBLIC int EMB_CALL embPointObjectList_count(EmbPointObjectList* pointer);
+extern EMB_PUBLIC int EMB_CALL embPointObjectList_empty(EmbPointObjectList* pointer);
+extern EMB_PUBLIC void EMB_CALL embPointObjectList_free(EmbPointObjectList* pointer);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_POINT_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-polygon.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-polygon.c
new file mode 100644
index 000000000..be656bbd6
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-polygon.c
@@ -0,0 +1,92 @@
+#include "emb-polygon.h"
+#include "emb-logging.h"
+#include <stdlib.h>
+
+/**************************************************/
+/* EmbPolygonObject */
+/**************************************************/
+
+EmbPolygonObject* embPolygonObject_create(EmbPointList* pointList, EmbColor color, int lineType)
+{
+ EmbPolygonObject* heapPolygonObj = 0;
+ if(!pointList) { embLog_error("emb-polygon.c embPolygonObject_create(), pointList argument is null\n"); return 0; }
+ heapPolygonObj = (EmbPolygonObject*)malloc(sizeof(EmbPolygonObject));
+ if(!heapPolygonObj) { embLog_error("emb-polygon.c embPolygonObject_create(), cannot allocate memory for heapPolygonObj\n"); return 0; }
+ heapPolygonObj->pointList = pointList;
+ /* TODO: layer */
+ heapPolygonObj->color = color;
+ heapPolygonObj->lineType = lineType;
+ return heapPolygonObj;
+}
+
+void embPolygonObject_free(EmbPolygonObject* pointer)
+{
+ embPointList_free(pointer->pointList);
+ pointer->pointList = 0;
+ free(pointer);
+ pointer = 0;
+}
+
+/**************************************************/
+/* EmbPolygonObjectList */
+/**************************************************/
+
+EmbPolygonObjectList* embPolygonObjectList_create(EmbPolygonObject* data)
+{
+ EmbPolygonObjectList* heapPolygonObjList = 0;
+ if(!data) { embLog_error("emb-polygon.c embPolygonObjectList_create(), data argument is null\n"); return 0; }
+ heapPolygonObjList = (EmbPolygonObjectList*)malloc(sizeof(EmbPolygonObjectList));
+ if(!heapPolygonObjList) { embLog_error("emb-polygon.c embPolygonObjectList_create(), cannot allocate memory for heapPolygonObjList\n"); return 0; }
+ heapPolygonObjList->polygonObj = data;
+ heapPolygonObjList->next = 0;
+ return heapPolygonObjList;
+}
+
+EmbPolygonObjectList* embPolygonObjectList_add(EmbPolygonObjectList* pointer, EmbPolygonObject* data)
+{
+ if(!pointer) { embLog_error("emb-polygon.c embPolygonObjectList_add(), pointer argument is null\n"); return 0; }
+ if(!data) { embLog_error("emb-polygon.c embPolygonObjectList_add(), data argument is null\n"); return 0; }
+ if(pointer->next) { embLog_error("emb-polygon.c embPolygonObjectList_add(), pointer->next should be null\n"); return 0; }
+ pointer->next = (EmbPolygonObjectList*)malloc(sizeof(EmbPolygonObjectList));
+ if(!pointer->next) { embLog_error("emb-polygon.c embPolygonObjectList_add(), cannot allocate memory for pointer->next\n"); return 0; }
+ pointer = pointer->next;
+ pointer->polygonObj = data;
+ pointer->next = 0;
+ return pointer;
+}
+
+int embPolygonObjectList_count(EmbPolygonObjectList* pointer)
+{
+ int i = 1;
+ if(!pointer) return 0;
+ while(pointer->next)
+ {
+ pointer = pointer->next;
+ i++;
+ }
+ return i;
+}
+
+int embPolygonObjectList_empty(EmbPolygonObjectList* pointer)
+{
+ if(!pointer)
+ return 1;
+ return 0;
+}
+
+void embPolygonObjectList_free(EmbPolygonObjectList* pointer)
+{
+ EmbPolygonObjectList* tempPointer = pointer;
+ EmbPolygonObjectList* nextPointer = 0;
+ while(tempPointer)
+ {
+ nextPointer = tempPointer->next;
+ embPolygonObject_free(tempPointer->polygonObj);
+ tempPointer->polygonObj = 0;
+ free(tempPointer);
+ tempPointer = nextPointer;
+ }
+ pointer = 0;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-polygon.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-polygon.h
new file mode 100644
index 000000000..bba2decd3
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-polygon.h
@@ -0,0 +1,44 @@
+/*! @file emb-polygon.h */
+#ifndef EMB_POLYGON_H
+#define EMB_POLYGON_H
+
+#include "emb-color.h"
+#include "emb-point.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct EmbPolygonObject_
+{
+ EmbPointList* pointList;
+
+ /* Properties */
+ int lineType;
+ EmbColor color;
+} EmbPolygonObject;
+
+extern EMB_PUBLIC EmbPolygonObject* EMB_CALL embPolygonObject_create(EmbPointList* pointList, EmbColor color, int lineType);
+extern EMB_PUBLIC void EMB_CALL embPolygonObject_free(EmbPolygonObject* pointer);
+
+typedef struct EmbPolygonObjectList_
+{
+ EmbPolygonObject* polygonObj;
+ struct EmbPolygonObjectList_* next;
+} EmbPolygonObjectList;
+
+extern EMB_PUBLIC EmbPolygonObjectList* EMB_CALL embPolygonObjectList_create(EmbPolygonObject* data);
+extern EMB_PUBLIC EmbPolygonObjectList* EMB_CALL embPolygonObjectList_add(EmbPolygonObjectList* pointer, EmbPolygonObject* data);
+extern EMB_PUBLIC int EMB_CALL embPolygonObjectList_count(EmbPolygonObjectList* pointer);
+extern EMB_PUBLIC int EMB_CALL embPolygonObjectList_empty(EmbPolygonObjectList* pointer);
+extern EMB_PUBLIC void EMB_CALL embPolygonObjectList_free(EmbPolygonObjectList* pointer);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_POLYGON_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-polyline.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-polyline.c
new file mode 100644
index 000000000..30b9d6403
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-polyline.c
@@ -0,0 +1,92 @@
+#include "emb-polyline.h"
+#include "emb-logging.h"
+#include <stdlib.h>
+
+/**************************************************/
+/* EmbPolylineObject */
+/**************************************************/
+
+EmbPolylineObject* embPolylineObject_create(EmbPointList* pointList, EmbColor color, int lineType)
+{
+ EmbPolylineObject* heapPolylineObj = 0;
+ if(!pointList) { embLog_error("emb-polyline.c embPolylineObject_create(), pointList argument is null\n"); return 0; }
+ heapPolylineObj = (EmbPolylineObject*)malloc(sizeof(EmbPolylineObject));
+ if(!heapPolylineObj) { embLog_error("emb-polyline.c embPolylineObject_create(), cannot allocate memory for heapPolylineObj\n"); return 0; }
+ heapPolylineObj->pointList = pointList;
+ /* TODO: layer */
+ heapPolylineObj->color = color;
+ heapPolylineObj->lineType = lineType;
+ return heapPolylineObj;
+}
+
+void embPolylineObject_free(EmbPolylineObject* pointer)
+{
+ embPointList_free(pointer->pointList);
+ pointer->pointList = 0;
+ free(pointer);
+ pointer = 0;
+}
+
+/**************************************************/
+/* EmbPolylineObjectList */
+/**************************************************/
+
+EmbPolylineObjectList* embPolylineObjectList_create(EmbPolylineObject* data)
+{
+ EmbPolylineObjectList* heapPolylineObjList = 0;
+ if(!data) { embLog_error("emb-polyline.c embPolylineObjectList_create(), data argument is null\n"); return 0; }
+ heapPolylineObjList = (EmbPolylineObjectList*)malloc(sizeof(EmbPolylineObjectList));
+ if(!heapPolylineObjList) { embLog_error("emb-polyline.c embPolylineObjectList_create(), cannot allocate memory for heapPolylineObjList\n"); return 0; }
+ heapPolylineObjList->polylineObj = data;
+ heapPolylineObjList->next = 0;
+ return heapPolylineObjList;
+}
+
+EmbPolylineObjectList* embPolylineObjectList_add(EmbPolylineObjectList* pointer, EmbPolylineObject* data)
+{
+ if(!pointer) { embLog_error("emb-polyline.c embPolylineObjectList_add(), pointer argument is null\n"); return 0; }
+ if(!data) { embLog_error("emb-polyline.c embPolylineObjectList_add(), data argument is null\n"); return 0; }
+ if(pointer->next) { embLog_error("emb-polyline.c embPolylineObjectList_add(), pointer->next should be null\n"); return 0; }
+ pointer->next = (EmbPolylineObjectList*)malloc(sizeof(EmbPolylineObjectList));
+ if(!pointer->next) { embLog_error("emb-polyline.c embPolylineObjectList_add(), cannot allocate memory for pointer->next\n"); return 0; }
+ pointer = pointer->next;
+ pointer->polylineObj = data;
+ pointer->next = 0;
+ return pointer;
+}
+
+int embPolylineObjectList_count(EmbPolylineObjectList* pointer)
+{
+ int i = 1;
+ if(!pointer) return 0;
+ while(pointer->next)
+ {
+ pointer = pointer->next;
+ i++;
+ }
+ return i;
+}
+
+int embPolylineObjectList_empty(EmbPolylineObjectList* pointer)
+{
+ if(!pointer)
+ return 1;
+ return 0;
+}
+
+void embPolylineObjectList_free(EmbPolylineObjectList* pointer)
+{
+ EmbPolylineObjectList* tempPointer = pointer;
+ EmbPolylineObjectList* nextPointer = 0;
+ while(tempPointer)
+ {
+ nextPointer = tempPointer->next;
+ embPolylineObject_free(tempPointer->polylineObj);
+ tempPointer->polylineObj = 0;
+ free(tempPointer);
+ tempPointer = nextPointer;
+ }
+ pointer = 0;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-polyline.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-polyline.h
new file mode 100644
index 000000000..45a73d616
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-polyline.h
@@ -0,0 +1,44 @@
+/*! @file emb-polyline.h */
+#ifndef EMB_POLYLINE_H
+#define EMB_POLYLINE_H
+
+#include "emb-color.h"
+#include "emb-point.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct EmbPolylineObject_
+{
+ EmbPointList* pointList;
+
+ /* Properties */
+ int lineType;
+ EmbColor color;
+} EmbPolylineObject;
+
+extern EMB_PUBLIC EmbPolylineObject* EMB_CALL embPolylineObject_create(EmbPointList* pointList, EmbColor color, int lineType);
+extern EMB_PUBLIC void EMB_CALL embPolylineObject_free(EmbPolylineObject* pointer);
+
+typedef struct EmbPolylineObjectList_
+{
+ EmbPolylineObject* polylineObj;
+ struct EmbPolylineObjectList_* next;
+} EmbPolylineObjectList;
+
+extern EMB_PUBLIC EmbPolylineObjectList* EMB_CALL embPolylineObjectList_create(EmbPolylineObject* data);
+extern EMB_PUBLIC EmbPolylineObjectList* EMB_CALL embPolylineObjectList_add(EmbPolylineObjectList* pointer, EmbPolylineObject* data);
+extern EMB_PUBLIC int EMB_CALL embPolylineObjectList_count(EmbPolylineObjectList* pointer);
+extern EMB_PUBLIC int EMB_CALL embPolylineObjectList_empty(EmbPolylineObjectList* pointer);
+extern EMB_PUBLIC void EMB_CALL embPolylineObjectList_free(EmbPolylineObjectList* pointer);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_POLYLINE_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-reader-writer.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-reader-writer.c
new file mode 100644
index 000000000..499e7670f
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-reader-writer.c
@@ -0,0 +1,582 @@
+#include "emb-reader-writer.h"
+#include "emb-logging.h"
+#include "formats.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+/*! Returns a pointer to an EmbReaderWriter if the \a fileName is a supported file type. */
+EmbReaderWriter* embReaderWriter_getByFileName(const char* fileName)
+{
+ int i = 0;
+ char ending[5];
+ EmbReaderWriter* rw = 0;
+
+ if(!fileName) { embLog_error("emb-reader-writer.c embReaderWriter_getByFileName(), fileName argument is null\n"); return 0; }
+
+ if(strlen(fileName) == 0) return 0;
+ strcpy(ending, strrchr(fileName, '.'));
+
+ while(ending[i] != '\0')
+ {
+ ending[i] = (char)tolower(ending[i]);
+ ++i;
+ }
+ rw = (EmbReaderWriter*)malloc(sizeof(EmbReaderWriter));
+ if(!rw) { embLog_error("emb-reader-writer.c embReaderWriter_getByFileName(), cannot allocate memory for rw\n"); return 0; }
+
+ if(!strcmp(ending, ".10o"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = read10o;
+ rw->writer = write10o;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".100"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = read100;
+ rw->writer = write100;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".art"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readArt;
+ rw->writer = writeArt;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".bmc"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readBmc;
+ rw->writer = writeBmc;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".bro"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readBro;
+ rw->writer = writeBro;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".cnd"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readCnd;
+ rw->writer = writeCnd;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".col"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readCol;
+ rw->writer = writeCol;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".csd"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readCsd;
+ rw->writer = writeCsd;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".csv"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readCsv;
+ rw->writer = writeCsv;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".dat"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readDat;
+ rw->writer = writeDat;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".dem"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readDem;
+ rw->writer = writeDem;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".dsb"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readDsb;
+ rw->writer = writeDsb;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".dst"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readDst;
+ rw->writer = writeDst;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".dsz"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readDsz;
+ rw->writer = writeDsz;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".dxf"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readDxf;
+ rw->writer = writeDxf;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".edr"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readEdr;
+ rw->writer = writeEdr;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".emd"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readEmd;
+ rw->writer = writeEmd;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".exp"))
+ {
+ rw->reader = readExp;
+ rw->writer = writeExp;
+ }
+ else if(!strcmp(ending, ".exy"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readExy;
+ rw->writer = writeExy;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".eys"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readEys;
+ rw->writer = writeEys;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".fxy"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readFxy;
+ rw->writer = writeFxy;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".gc"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readGc;
+ rw->writer = writeGc;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".gnc"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readGnc;
+ rw->writer = writeGnc;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".gt"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readGt;
+ rw->writer = writeGt;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".hus"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readHus;
+ rw->writer = writeHus;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".inb"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readInb;
+ rw->writer = writeInb;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".inf"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readInf;
+ rw->writer = writeInf;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".jef"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readJef;
+ rw->writer = writeJef;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".ksm"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readKsm;
+ rw->writer = writeKsm;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".max"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readMax;
+ rw->writer = writeMax;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".mit"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readMit;
+ rw->writer = writeMit;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".new"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readNew;
+ rw->writer = writeNew;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".ofm"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readOfm;
+ rw->writer = writeOfm;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".pcd"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readPcd;
+ rw->writer = writePcd;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".pcm"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readPcm;
+ rw->writer = writePcm;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".pcq"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readPcq;
+ rw->writer = writePcq;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".pcs"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readPcs;
+ rw->writer = writePcs;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".pec"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readPec;
+ rw->writer = writePec;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".pel"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readPel;
+ rw->writer = writePel;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".pem"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readPem;
+ rw->writer = writePem;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".pes"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readPes;
+ rw->writer = writePes;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".phb"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readPhb;
+ rw->writer = writePhb;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".phc"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readPhc;
+ rw->writer = writePhc;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".plt"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readPlt;
+ rw->writer = writePlt;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".rgb"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readRgb;
+ rw->writer = writeRgb;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".sew"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readSew;
+ rw->writer = writeSew;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".shv"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readShv;
+ rw->writer = writeShv;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".sst"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readSst;
+ rw->writer = writeSst;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".stx"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readStx;
+ rw->writer = writeStx;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".svg"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readSvg;
+ rw->writer = writeSvg;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".t01"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readT01;
+ rw->writer = writeT01;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".t09"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readT09;
+ rw->writer = writeT09;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".tap"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readTap;
+ rw->writer = writeTap;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".thr"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readThr;
+ rw->writer = writeThr;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".txt"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readTxt;
+ rw->writer = writeTxt;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".u00"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readU00;
+ rw->writer = writeU00;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".u01"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readU01;
+ rw->writer = writeU01;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".vip"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readVip;
+ rw->writer = writeVip;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".vp3"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readVp3;
+ rw->writer = writeVp3;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".xxx"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readXxx;
+ rw->writer = writeXxx;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else if(!strcmp(ending, ".zsk"))
+ {
+ #ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+ return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+ #else /* ARDUINO TODO: This is temporary. Remove when complete. */
+ rw->reader = readZsk;
+ rw->writer = writeZsk;
+ #endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+ }
+ else
+ {
+ embLog_error("emb-reader-writer.c embReaderWriter_getByFileName(), unsupported file type: %s\n", ending);
+ return 0;
+ }
+ return rw;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-reader-writer.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-reader-writer.h
new file mode 100644
index 000000000..029809be0
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-reader-writer.h
@@ -0,0 +1,27 @@
+/*! @file emb-reader-writer.h */
+#ifndef EMB_READER_WRITER_H
+#define EMB_READER_WRITER_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct EmbReaderWriter_
+{
+ int (*reader)(EmbPattern*, const char*);
+ int (*writer)(EmbPattern*, const char*);
+} EmbReaderWriter;
+
+extern EMB_PUBLIC EmbReaderWriter* EMB_CALL embReaderWriter_getByFileName(const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_READER_WRITER_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-rect.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-rect.c
new file mode 100644
index 000000000..5d55aa3af
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-rect.c
@@ -0,0 +1,153 @@
+#include "emb-rect.h"
+#include "emb-logging.h"
+#include <stdlib.h>
+
+/**************************************************/
+/* EmbRect */
+/**************************************************/
+
+double embRect_x(EmbRect rect)
+{
+ return rect.left;
+}
+
+double embRect_y(EmbRect rect)
+{
+ return rect.top;
+}
+
+double embRect_width(EmbRect rect)
+{
+ return rect.right - rect.left;
+}
+
+double embRect_height(EmbRect rect)
+{
+ return rect.bottom - rect.top;
+}
+
+/* Sets the left edge of the rect to x. The right edge is not modified. */
+void embRect_setX(EmbRect* rect, double x)
+{
+ rect->left = x;
+}
+
+/* Sets the top edge of the rect to y. The bottom edge is not modified. */
+void embRect_setY(EmbRect* rect, double y)
+{
+ rect->top = y;
+}
+
+/* Sets the width of the rect to w. The right edge is modified. The left edge is not modified. */
+void embRect_setWidth(EmbRect* rect, double w)
+{
+ rect->right = rect->left + w;
+}
+
+/* Sets the height of the rect to h. The bottom edge is modified. The top edge is not modified. */
+void embRect_setHeight(EmbRect* rect, double h)
+{
+ rect->bottom = rect->top + h;
+}
+
+void embRect_setCoords(EmbRect* rect, double x1, double y1, double x2, double y2)
+{
+ rect->left = x1;
+ rect->top = y1;
+ rect->right = x2;
+ rect->bottom = y2;
+}
+
+void embRect_setRect(EmbRect* rect, double x, double y, double w, double h)
+{
+ rect->left = x;
+ rect->top = y;
+ rect->right = x + w;
+ rect->bottom = y + h;
+}
+
+/**************************************************/
+/* EmbRectObject */
+/**************************************************/
+
+/* Returns an EmbRectObject. It is created on the stack. */
+EmbRectObject embRectObject_make(double x, double y, double w, double h)
+{
+ EmbRectObject stackRectObj;
+ stackRectObj.rect.left = x;
+ stackRectObj.rect.top = y;
+ stackRectObj.rect.right = x + w;
+ stackRectObj.rect.bottom = y + h;
+ return stackRectObj;
+}
+
+/* Returns a pointer to an EmbRectObject. It is created on the heap. The caller is responsible for freeing the allocated memory. */
+EmbRectObject* embRectObject_create(double x, double y, double w, double h)
+{
+ EmbRectObject* heapRectObj = (EmbRectObject*)malloc(sizeof(EmbRectObject));
+ if(!heapRectObj) { embLog_error("emb-rect.c embRectObject_create(), cannot allocate memory for heapRectObj\n"); return 0; }
+ heapRectObj->rect.left = x;
+ heapRectObj->rect.top = y;
+ heapRectObj->rect.right = x + w;
+ heapRectObj->rect.bottom = y + h;
+ return heapRectObj;
+}
+
+/**************************************************/
+/* EmbRectObjectList */
+/**************************************************/
+
+EmbRectObjectList* embRectObjectList_create(EmbRectObject data)
+{
+ EmbRectObjectList* heapRectObjList = (EmbRectObjectList*)malloc(sizeof(EmbRectObjectList));
+ if(!heapRectObjList) { embLog_error("emb-rect.c embRectObjectList_create(), cannot allocate memory for heapRectObjList\n"); return 0; }
+ heapRectObjList->rectObj = data;
+ heapRectObjList->next = 0;
+ return heapRectObjList;
+}
+
+EmbRectObjectList* embRectObjectList_add(EmbRectObjectList* pointer, EmbRectObject data)
+{
+ if(!pointer) { embLog_error("emb-rect.c embRectObjectList_add(), pointer argument is null\n"); return 0; }
+ if(pointer->next) { embLog_error("emb-rect.c embRectObjectList_add(), pointer->next should be null\n"); return 0; }
+ pointer->next = (EmbRectObjectList*)malloc(sizeof(EmbRectObjectList));
+ if(!pointer->next) { embLog_error("emb-rect.c embRectObjectList_add(), cannot allocate memory for pointer->next\n"); return 0; }
+ pointer = pointer->next;
+ pointer->rectObj = data;
+ pointer->next = 0;
+ return pointer;
+}
+
+int embRectObjectList_count(EmbRectObjectList* pointer)
+{
+ int i = 1;
+ if(!pointer) return 0;
+ while(pointer->next)
+ {
+ pointer = pointer->next;
+ i++;
+ }
+ return i;
+}
+
+int embRectObjectList_empty(EmbRectObjectList* pointer)
+{
+ if(!pointer)
+ return 1;
+ return 0;
+}
+
+void embRectObjectList_free(EmbRectObjectList* pointer)
+{
+ EmbRectObjectList* tempPointer = pointer;
+ EmbRectObjectList* nextPointer = 0;
+ while(tempPointer)
+ {
+ nextPointer = tempPointer->next;
+ free(tempPointer);
+ tempPointer = nextPointer;
+ }
+ pointer = 0;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-rect.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-rect.h
new file mode 100644
index 000000000..5afee4c73
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-rect.h
@@ -0,0 +1,66 @@
+/*! @file emb-rect.h */
+#ifndef EMB_RECT_H
+#define EMB_RECT_H
+
+#include "emb-color.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct EmbRect_
+{
+ double top;
+ double left;
+ double bottom;
+ double right;
+} EmbRect;
+
+extern EMB_PUBLIC double EMB_CALL embRect_x(EmbRect rect);
+extern EMB_PUBLIC double EMB_CALL embRect_y(EmbRect rect);
+extern EMB_PUBLIC double EMB_CALL embRect_width(EmbRect rect);
+extern EMB_PUBLIC double EMB_CALL embRect_height(EmbRect rect);
+
+extern EMB_PUBLIC void EMB_CALL embRect_setX(EmbRect* rect, double x);
+extern EMB_PUBLIC void EMB_CALL embRect_setY(EmbRect* rect, double y);
+extern EMB_PUBLIC void EMB_CALL embRect_setWidth(EmbRect* rect, double w);
+extern EMB_PUBLIC void EMB_CALL embRect_setHeight(EmbRect* rect, double h);
+
+extern EMB_PUBLIC void EMB_CALL embRect_setCoords(EmbRect* rect, double x1, double y1, double x2, double y2);
+extern EMB_PUBLIC void EMB_CALL embRect_setRect(EmbRect* rect, double x, double y, double w, double h);
+
+typedef struct EmbRectObject_
+{
+ EmbRect rect;
+ double rotation;
+ double radius;
+
+ /* Properties */
+ int lineType;
+ EmbColor color;
+} EmbRectObject;
+
+extern EMB_PUBLIC EmbRectObject EMB_CALL embRectObject_make(double x, double y, double w, double h);
+extern EMB_PUBLIC EmbRectObject* EMB_CALL embRectObject_create(double x, double y, double w, double h);
+
+typedef struct EmbRectObjectList_
+{
+ EmbRectObject rectObj;
+ struct EmbRectObjectList_* next;
+} EmbRectObjectList;
+
+extern EMB_PUBLIC EmbRectObjectList* EMB_CALL embRectObjectList_create(EmbRectObject data);
+extern EMB_PUBLIC EmbRectObjectList* EMB_CALL embRectObjectList_add(EmbRectObjectList* pointer, EmbRectObject data);
+extern EMB_PUBLIC int EMB_CALL embRectObjectList_count(EmbRectObjectList* pointer);
+extern EMB_PUBLIC int EMB_CALL embRectObjectList_empty(EmbRectObjectList* pointer);
+extern EMB_PUBLIC void EMB_CALL embRectObjectList_free(EmbRectObjectList* pointer);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_RECT_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-satin-line.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-satin-line.c
new file mode 100644
index 000000000..4d61972cf
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-satin-line.c
@@ -0,0 +1,139 @@
+#include "emb-satin-line.h"
+#include "emb-line.h"
+#include "emb-logging.h"
+#include "emb-vector.h"
+#include <math.h>
+#include <stdlib.h>
+
+void embSatinOutline_generateSatinOutline(EmbVector lines[], int numberOfPoints, double thickness, EmbSatinOutline* result)
+{
+ int i;
+ EmbSatinOutline outline;
+ double halfThickness = thickness / 2.0;
+ int intermediateOutlineCount = 2 * numberOfPoints - 2;
+ outline.side1 = (EmbVector*)malloc(sizeof(EmbVector) * intermediateOutlineCount);
+ if(!outline.side1) { embLog_error("emb-satin-line.c embSatinOutline_generateSatinOutline(), cannot allocate memory for outline->side1\n"); return; }
+ outline.side2 = (EmbVector*)malloc(sizeof(EmbVector) * intermediateOutlineCount);
+ if(!outline.side2) { embLog_error("emb-satin-line.c embSatinOutline_generateSatinOutline(), cannot allocate memory for outline->side2\n"); return; }
+
+ for(i = 1; i < numberOfPoints; i++)
+ {
+ int j = (i - 1) * 2;
+ EmbVector v1;
+ EmbVector temp;
+
+ embLine_normalVector(lines[i - 1], lines[i], &v1, 1);
+
+ embVector_multiply(v1, halfThickness, &temp);
+ embVector_add(temp, lines[i - 1], &outline.side1[j]);
+ embVector_add(temp, lines[i], &outline.side1[j + 1]);
+
+ embVector_multiply(v1, -halfThickness, &temp);
+ embVector_add(temp, lines[i - 1], &outline.side2[j]);
+ embVector_add(temp, lines[i], &outline.side2[j + 1]);
+ }
+
+ if(!result) { embLog_error("emb-satin-line.c embSatinOutline_generateSatinOutline(), result argument is null\n"); return; }
+ result->side1 = (EmbVector*)malloc(sizeof(EmbVector) * numberOfPoints);
+ if(!result->side1) { embLog_error("emb-satin-line.c embSatinOutline_generateSatinOutline(), cannot allocate memory for result->side1\n"); return; }
+ result->side2 = (EmbVector*)malloc(sizeof(EmbVector) * numberOfPoints);
+ if(!result->side2) { embLog_error("emb-satin-line.c embSatinOutline_generateSatinOutline(), cannot allocate memory for result->side2\n"); return; }
+
+ result->side1[0] = outline.side1[0];
+ result->side2[0] = outline.side2[0];
+
+ for(i = 3; i < intermediateOutlineCount; i += 2)
+ {
+ embLine_intersectionPoint(outline.side1[i - 3], outline.side1[i - 2], outline.side1[i - 1], outline.side1[i], &result->side1[(i - 1) / 2]);
+ }
+
+ for(i = 3; i < intermediateOutlineCount; i += 2)
+ {
+ embLine_intersectionPoint(outline.side2[i - 3], outline.side2[i - 2], outline.side2[i - 1], outline.side2[i], &result->side2[(i - 1) / 2]);
+ }
+
+ result->side1[numberOfPoints - 1] = outline.side1[2 * numberOfPoints - 3];
+ result->side2[numberOfPoints - 1] = outline.side2[2 * numberOfPoints - 3];
+ result->length = numberOfPoints;
+}
+
+EmbVectorList* embSatinOutline_renderStitches(EmbSatinOutline* result, double density)
+{
+ int i, j;
+ EmbVectorList* stitches = 0;
+ EmbVectorList* currentStitch = 0;
+ EmbVector temp;
+
+ if(!result) { embLog_error("emb-satin-line.c embSatinOutline_renderStitches(), result argument is null\n"); return 0; }
+
+ if(result->length > 0)
+ {
+ double currTopX = 0;
+ double currTopY = 0;
+ double currBottomX = 0;
+ double currBottomY = 0;
+
+ for(j = 0; j < result->length - 1; j++)
+ {
+ EmbVector p1 = result->side1[j];
+ EmbVector p2 = result->side1[j + 1];
+ EmbVector p3 = result->side2[j];
+ EmbVector p4 = result->side2[j + 1];
+
+ double topXDiff = p2.X - p1.X;
+ double topYDiff = p2.Y - p1.Y;
+ double bottomXDiff = p4.X - p3.X;
+ double bottomYDiff = p4.Y - p3.Y;
+
+ double midLeftX = (p1.X + p3.X) / 2;
+ double midLeftY = (p1.Y + p3.Y) / 2;
+ double midRightX = (p2.X + p4.X) / 2;
+ double midRightY = (p2.Y + p4.Y) / 2;
+
+ double midXDiff = midLeftX - midRightX;
+ double midYDiff = midLeftY - midRightY;
+ double midLength = sqrt(midXDiff * midXDiff + midYDiff * midYDiff);
+
+ int numberOfSteps = (int)(midLength * density / 200);
+ double topStepX = topXDiff / numberOfSteps;
+ double topStepY = topYDiff / numberOfSteps;
+ double bottomStepX = bottomXDiff / numberOfSteps;
+ double bottomStepY = bottomYDiff / numberOfSteps;
+ currTopX = p1.X;
+ currTopY = p1.Y;
+ currBottomX = p3.X;
+ currBottomY = p3.Y;
+
+ for(i = 0; i < numberOfSteps; i++)
+ {
+ EmbVector temp2;
+ temp.X= currTopX;
+ temp.Y = currTopY;
+ if(stitches)
+ {
+ currentStitch = embVectorList_add(currentStitch, temp);
+ }
+ else
+ {
+ stitches = currentStitch = embVectorList_create(temp);
+ }
+ temp2.X = currBottomX;
+ temp2.Y = currBottomY;
+ currentStitch = embVectorList_add(currentStitch, temp2);
+ currTopX += topStepX;
+ currTopY += topStepY;
+ currBottomX += bottomStepX;
+ currBottomY += bottomStepY;
+ }
+ }
+ temp.X = currTopX;
+ temp.Y = currTopY;
+ currentStitch = embVectorList_add(currentStitch, temp);
+ temp.X = currBottomX;
+ temp.Y = currBottomY;
+ currentStitch = embVectorList_add(currentStitch, temp);
+ }
+ return stitches;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-satin-line.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-satin-line.h
new file mode 100644
index 000000000..9fbe2a0cf
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-satin-line.h
@@ -0,0 +1,29 @@
+/*! @file emb-satin-line.h */
+#ifndef EMB_SATINLINE_H
+#define EMB_SATINLINE_H
+
+#include "emb-vector.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct EmbSatinOutline_
+{
+ int length;
+ EmbVector* side1;
+ EmbVector* side2;
+} EmbSatinOutline;
+
+extern EMB_PUBLIC void EMB_CALL embSatinOutline_generateSatinOutline(EmbVector lines[], int numberOfPoints, double thickness, EmbSatinOutline* result);
+extern EMB_PUBLIC EmbVectorList* EMB_CALL embSatinOutline_renderStitches(EmbSatinOutline* result, double density);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_SATINLINE_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-settings.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-settings.c
new file mode 100644
index 000000000..a7a7939d4
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-settings.c
@@ -0,0 +1,24 @@
+#include "emb-settings.h"
+
+/*! Initializes and returns an EmbSettings */
+EmbSettings embSettings_init(void)
+{
+ EmbSettings settings;
+ settings.dstJumpsPerTrim = 6;
+ settings.home = embPoint_make(0.0, 0.0);
+ return settings;
+}
+
+/*! Returns the home position stored in (\a settings) as an EmbPoint (\a point). */
+EmbPoint embSettings_home(EmbSettings* settings)
+{
+ return settings->home;
+}
+
+/*! Sets the home position stored in (\a settings) to EmbPoint (\a point). You will rarely ever need to use this. */
+void embSettings_setHome(EmbSettings* settings, EmbPoint point)
+{
+ settings->home = point;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-settings.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-settings.h
new file mode 100644
index 000000000..15c709710
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-settings.h
@@ -0,0 +1,30 @@
+/*! @file emb-settings.h */
+#ifndef EMB_SETTINGS_H
+#define EMB_SETTINGS_H
+
+#include "emb-point.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct EmbSettings_
+{
+ unsigned int dstJumpsPerTrim;
+ EmbPoint home;
+} EmbSettings;
+
+extern EMB_PUBLIC EmbSettings EMB_CALL embSettings_init(void);
+
+extern EMB_PUBLIC EmbPoint EMB_CALL embSettings_home(EmbSettings* settings);
+extern EMB_PUBLIC void EMB_CALL embSettings_setHome(EmbSettings* settings, EmbPoint point);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_SETTINGS_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-spline.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-spline.c
new file mode 100644
index 000000000..d84a035fb
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-spline.c
@@ -0,0 +1,22 @@
+#include "emb-spline.h"
+
+int embSplineObjectList_count(EmbSplineObjectList* pointer)
+{
+ int i = 1;
+ if(!pointer) return 0;
+ while(pointer->next)
+ {
+ pointer = pointer->next;
+ i++;
+ }
+ return i;
+}
+
+int embSplineObjectList_empty(EmbSplineObjectList* pointer)
+{
+ if(!pointer)
+ return 1;
+ return 0;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-spline.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-spline.h
new file mode 100644
index 000000000..ee9e9d2a9
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-spline.h
@@ -0,0 +1,51 @@
+/*! @file emb-spline.h */
+#ifndef EMB_SPLINE_H
+#define EMB_SPLINE_H
+
+#include "emb-color.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct EmbBezier_
+{
+ double startX;
+ double startY;
+ double control1X;
+ double control1Y;
+ double control2X;
+ double control2Y;
+ double endX;
+ double endY;
+} EmbBezier;
+
+typedef struct EmbSplineObject_
+{
+ EmbBezier bezier;
+ struct EmbSplineObject_* next;
+
+ /* Properties */
+ int lineType;
+ EmbColor color;
+} EmbSplineObject;
+
+/* A list of bezier curves is a B-spline */
+typedef struct EmbSplineObjectList_
+{
+ EmbSplineObject splineObj;
+ struct EmbSplineObjectList_* next;
+} EmbSplineObjectList; /* TODO: This struct/file needs reworked to work internally similar to polylines */
+
+extern EMB_PUBLIC int EMB_CALL embSplineObjectList_count(EmbSplineObjectList* pointer);
+extern EMB_PUBLIC int EMB_CALL embSplineObjectList_empty(EmbSplineObjectList* pointer);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_SPLINE_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-stitch.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-stitch.c
new file mode 100644
index 000000000..c791ddf67
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-stitch.c
@@ -0,0 +1,71 @@
+#include "emb-stitch.h"
+#include "emb-logging.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+EmbStitchList* embStitchList_create(EmbStitch data)
+{
+ EmbStitchList* heapStitchList = (EmbStitchList*)malloc(sizeof(EmbStitchList));
+ if(!heapStitchList) { embLog_error("emb-stitch.c embStitchList_create(), cannot allocate memory for heapStitchList\n"); return 0; }
+ heapStitchList->stitch = data;
+ heapStitchList->next = 0;
+ return heapStitchList;
+}
+
+EmbStitchList* embStitchList_add(EmbStitchList* pointer, EmbStitch data)
+{
+ if(!pointer) { embLog_error("emb-stitch.c embStitchList_add(), pointer argument is null\n"); return 0; }
+ if(pointer->next) { embLog_error("emb-stitch.c embStitchList_add(), pointer->next should be null\n"); return 0; }
+ pointer->next = (EmbStitchList*)malloc(sizeof(EmbStitchList));
+ if(!pointer->next) { embLog_error("emb-stitch.c embStitchList_add(), cannot allocate memory for pointer->next\n"); return 0; }
+ pointer = pointer->next;
+ pointer->stitch = data;
+ pointer->next = 0;
+ return pointer;
+}
+
+EmbStitch embStitchList_getAt(EmbStitchList* pointer, int num)
+{
+ /* TODO: pointer safety */
+ int i;
+ for(i = 0; i < num; i++)
+ {
+ pointer = pointer->next;
+ }
+ return pointer->stitch;
+}
+
+/* TODO: Add a default parameter to handle returning count based on stitch flags. Currently, it includes JUMP and TRIM stitches, maybe we just want NORMAL stitches only or vice versa */
+int embStitchList_count(EmbStitchList* pointer)
+{
+ int i = 1;
+ if(!pointer) return 0;
+ while(pointer->next)
+ {
+ pointer = pointer->next;
+ i++;
+ }
+ return i;
+}
+
+int embStitchList_empty(EmbStitchList* pointer)
+{
+ if(!pointer)
+ return 1;
+ return 0;
+}
+
+void embStitchList_free(EmbStitchList* pointer)
+{
+ EmbStitchList* tempPointer = pointer;
+ EmbStitchList* nextPointer = 0;
+ while(tempPointer)
+ {
+ nextPointer = tempPointer->next;
+ free(tempPointer);
+ tempPointer = nextPointer;
+ }
+ pointer = 0;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-stitch.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-stitch.h
new file mode 100644
index 000000000..595363b73
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-stitch.h
@@ -0,0 +1,46 @@
+/*! @file emb-stitch.h */
+#ifndef EMB_STITCH_H
+#define EMB_STITCH_H
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Machine codes for stitch flags */
+#define NORMAL 0 /* stitch to (xx, yy) */
+#define JUMP 1 /* move to(xx, yy) */
+#define TRIM 2 /* trim + move to(xx, yy) */
+#define STOP 4 /* pause machine for thread change */
+#define SEQUIN 8 /* sequin */
+#define END 16 /* end of program */
+
+typedef struct EmbStitch_
+{
+ int flags; /* uses codes defined above */
+ double xx; /* absolute position (not relative) */
+ double yy; /* positive is up, units are in mm */
+ int color; /* color number for this stitch */ /* TODO: this should be called colorIndex since it is not an EmbColor */
+} EmbStitch;
+
+typedef struct EmbStitchList_
+{
+ struct EmbStitch_ stitch;
+ struct EmbStitchList_* next;
+} EmbStitchList;
+
+extern EMB_PUBLIC EmbStitchList* EMB_CALL embStitchList_create(EmbStitch data);
+extern EMB_PUBLIC EmbStitchList* EMB_CALL embStitchList_add(EmbStitchList* pointer, EmbStitch data);
+extern EMB_PUBLIC int EMB_CALL embStitchList_count(EmbStitchList* pointer);
+extern EMB_PUBLIC int EMB_CALL embStitchList_empty(EmbStitchList* pointer);
+extern EMB_PUBLIC void EMB_CALL embStitchList_free(EmbStitchList* pointer);
+extern EMB_PUBLIC EmbStitch EMB_CALL embStitchList_getAt(EmbStitchList* pointer, int num);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_STITCH_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-thread.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-thread.c
new file mode 100644
index 000000000..c632ccdc1
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-thread.c
@@ -0,0 +1,150 @@
+#include "emb-thread.h"
+#include "emb-logging.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+int embThread_findNearestColor(EmbColor color, EmbThreadList* colors)
+{
+ double currentClosestValue = 9999999;
+ int closestIndex = -1;
+ int red = color.r;
+ int green = color.g;
+ int blue = color.b;
+ int i = 0;
+ EmbThreadList* currentThreadItem = colors;
+
+ while(currentThreadItem != NULL)
+ {
+ int deltaRed;
+ int deltaBlue;
+ int deltaGreen;
+ double dist;
+ EmbColor c;
+ c = currentThreadItem->thread.color;
+
+ deltaRed = red - c.r;
+ deltaBlue = green - c.g;
+ deltaGreen = blue - c.b;
+
+ dist = sqrt((double)(deltaRed * deltaRed) + (deltaBlue * deltaBlue) + (deltaGreen * deltaGreen));
+ if(dist <= currentClosestValue)
+ {
+ currentClosestValue = dist;
+ closestIndex = i;
+ }
+ currentThreadItem = currentThreadItem->next;
+ i++;
+ }
+ return closestIndex;
+}
+
+int embThread_findNearestColorInArray(EmbColor color, EmbThread* colorArray, int count)
+{
+ double currentClosestValue = 9999999;
+ int closestIndex = -1;
+ int red = color.r;
+ int green = color.g;
+ int blue = color.b;
+ int i = 0;
+ for(i = 0; i < count; i++)
+ {
+ int deltaRed;
+ int deltaBlue;
+ int deltaGreen;
+ double dist;
+ EmbColor c;
+ c = colorArray[i].color;
+
+ deltaRed = red - c.r;
+ deltaBlue = green - c.g;
+ deltaGreen = blue - c.b;
+
+ dist = sqrt((double)(deltaRed * deltaRed) + (deltaBlue * deltaBlue) + (deltaGreen * deltaGreen));
+ if(dist <= currentClosestValue)
+ {
+ currentClosestValue = dist;
+ closestIndex = i;
+ }
+ }
+ return closestIndex;
+}
+
+EmbThread embThread_getRandom(void)
+{
+ EmbThread c;
+ c.color.r = rand()%256;
+ c.color.g = rand()%256;
+ c.color.b = rand()%256;
+ c.description = "random";
+ c.catalogNumber = "";
+ return c;
+}
+
+EmbThreadList* embThreadList_create(EmbThread data)
+{
+ EmbThreadList* heapThreadList = (EmbThreadList*)malloc(sizeof(EmbThreadList));
+ if(!heapThreadList) { embLog_error("emb-thread.c embThreadList_create(), cannot allocate memory for heapThreadList\n"); return 0; }
+ heapThreadList->thread = data;
+ heapThreadList->next = 0;
+ return heapThreadList;
+}
+
+EmbThreadList* embThreadList_add(EmbThreadList* pointer, EmbThread data)
+{
+ if(!pointer) { embLog_error("emb-thread.c embThreadList_add(), pointer argument is null\n"); return 0; }
+ if(pointer->next) { embLog_error("emb-thread.c embThreadList_add(), pointer->next should be null\n"); return 0; }
+ pointer->next = (EmbThreadList*)malloc(sizeof(EmbThreadList));
+ if(!pointer->next) { embLog_error("emb-thread.c embThreadList_add(), cannot allocate memory for pointer->next\n"); return 0; }
+ pointer = pointer->next;
+ pointer->thread = data;
+ pointer->next = 0;
+ return pointer;
+}
+
+EmbThread embThreadList_getAt(EmbThreadList* pointer, int num)
+{
+ /* TODO: pointer safety */
+ int i = 0;
+ for(i = 0; i < num; i++)
+ {
+ if(pointer->next)
+ {
+ pointer = pointer->next;
+ }
+ }
+ return pointer->thread;
+}
+
+int embThreadList_count(EmbThreadList* pointer)
+{
+ int i = 1;
+ if(!pointer) return 0;
+ while(pointer->next)
+ {
+ pointer = pointer->next;
+ i++;
+ }
+ return i;
+}
+
+int embThreadList_empty(EmbThreadList* pointer)
+{
+ if(!pointer)
+ return 1;
+ return 0;
+}
+
+void embThreadList_free(EmbThreadList* pointer)
+{
+ EmbThreadList* tempPointer = pointer;
+ EmbThreadList* nextPointer = 0;
+ while(tempPointer)
+ {
+ nextPointer = tempPointer->next;
+ free(tempPointer);
+ tempPointer = nextPointer;
+ }
+ pointer = 0;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-thread.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-thread.h
new file mode 100644
index 000000000..70aca5375
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-thread.h
@@ -0,0 +1,45 @@
+/*! @file emb-thread.h */
+#ifndef EMB_THREAD_H
+#define EMB_THREAD_H
+
+/* TODO: what the heck is math.h doing here? This needs moved to the source file instead of being here. */
+#include <math.h>
+#include "emb-color.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct EmbThread_
+{
+ EmbColor color;
+ const char* description;
+ const char* catalogNumber;
+} EmbThread;
+
+typedef struct EmbThreadList_
+{
+ EmbThread thread;
+ struct EmbThreadList_* next;
+} EmbThreadList;
+
+extern EMB_PUBLIC int EMB_CALL embThread_findNearestColor(EmbColor color, EmbThreadList* colors);
+extern EMB_PUBLIC int EMB_CALL embThread_findNearestColorInArray(EmbColor color, EmbThread* colorArray, int count);
+extern EMB_PUBLIC EmbThread EMB_CALL embThread_getRandom(void);
+
+extern EMB_PUBLIC EmbThreadList* EMB_CALL embThreadList_create(EmbThread data);
+extern EMB_PUBLIC EmbThreadList* EMB_CALL embThreadList_add(EmbThreadList* pointer, EmbThread data);
+extern EMB_PUBLIC int EMB_CALL embThreadList_count(EmbThreadList* pointer);
+extern EMB_PUBLIC int EMB_CALL embThreadList_empty(EmbThreadList* pointer);
+extern EMB_PUBLIC void EMB_CALL embThreadList_free(EmbThreadList* pointer);
+extern EMB_PUBLIC EmbThread EMB_CALL embThreadList_getAt(EmbThreadList* pointer, int num);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_THREAD_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-time.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-time.c
new file mode 100644
index 000000000..f9a40d65a
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-time.c
@@ -0,0 +1,40 @@
+#include "emb-time.h"
+
+#ifdef ARDUINO
+/*TODO: arduino embTime includes */
+#else
+#include <time.h>
+#endif
+
+void embTime_initNow(EmbTime* t)
+{
+#ifdef ARDUINO
+/*TODO: arduino embTime_initNow */
+#else
+ time_t rawtime;
+ struct tm* timeinfo;
+ time(&rawtime);
+ timeinfo = localtime(&rawtime);
+
+ t->year = timeinfo->tm_year;
+ t->month = timeinfo->tm_mon;
+ t->day = timeinfo->tm_mday;
+ t->hour = timeinfo->tm_hour;
+ t->minute = timeinfo->tm_min;
+ t->second = timeinfo->tm_sec;
+#endif /* ARDUINO */
+}
+
+EmbTime embTime_time(EmbTime* t)
+{
+#ifdef ARDUINO
+/*TODO: arduino embTime_time */
+#else
+
+int divideByZero = 0;
+divideByZero = divideByZero/divideByZero; /*TODO: wrap time() from time.h and verify it works consistently */
+
+#endif /* ARDUINO */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-time.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-time.h
new file mode 100644
index 000000000..b2f2ea8a8
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-time.h
@@ -0,0 +1,30 @@
+/*! @file emb-time.h */
+#ifndef EMB_TIME_H
+#define EMB_TIME_H
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct EmbTime_
+{
+ unsigned int year;
+ unsigned int month;
+ unsigned int day;
+ unsigned int hour;
+ unsigned int minute;
+ unsigned int second;
+} EmbTime;
+
+extern EMB_PUBLIC void EMB_CALL embTime_initNow(EmbTime* t);
+extern EMB_PUBLIC EmbTime EMB_CALL embTime_time(EmbTime* t);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_TIME_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-vector.c b/Software/Visual_Studio/Embroidery/libembroidery/emb-vector.c
new file mode 100644
index 000000000..749b1282c
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-vector.c
@@ -0,0 +1,85 @@
+#include "emb-vector.h"
+#include "emb-logging.h"
+#include <math.h>
+#include <stdlib.h>
+
+void embVector_normalize(EmbVector vector, EmbVector* result)
+{
+ double length = embVector_getLength(vector);
+
+ if(!result) { embLog_error("emb-vector.c embVector_normalize(), result argument is null\n"); return; }
+ result->X = vector.X / length;
+ result->Y = vector.Y / length;
+}
+
+void embVector_multiply(EmbVector vector, double magnitude, EmbVector* result)
+{
+ if(!result) { embLog_error("emb-vector.c embVector_multiply(), result argument is null\n"); return; }
+ result->X = vector.X * magnitude;
+ result->Y = vector.Y * magnitude;
+}
+
+void embVector_add(EmbVector v1, EmbVector v2, EmbVector* result)
+{
+ if(!result) { embLog_error("emb-vector.c embVector_add(), result argument is null\n"); return; }
+ result->X = v1.X + v2.X;
+ result->Y = v1.Y + v2.Y;
+}
+
+double embVector_getLength(EmbVector vector)
+{
+ return sqrt(vector.X * vector.X + vector.Y * vector.Y);
+}
+
+EmbVectorList* embVectorList_create(EmbVector data)
+{
+ EmbVectorList* pointer = (EmbVectorList*)malloc(sizeof(EmbVectorList));
+ if(!pointer) { embLog_error("emb-vector.c embVectorList_create(), cannot allocate memory for pointer\n"); return 0; }
+ pointer->vector = data;
+ pointer->next = 0;
+ return pointer;
+}
+
+EmbVectorList* embVectorList_add(EmbVectorList* pointer, EmbVector data)
+{
+ if(!pointer) { embLog_error("emb-vector.c embVectorList_add(), pointer argument is null\n"); return 0; }
+ if(pointer->next) { embLog_error("emb-vector.c embVectorList_add(), pointer->next should be null\n"); return 0; }
+ pointer->next = (EmbVectorList*)malloc(sizeof(EmbVectorList));
+ if(!pointer->next) { embLog_error("emb-vector.c embVectorList_add(), cannot allocate memory for pointer->next\n"); return 0; }
+ pointer = pointer->next;
+ pointer->vector = data;
+ pointer->next = 0;
+ return pointer;
+}
+
+int embVectorList_count(EmbVectorList* pointer)
+{
+ int i = 1;
+ if(!pointer) return 0;
+ while(pointer->next)
+ {
+ pointer = pointer->next;
+ i++;
+ }
+ return i;
+}
+
+int embVectorList_empty(EmbVectorList* pointer)
+{
+ if(!pointer)
+ return 1;
+ return 0;
+}
+
+void embVectorList_free(EmbVectorList* pointer)
+{
+ while(pointer)
+ {
+ EmbVectorList* temp = pointer;
+ pointer = pointer->next;
+ free(temp);
+ temp = 0;
+ }
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/emb-vector.h b/Software/Visual_Studio/Embroidery/libembroidery/emb-vector.h
new file mode 100644
index 000000000..1bbfa514f
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/emb-vector.h
@@ -0,0 +1,43 @@
+/*! @file emb-vector.h */
+#ifndef EMB_VECTOR_H
+#define EMB_VECTOR_H
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* TODO: EmbVector should just be a typedef of EmbPoint since internally, they are the same.
+ In cases where it represents vector data, then the name can be used to avoid confusion.
+ */
+typedef struct EmbVector_
+{
+ double X;
+ double Y;
+} EmbVector;
+
+typedef struct EmbVectorList_
+{
+ EmbVector vector;
+ struct EmbVectorList_* next;
+} EmbVectorList;
+
+extern EMB_PUBLIC void EMB_CALL embVector_normalize(EmbVector vector, EmbVector* result);
+extern EMB_PUBLIC void EMB_CALL embVector_multiply(EmbVector vector, double magnitude, EmbVector* result);
+extern EMB_PUBLIC void EMB_CALL embVector_add(EmbVector v1, EmbVector v2, EmbVector* result);
+extern EMB_PUBLIC double EMB_CALL embVector_getLength(EmbVector vector);
+
+extern EMB_PUBLIC EmbVectorList* EMB_CALL embVectorList_create(EmbVector data);
+extern EMB_PUBLIC EmbVectorList* EMB_CALL embVectorList_add(EmbVectorList* pointer, EmbVector data);
+extern EMB_PUBLIC int EMB_CALL embVectorList_count(EmbVectorList* pointer);
+extern EMB_PUBLIC int EMB_CALL embVectorList_empty(EmbVectorList* pointer);
+extern EMB_PUBLIC void EMB_CALL embVectorList_free(EmbVectorList* pointer);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* EMB_VECTOR_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/examples/README.md b/Software/Visual_Studio/Embroidery/libembroidery/examples/README.md
new file mode 100644
index 000000000..cad2bb8b7
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/examples/README.md
@@ -0,0 +1,4 @@
+libembroidery Arduino Examples
+------------------------------
+
+This folder contains Arduino example sketches for libembroidery.
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/examples/barebones/barebones.ino b/Software/Visual_Studio/Embroidery/libembroidery/examples/barebones/barebones.ino
new file mode 100644
index 000000000..32c12fcf2
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/examples/barebones/barebones.ino
@@ -0,0 +1,84 @@
+//libembroidery barebones example
+//TODO: This is a work in progress sketch using libembroidery
+//TODO: NOTE: you may need to modify the SD_CS and/or supply your own sample file
+
+#include <SD.h>
+#include "emb-pattern.h"
+#include "geom-arc.h" //TODO: remove this later
+
+#define SD_CS 5 // Card select
+
+//SPCR States (SPI Control Register)
+uint8_t SPI_SDCARD = 0; // Set the SPCR to this before reading
+
+uint32_t stitchCount = 0;
+
+void setup(void)
+{
+ Serial.begin(9600);
+ Serial.println(F("libembroidery barebones example"));
+
+ Serial.print(F("Initializing SD card..."));
+ if(!SD.begin(SD_CS))
+ {
+ Serial.println(F("failed!"));
+ return;
+ }
+ Serial.println(F("OK!"));
+ SPI_SDCARD = SPCR; //Save the state for later use
+}
+
+void loop(void)
+{
+ loadEmb("sample.exp");
+}
+
+void loadEmb(char* fileName)
+{
+ SPCR = SPI_SDCARD;
+
+ if(!SD.exists(fileName))
+ {
+ Serial.println("file DOES NOT exist!.");
+ return;
+ }
+
+ //==============================
+ // Reading
+ //==============================
+ EmbPattern* p = 0;
+ int successful = 0;
+
+ p = embPattern_create();
+ if(!p) { Serial.println(F("ERROR: Could not allocate memory for embroidery pattern.")); return; }
+
+ successful = embPattern_read(p, fileName);
+ if(!successful)
+ {
+ Serial.print("ERROR: Reading file was unsuccessful: ");
+ Serial.println(fileName);
+ embPattern_free(p);
+ return;
+ }
+
+ //==============================
+ // Report Design Info
+ //==============================
+ Serial.print(F("Total Stitches: "));
+ Serial.println(stitchCount, DEC); //TODO: For some reason we are missing the last 2 stitches. Investigate embPattern_addStitchAbs() causing a small memory leak.
+ stitchCount = 0;
+
+ //==============================
+ // Cleanup
+ //==============================
+ embPattern_free(p);
+}
+
+void eventHandler_addStitchAbs(EmbPattern* p, double x, double y, int flags, int isAutoColorIndex)
+{
+ stitchCount++;
+ Serial.print(F("Adding Stitch: "));
+ Serial.println(stitchCount, DEC);
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-100.c b/Software/Visual_Studio/Embroidery/libembroidery/format-100.c
new file mode 100644
index 000000000..9a8650056
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-100.c
@@ -0,0 +1,65 @@
+#include "format-100.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int read100(EmbPattern* pattern, const char* fileName)
+{
+ EmbFile* file = 0;
+ int x, y;
+ int stitchType;
+ unsigned char b[4];
+
+ if(!pattern) { embLog_error("format-100.c read100(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-100.c read100(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-100.c read100(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+ embPattern_loadExternalColorFile(pattern, fileName);
+ while(embFile_read(b, 1, 4, file) == 4)
+ {
+ stitchType = NORMAL;
+ x = (b[2] > 0x80) ? -(b[2] - 0x80) : b[2];
+ y = (b[3] > 0x80) ? -(b[3] - 0x80) : b[3];
+ /*if(!(b[0] & 0xFC)) stitchType = JUMP; TODO: review & fix */
+ if(!(b[0] & 0x01)) stitchType = STOP;
+ if(b[0] == 0x1F) stitchType = END;
+ embPattern_addStitchRel(pattern, x / 10.0, y / 10.0, stitchType, 1);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int write100(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-100.c write100(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-100.c write100(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-100.c write100(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish write100 */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-100.h b/Software/Visual_Studio/Embroidery/libembroidery/format-100.h
new file mode 100644
index 000000000..3c795ae51
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-100.h
@@ -0,0 +1,22 @@
+/*! @file format-100.h */
+#ifndef FORMAT_100_H
+#define FORMAT_100_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL read100(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL write100(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_100_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-10o.c b/Software/Visual_Studio/Embroidery/libembroidery/format-10o.c
new file mode 100644
index 000000000..e13c3b2c1
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-10o.c
@@ -0,0 +1,84 @@
+#include "format-10o.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int read10o(EmbPattern* pattern, const char* fileName)
+{
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-10o.c read10o(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-10o.c read10o(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName,"rb");
+ if(!file)
+ {
+ embLog_error("format-10o.c read10o(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embPattern_loadExternalColorFile(pattern, fileName);
+
+ while(1)
+ {
+ int x, y;
+ int stitchType = NORMAL;
+ unsigned char ctrl = (unsigned char)embFile_getc(file);
+ if(embFile_eof(file))
+ break;
+ y = embFile_getc(file);
+ if(embFile_eof(file))
+ break;
+ x = embFile_getc(file);
+ if(embFile_eof(file))
+ break;
+ if(ctrl & 0x20)
+ x = -x;
+ if(ctrl & 0x40)
+ y = -y;
+ if(ctrl & 0x01)
+ stitchType = TRIM;
+ if((ctrl & 0x5) == 5)
+ {
+ stitchType = STOP;
+ }
+ if(ctrl == 0xF8 || ctrl == 0x91 || ctrl == 0x87)
+ {
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+ break;
+ }
+ embPattern_addStitchRel(pattern, x / 10.0, y / 10.0, stitchType, 1);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int write10o(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-10o.c write10o(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-10o.c write10o(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-10o.c write10o(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish write10o */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-10o.h b/Software/Visual_Studio/Embroidery/libembroidery/format-10o.h
new file mode 100644
index 000000000..25f90b5fe
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-10o.h
@@ -0,0 +1,22 @@
+/*! @file format-10o.h */
+#ifndef FORMAT_10O_H
+#define FORMAT_10O_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL read10o(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL write10o(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_10O_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-art.c b/Software/Visual_Studio/Embroidery/libembroidery/format-art.c
new file mode 100644
index 000000000..c515ac58b
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-art.c
@@ -0,0 +1,35 @@
+#include "format-art.h"
+#include "emb-logging.h"
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readArt(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-art.c readArt(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-art.c readArt(), fileName argument is null\n"); return 0; }
+ return 0; /*TODO: finish readArt */
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeArt(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-art.c writeArt(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-art.c writeArt(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-art.c writeArt(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writeArt */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-art.h b/Software/Visual_Studio/Embroidery/libembroidery/format-art.h
new file mode 100644
index 000000000..ba565ca76
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-art.h
@@ -0,0 +1,22 @@
+/*! @file format-art.h */
+#ifndef FORMAT_ART_H
+#define FORMAT_ART_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readArt(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeArt(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_ART_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-bmc.c b/Software/Visual_Studio/Embroidery/libembroidery/format-bmc.c
new file mode 100644
index 000000000..d295db3ee
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-bmc.c
@@ -0,0 +1,35 @@
+#include "format-bmc.h"
+#include "emb-logging.h"
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readBmc(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-bmc.c readBmc(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-bmc.c readBmc(), fileName argument is null\n"); return 0; }
+ return 0; /*TODO: finish readBmc */
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeBmc(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-bmc.c writeBmc(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-bmc.c writeBmc(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-bmc.c writeBmc(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writeBmc */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-bmc.h b/Software/Visual_Studio/Embroidery/libembroidery/format-bmc.h
new file mode 100644
index 000000000..e8cd51c6a
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-bmc.h
@@ -0,0 +1,22 @@
+/*! @file format-bmc.h */
+#ifndef FORMAT_BMC_H
+#define FORMAT_BMC_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readBmc(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeBmc(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_BMC_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-bro.c b/Software/Visual_Studio/Embroidery/libembroidery/format-bro.c
new file mode 100644
index 000000000..a99dc7041
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-bro.c
@@ -0,0 +1,97 @@
+#include "format-bro.h"
+#include "helpers-binary.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readBro(EmbPattern* pattern, const char* fileName)
+{
+ unsigned char x55;
+ short unknown1, unknown2, unknown3, unknown4, moreBytesToEnd;
+ char name[8];
+ int stitchType;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-bro.c readBro(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-bro.c readBro(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-bro.c readBro(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embPattern_loadExternalColorFile(pattern, fileName);
+
+ x55 = binaryReadByte(file);
+ unknown1 = binaryReadInt16(file); /* TODO: determine what this unknown data is */
+
+ embFile_read(name, 1, 8, file);
+ unknown2 = binaryReadInt16(file); /* TODO: determine what this unknown data is */
+ unknown3 = binaryReadInt16(file); /* TODO: determine what this unknown data is */
+ unknown4 = binaryReadInt16(file); /* TODO: determine what this unknown data is */
+ moreBytesToEnd = binaryReadInt16(file);
+
+ embFile_seek(file, 0x100, SEEK_SET);
+
+ while(1)
+ {
+ short b1, b2;
+ stitchType = NORMAL;
+ b1 = binaryReadByte(file);
+ b2 = binaryReadByte(file);
+ if(b1 == -128)
+ {
+ unsigned char bCode = binaryReadByte(file);
+ b1 = binaryReadInt16(file);
+ b2 = binaryReadInt16(file);
+ if(bCode == 2)
+ {
+ stitchType = STOP;
+ }
+ else if(bCode == 3)
+ {
+ stitchType = TRIM;
+ }
+ else if(bCode == 0x7E)
+ {
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+ break;
+ }
+ }
+ embPattern_addStitchRel(pattern, b1 / 10.0, b2 / 10.0, stitchType, 1);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeBro(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-bro.c writeBro(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-bro.c writeBro(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-bro.c writeBro(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writeBro */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-bro.h b/Software/Visual_Studio/Embroidery/libembroidery/format-bro.h
new file mode 100644
index 000000000..a826ada49
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-bro.h
@@ -0,0 +1,22 @@
+/*! @file format-bro.h */
+#ifndef FORMAT_BRO_H
+#define FORMAT_BRO_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readBro(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeBro(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_BRO_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-cnd.c b/Software/Visual_Studio/Embroidery/libembroidery/format-cnd.c
new file mode 100644
index 000000000..136c85ae4
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-cnd.c
@@ -0,0 +1,35 @@
+#include "format-cnd.h"
+#include "emb-logging.h"
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readCnd(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-cnd.c readCnd(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-cnd.c readCnd(), fileName argument is null\n"); return 0; }
+ return 0; /*TODO: finish readCnd */
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeCnd(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-cnd.c writeCnd(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-cnd.c writeCnd(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-cnd.c writeCnd(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writeCnd */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-cnd.h b/Software/Visual_Studio/Embroidery/libembroidery/format-cnd.h
new file mode 100644
index 000000000..9737e31a5
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-cnd.h
@@ -0,0 +1,22 @@
+/*! @file format-cnd.h */
+#ifndef FORMAT_CND_H
+#define FORMAT_CND_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readCnd(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeCnd(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_CND_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-col.c b/Software/Visual_Studio/Embroidery/libembroidery/format-col.c
new file mode 100644
index 000000000..d89361c29
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-col.c
@@ -0,0 +1,94 @@
+#include "format-col.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+#include <stdlib.h>
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readCol(EmbPattern* pattern, const char* fileName)
+{
+ int numberOfColors, i;
+ FILE* file = 0;
+
+ if(!pattern) { embLog_error("format-col.c readCol(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-col.c readCol(), fileName argument is null\n"); return 0; }
+
+ file = fopen(fileName, "r");
+ if(!file)
+ {
+ /* NOTE: The .col format is an optional color file. Do not log an error if the file does not exist */
+ return 0;
+ }
+
+ embThreadList_free(pattern->threadList);
+ pattern->threadList = 0;
+ pattern->lastThread = 0;
+
+ /* TODO: replace all scanf code */
+ if(fscanf(file, "%d\r", &numberOfColors) < 1) /* TODO: needs to work cross-platform - Win: \r\n Mac: \r Linux: \n */
+ {
+ /* TODO: log error */
+ return 0;
+ }
+ for(i = 0; i < numberOfColors; i++)
+ {
+ int num, blue, green, red;
+ EmbThread t;
+ char line[30];
+ /* TODO: replace all scanf code */
+ if(fscanf(file, "%s\r", line) < 1) /* TODO: needs to work cross-platform - Win: \r\n Mac: \r Linux: \n */
+ {
+ /* TODO: log error */
+ return 0;
+ }
+ /* TODO: replace all scanf code */
+ if(sscanf(line,"%d,%d,%d,%d\n\r", &num, &blue, &green, &red) != 4) /* TODO: needs to work cross-platform - Win: \r\n Mac: \r Linux: \n */
+ {
+ break;
+ }
+ t.color.r = (unsigned char)red;
+ t.color.g = (unsigned char)green;
+ t.color.b = (unsigned char)blue;
+ t.catalogNumber = "";
+ t.description = "";
+ embPattern_addThread(pattern, t);
+ }
+ fclose(file);
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeCol(EmbPattern* pattern, const char* fileName)
+{
+ FILE* file = 0;
+ int i, colorCount;
+ EmbThreadList *colors;
+
+ if(!pattern) { embLog_error("format-col.c writeCol(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-col.c writeCol(), fileName argument is null\n"); return 0; }
+
+ file = fopen(fileName, "w");
+ if(!file)
+ {
+ embLog_error("format-col.c writeCol(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+ colorCount = embThreadList_count(pattern->threadList);
+ fprintf(file, "%d\n\r", colorCount); /* TODO: needs to be \r\n */
+ colors = pattern->threadList;
+ i = 0;
+ while(colors)
+ {
+ EmbColor c;
+ c = colors->thread.color;
+ fprintf(file, "%d,%d,%d,%d\n\r", i, (int)c.r, (int)c.g, (int)c.b); /* TODO: needs to be \r\n */
+ i++;
+ colors = colors->next;
+ }
+ fclose(file);
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-col.h b/Software/Visual_Studio/Embroidery/libembroidery/format-col.h
new file mode 100644
index 000000000..fbb7ebb9d
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-col.h
@@ -0,0 +1,22 @@
+/*! @file format-col.h */
+#ifndef FORMAT_COL_H
+#define FORMAT_COL_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readCol(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeCol(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_COL_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-csd.c b/Software/Visual_Studio/Embroidery/libembroidery/format-csd.c
new file mode 100644
index 000000000..29c26a7f7
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-csd.c
@@ -0,0 +1,218 @@
+#include "format-csd.h"
+#include "helpers-binary.h"
+#include "helpers-misc.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include <stdlib.h>
+
+#define CsdSubMaskSize 479
+#define CsdXorMaskSize 501
+
+static char _subMask[CsdSubMaskSize];
+static char _xorMask[CsdXorMaskSize];
+
+static void BuildDecryptionTable(int seed)
+{
+ int i;
+ const int mul1 = 0x41C64E6D;
+ const int add1 = 0x3039;
+
+ for(i = 0; i < CsdSubMaskSize; i++)
+ {
+ seed *= mul1;
+ seed += add1;
+ _subMask[i] = (char) ((seed >> 16) & 0xFF);
+ }
+ for(i = 0; i < CsdXorMaskSize; i++)
+ {
+ seed *= mul1;
+ seed += add1;
+ _xorMask[i] = (char) ((seed >> 16) & 0xFF);
+ }
+}
+
+static unsigned char DecodeCsdByte(long fileOffset, unsigned char val, int type)
+{
+ static const unsigned char _decryptArray[] =
+ {
+ 0x43, 0x6E, 0x72, 0x7A, 0x76, 0x6C, 0x61, 0x6F, 0x7C, 0x29, 0x5D, 0x62, 0x60, 0x6E, 0x61, 0x62, 0x20
+ , 0x41, 0x66, 0x6A, 0x3A, 0x35, 0x5A, 0x63, 0x7C, 0x37, 0x3A, 0x2A, 0x25, 0x24, 0x2A, 0x33, 0x00, 0x10
+ , 0x14, 0x03, 0x72, 0x4C, 0x48, 0x42, 0x08, 0x7A, 0x5E, 0x0B, 0x6F, 0x45, 0x47, 0x5F, 0x40, 0x54, 0x5C
+ , 0x57, 0x55, 0x59, 0x53, 0x3A, 0x32, 0x6F, 0x53, 0x54, 0x50, 0x5C, 0x4A, 0x56, 0x2F, 0x2F, 0x62, 0x2C
+ , 0x22, 0x65, 0x25, 0x28, 0x38, 0x30, 0x38, 0x22, 0x2B, 0x25, 0x3A, 0x6F, 0x27, 0x38, 0x3E, 0x3F, 0x74
+ , 0x37, 0x33, 0x77, 0x2E, 0x30, 0x3D, 0x34, 0x2E, 0x32, 0x2B, 0x2C, 0x0C, 0x18, 0x42, 0x13, 0x16, 0x0A
+ , 0x15, 0x02, 0x0B, 0x1C, 0x1E, 0x0E, 0x08, 0x60, 0x64, 0x0D, 0x09, 0x51, 0x25, 0x1A, 0x18, 0x16, 0x19
+ , 0x1A, 0x58, 0x10, 0x14, 0x5B, 0x08, 0x15, 0x1B, 0x5F, 0xD5, 0xD2, 0xAE, 0xA3, 0xC1, 0xF0, 0xF4, 0xE8
+ , 0xF8, 0xEC, 0xA6, 0xAB, 0xCD, 0xF8, 0xFD, 0xFB, 0xE2, 0xF0, 0xFE, 0xFA, 0xF5, 0xB5, 0xF7, 0xF9, 0xFC
+ , 0xB9, 0xF5, 0xEF, 0xF4, 0xF8, 0xEC, 0xBF, 0xC3, 0xCE, 0xD7, 0xCD, 0xD0, 0xD7, 0xCF, 0xC2, 0xDB, 0xA4
+ , 0xA0, 0xB0, 0xAF, 0xBE, 0x98, 0xE2, 0xC2, 0x91, 0xE5, 0xDC, 0xDA, 0xD2, 0x96, 0xC4, 0x98, 0xF8, 0xC9
+ , 0xD2, 0xDD, 0xD3, 0x9E, 0xDE, 0xAE, 0xA5, 0xE2, 0x8C, 0xB6, 0xAC, 0xA3, 0xA9, 0xBC, 0xA8, 0xA6, 0xEB
+ , 0x8B, 0xBF, 0xA1, 0xAC, 0xB5, 0xA3, 0xBB, 0xB6, 0xA7, 0xD8, 0xDC, 0x9A, 0xAA, 0xF9, 0x82, 0xFB, 0x9D
+ , 0xB9, 0xAB, 0xB3, 0x94, 0xC1, 0xA0, 0x8C, 0x8B, 0x8E, 0x95, 0x8F, 0x87, 0x99, 0xE7, 0xE1, 0xA3, 0x83
+ , 0x8B, 0xCF, 0xA3, 0x85, 0x9D, 0x83, 0xD4, 0xB7, 0x83, 0x84, 0x91, 0x97, 0x9F, 0x88, 0x8F, 0xDD, 0xAD
+ , 0x90
+ };
+ int newOffset;
+
+ fileOffset = fileOffset - 1;
+ if(type != 0)
+ {
+ int final;
+ int fileOffsetHigh = (int) (fileOffset & 0xFFFFFF00);
+ int fileOffsetLow = (int) (fileOffset & 0xFF);
+
+ newOffset = fileOffsetLow;
+ fileOffsetLow = fileOffsetHigh;
+ final = fileOffsetLow%0x300;
+ if(final != 0x100 && final != 0x200)
+ {
+ newOffset = _decryptArray[newOffset] | fileOffsetHigh;
+ }
+ else if(final != 0x100 && final == 0x200)
+ {
+ if(newOffset == 0)
+ {
+ fileOffsetHigh = fileOffsetHigh - 0x100;
+ }
+ newOffset = _decryptArray[newOffset] | fileOffsetHigh;
+ }
+ else if(newOffset != 1 && newOffset != 0)
+ {
+ newOffset = _decryptArray[newOffset] | fileOffsetHigh;
+ }
+ else
+ {
+ fileOffsetHigh = fileOffsetHigh - 0x100;
+ newOffset = _decryptArray[newOffset] | fileOffsetHigh;
+ }
+ }
+ else
+ {
+ newOffset = (int) fileOffset;
+ }
+ return ((unsigned char) ((unsigned char) (val ^ _xorMask[newOffset%CsdXorMaskSize]) - _subMask[newOffset%CsdSubMaskSize]));
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readCsd(EmbPattern* pattern, const char* fileName)
+{
+ int i, type = 0;
+ unsigned char identifier[8];
+ unsigned char unknown1, unknown2;
+ char dx = 0, dy = 0;
+ int colorChange = -1;
+ int flags;
+ char endOfStream = 0;
+ EmbFile* file = 0;
+ unsigned char colorOrder[14];
+
+ if(!pattern) { embLog_error("format-csd.c readCsd(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-csd.c readCsd(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-csd.c readCsd(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ binaryReadBytes(file, identifier, 8); /* TODO: check return value */
+
+ if(identifier[0] != 0x7C && identifier[2] != 0xC3)
+ {
+ type = 1;
+ }
+ if(type == 0)
+ {
+ BuildDecryptionTable(0xC);
+ }
+ else
+ {
+ BuildDecryptionTable(identifier[0]);
+ }
+ embFile_seek(file, 8, SEEK_SET);
+ for(i = 0; i < 16; i++)
+ {
+ EmbThread thread;
+ thread.color.r = DecodeCsdByte(embFile_tell(file), binaryReadByte(file), type);
+ thread.color.g = DecodeCsdByte(embFile_tell(file), binaryReadByte(file), type);
+ thread.color.b = DecodeCsdByte(embFile_tell(file), binaryReadByte(file), type);
+ thread.catalogNumber = "";
+ thread.description = "";
+ embPattern_addThread(pattern, thread);
+ }
+ unknown1 = DecodeCsdByte(embFile_tell(file), binaryReadByte(file), type);
+ unknown2 = DecodeCsdByte(embFile_tell(file), binaryReadByte(file), type);
+
+ for(i = 0; i < 14; i++)
+ {
+ colorOrder[i] = (unsigned char) DecodeCsdByte(embFile_tell(file), binaryReadByte(file), type);
+ }
+ for(i = 0; !endOfStream; i++)
+ {
+ char negativeX, negativeY;
+ unsigned char b0 = DecodeCsdByte(embFile_tell(file), binaryReadByte(file), type);
+ unsigned char b1 = DecodeCsdByte(embFile_tell(file), binaryReadByte(file), type);
+ unsigned char b2 = DecodeCsdByte(embFile_tell(file), binaryReadByte(file), type);
+
+ if(b0 == 0xF8 || b0 == 0x87 || b0 == 0x91)
+ {
+ break;
+ }
+ negativeX = ((b0 & 0x20) > 0);
+ negativeY = ((b0 & 0x40) > 0);
+ b0 = (unsigned char)(b0 & (0xFF ^ 0xE0));
+
+ if((b0 & 0x1F) == 0) flags = NORMAL;
+ else if((b0 & 0x0C) > 0)
+ {
+ flags = STOP;
+ if(colorChange >= 14)
+ {
+ printf("Invalid color change detected\n");
+ }
+ embPattern_changeColor(pattern, colorOrder[colorChange % 14]);
+ colorChange += 1;
+ }
+ else if((b0 & 0x1F) > 0) flags = TRIM;
+ else flags = NORMAL;
+ dx = (char) b2;
+ dy = (char) b1;
+ if(negativeX) dx = (char) -dx;
+ if(negativeY) dy = (char) -dy;
+ if(flags == STOP) embPattern_addStitchRel(pattern, 0, 0, flags, 1);
+ else embPattern_addStitchRel(pattern, dx / 10.0, dy / 10.0, flags, 1);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeCsd(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-csd.c writeCsd(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-csd.c writeCsd(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-csd.c writeCsd(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writeCsd */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-csd.h b/Software/Visual_Studio/Embroidery/libembroidery/format-csd.h
new file mode 100644
index 000000000..dc80eed42
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-csd.h
@@ -0,0 +1,22 @@
+/*! @file format-csd.h */
+#ifndef FORMAT_CSD_H
+#define FORMAT_CSD_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readCsd(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeCsd(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_CSD_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-csv.c b/Software/Visual_Studio/Embroidery/libembroidery/format-csv.c
new file mode 100644
index 000000000..0c38e76f4
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-csv.c
@@ -0,0 +1,345 @@
+#include "format-csv.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include <stdlib.h>
+#include <string.h>
+
+static char* csvStitchFlagToStr(int flags)
+{
+ switch(flags)
+ {
+ case NORMAL:
+ return "STITCH";
+ break;
+ case JUMP:
+ return "JUMP";
+ break;
+ case TRIM:
+ return "TRIM";
+ break;
+ case STOP:
+ return "COLOR";
+ break;
+ case END:
+ return "END";
+ break;
+ default:
+ return "UNKNOWN";
+ break;
+ }
+}
+
+static int csvStrToStitchFlag(const char* str)
+{
+ if(!str)
+ {
+ embLog_error("format-csv.c csvStrToStitchFlag(), str argument is null\n");
+ return -1;
+ }
+ if(!strcmp(str, "STITCH"))
+ return NORMAL;
+ else if(!strcmp(str, "JUMP"))
+ return JUMP;
+ else if(!strcmp(str, "TRIM"))
+ return TRIM;
+ else if(!strcmp(str, "COLOR"))
+ return STOP;
+ else if(!strcmp(str, "END"))
+ return END;
+ else if(!strcmp(str, "UNKNOWN"))
+ return -1;
+ return -1;
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readCsv(EmbPattern* pattern, const char* fileName)
+{
+ EmbFile* file = 0;
+ int numColorChanges = 0;
+ int size = 1024;
+ int pos = 0;
+ int c = 0;
+ int cellNum = 0;
+ int process = 0;
+ int csvMode = CSV_MODE_NULL;
+ int expect = CSV_EXPECT_QUOTE1;
+ int flags = 0;
+ double xx = 0.0;
+ double yy = 0.0;
+ unsigned char r = 0, g = 0, b = 0;
+ char* buff = 0;
+
+ if(!pattern) { embLog_error("format-csv.c readCsv(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-csv.c readCsv(), fileName argument is null\n"); return 0; }
+
+ buff = (char*)malloc(size);
+ if(!buff) { embLog_error("format-csv.c readCsv(), unable to allocate memory for buff\n"); return 0; }
+
+ file = embFile_open(fileName,"r");
+ if(!file)
+ {
+ embLog_error("format-csv.c readCsv(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+ else
+ {
+ pos = 0;
+ do
+ {
+ c = embFile_getc(file);
+ switch(c)
+ {
+ case '"':
+ if(expect == CSV_EXPECT_QUOTE1)
+ {
+ expect = CSV_EXPECT_QUOTE2;
+ }
+ else if(expect == CSV_EXPECT_QUOTE2)
+ expect = CSV_EXPECT_COMMA;
+ break;
+ case ',':
+ if(expect == CSV_EXPECT_COMMA)
+ {
+ process = 1;
+ }
+ break;
+ case '\n':
+ if(expect == CSV_EXPECT_COMMA)
+ {
+ process = 1;
+ }
+ else if(expect == CSV_EXPECT_QUOTE1)
+ {
+ /* Do Nothing. We encountered a blank line. */
+ }
+ else
+ {
+ embLog_error("format-csv.c readCsv(), premature newline\n");
+ return 0;
+ }
+ break;
+ }
+ if(pos >= size - 1)
+ {
+ size *= 2;
+ buff = (char*)realloc(buff,size);
+ if(!buff) { embLog_error("format-csv.c readCsv(), cannot re-allocate memory for buff\n"); return 0; }
+ }
+
+ if(process)
+ {
+ buff[pos] = 0;
+ pos = 0;
+ process = 0;
+ cellNum++;
+ expect = CSV_EXPECT_QUOTE1;
+ if(csvMode == CSV_MODE_NULL)
+ {
+ if (!strcmp(buff, "#")) { csvMode = CSV_MODE_COMMENT; }
+ else if(!strcmp(buff, ">")) { csvMode = CSV_MODE_VARIABLE; }
+ else if(!strcmp(buff, "$")) { csvMode = CSV_MODE_THREAD; }
+ else if(!strcmp(buff, "*")) { csvMode = CSV_MODE_STITCH; }
+ else { /* TODO: error */ return 0; }
+ }
+ else if(csvMode == CSV_MODE_COMMENT)
+ {
+ /* Do Nothing */
+ }
+ else if(csvMode == CSV_MODE_VARIABLE)
+ {
+ /* Do Nothing */
+ }
+ else if(csvMode == CSV_MODE_THREAD)
+ {
+ if(cellNum == 2)
+ {
+ /* Do Nothing. Ignore Thread Number */
+ }
+ else if(cellNum == 3)
+ r = (unsigned char)atoi(buff);
+ else if(cellNum == 4)
+ g = (unsigned char)atoi(buff);
+ else if(cellNum == 5)
+ b = (unsigned char)atoi(buff);
+ else if(cellNum == 6)
+ {
+ /* TODO: Thread Description */
+ }
+ else if(cellNum == 7)
+ {
+ /* TODO: Thread Catalog Number */
+ EmbThread t;
+ t.color.r = r;
+ t.color.g = g;
+ t.color.b = b;
+ t.description = "TODO:DESCRIPTION";
+ t.catalogNumber = "TODO:CATALOG_NUMBER";
+ embPattern_addThread(pattern, t);
+ csvMode = CSV_MODE_NULL;
+ cellNum = 0;
+ }
+ else
+ {
+ /* TODO: error */
+ return 0;
+ }
+ }
+ else if(csvMode == CSV_MODE_STITCH)
+ {
+ if(cellNum == 2)
+ {
+ flags = csvStrToStitchFlag(buff);
+ if(flags == STOP)
+ numColorChanges++;
+ }
+ else if(cellNum == 3)
+ xx = atof(buff);
+ else if(cellNum == 4)
+ {
+ yy = atof(buff);
+ embPattern_addStitchAbs(pattern, xx, yy, flags, 1);
+ csvMode = CSV_MODE_NULL;
+ cellNum = 0;
+ }
+ else
+ {
+ /* TODO: error */
+ return 0;
+ }
+ }
+
+ if(c == '\n')
+ {
+ csvMode = CSV_MODE_NULL;
+ cellNum = 0;
+ }
+ }
+ else
+ {
+ if(expect == CSV_EXPECT_QUOTE2 && c != '"')
+ buff[pos++] = (char)c;
+ }
+ }
+ while(c != EOF);
+ embFile_close(file);
+ }
+
+ /* if not enough colors defined, fill in random colors */
+ while(embThreadList_count(pattern->threadList) < numColorChanges)
+ {
+ embPattern_addThread(pattern, embThread_getRandom());
+ }
+
+ free(buff);
+ buff = 0;
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeCsv(EmbPattern* pattern, const char* fileName)
+{
+ EmbFile* file = 0;
+ EmbStitchList* sList = 0;
+ EmbThreadList* tList = 0;
+ EmbRect boundingRect;
+ int i = 0;
+ int stitchCount = 0;
+ int threadCount = 0;
+
+ if(!pattern) { embLog_error("format-csv.c writeCsv(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-csv.c writeCsv(), fileName argument is null\n"); return 0; }
+
+ sList = pattern->stitchList;
+ stitchCount = embStitchList_count(sList);
+
+ tList = pattern->threadList;
+ threadCount = embThreadList_count(tList);
+
+ boundingRect = embPattern_calcBoundingBox(pattern);
+
+ if(!stitchCount)
+ {
+ embLog_error("format-csv.c writeCsv(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ {
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+ stitchCount++;
+ }
+
+ file = embFile_open(fileName, "w");
+ if(!file)
+ {
+ embLog_error("format-csv.c writeCsv(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+
+ /* write header */
+ embFile_printf(file, "\"#\",\"Embroidermodder 2 CSV Embroidery File\"\n");
+ embFile_printf(file, "\"#\",\"http://embroidermodder.github.io\"\n");
+ embFile_printf(file, "\n");
+ embFile_printf(file, "\"#\",\"General Notes:\"\n");
+ embFile_printf(file, "\"#\",\"This file can be read by Excel or LibreOffice as CSV (Comma Separated Value) or with a text editor.\"\n");
+ embFile_printf(file, "\"#\",\"Lines beginning with # are comments.\"\n");
+ embFile_printf(file, "\"#\",\"Lines beginning with > are variables: [VAR_NAME], [VAR_VALUE]\"\n");
+ embFile_printf(file, "\"#\",\"Lines beginning with $ are threads: [THREAD_NUMBER], [RED], [GREEN], [BLUE], [DESCRIPTION], [CATALOG_NUMBER]\"\n");
+ embFile_printf(file, "\"#\",\"Lines beginning with * are stitch entries: [STITCH_TYPE], [X], [Y]\"\n");
+ embFile_printf(file, "\n");
+ embFile_printf(file, "\"#\",\"Stitch Entry Notes:\"\n");
+ embFile_printf(file, "\"#\",\"STITCH instructs the machine to move to the position [X][Y] and then make a stitch.\"\n");
+ embFile_printf(file, "\"#\",\"JUMP instructs the machine to move to the position [X][Y] without making a stitch.\"\n");
+ embFile_printf(file, "\"#\",\"TRIM instructs the machine to cut the thread before moving to the position [X][Y] without making a stitch.\"\n");
+ embFile_printf(file, "\"#\",\"COLOR instructs the machine to stop temporarily so that the user can change to a different color thread before resuming.\"\n");
+ embFile_printf(file, "\"#\",\"END instructs the machine that the design is completed and there are no further instructions.\"\n");
+ embFile_printf(file, "\"#\",\"UNKNOWN encompasses instructions that may not be supported currently.\"\n");
+ embFile_printf(file, "\"#\",\"[X] and [Y] are absolute coordinates in millimeters (mm).\"\n");
+ embFile_printf(file, "\n");
+
+ /* write variables */
+ embFile_printf(file,"\"#\",\"[VAR_NAME]\",\"[VAR_VALUE]\"\n");
+ embFile_printf(file, "\">\",\"STITCH_COUNT:\",\"%u\"\n", (unsigned int)stitchCount);
+ embFile_printf(file, "\">\",\"THREAD_COUNT:\",\"%u\"\n", (unsigned int)threadCount);
+ embFile_printf(file, "\">\",\"EXTENTS_LEFT:\",\"%f\"\n", boundingRect.left);
+ embFile_printf(file, "\">\",\"EXTENTS_TOP:\",\"%f\"\n", boundingRect.top);
+ embFile_printf(file, "\">\",\"EXTENTS_RIGHT:\",\"%f\"\n", boundingRect.right);
+ embFile_printf(file, "\">\",\"EXTENTS_BOTTOM:\",\"%f\"\n", boundingRect.bottom);
+ embFile_printf(file, "\">\",\"EXTENTS_WIDTH:\",\"%f\"\n", embRect_width(boundingRect));
+ embFile_printf(file, "\">\",\"EXTENTS_HEIGHT:\",\"%f\"\n", embRect_height(boundingRect));
+ embFile_printf(file,"\n");
+
+ /* write colors */
+ embFile_printf(file, "\"#\",\"[THREAD_NUMBER]\",\"[RED]\",\"[GREEN]\",\"[BLUE]\",\"[DESCRIPTION]\",\"[CATALOG_NUMBER]\"\n");
+ i = 1;
+ while(tList)
+ {
+ embFile_printf(file, "\"$\",\"%d\",\"%d\",\"%d\",\"%d\",\"%s\",\"%s\"\n", i, /* TODO: fix segfault that backtraces here when libembroidery-convert from dst to csv. */
+ (int)tList->thread.color.r,
+ (int)tList->thread.color.g,
+ (int)tList->thread.color.b,
+ tList->thread.description,
+ tList->thread.catalogNumber);
+ i++;
+ tList = tList->next;
+ }
+ embFile_printf(file, "\n");
+
+ /* write stitches */
+ embFile_printf(file, "\"#\",\"[STITCH_TYPE]\",\"[X]\",\"[Y]\"\n");
+ while(sList)
+ {
+ EmbStitch s = sList->stitch;
+ embFile_printf(file, "\"*\",\"%s\",\"%f\",\"%f\"\n", csvStitchFlagToStr(s.flags), s.xx, s.yy);
+ sList = sList->next;
+ }
+
+ embFile_close(file);
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-csv.h b/Software/Visual_Studio/Embroidery/libembroidery/format-csv.h
new file mode 100644
index 000000000..e7bd1114c
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-csv.h
@@ -0,0 +1,39 @@
+/*! @file format-csv.h */
+#ifndef FORMAT_CSV_H
+#define FORMAT_CSV_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{
+ CSV_EXPECT_NULL,
+ CSV_EXPECT_QUOTE1,
+ CSV_EXPECT_QUOTE2,
+ CSV_EXPECT_COMMA
+} CSV_EXPECT;
+
+typedef enum
+{
+ CSV_MODE_NULL,
+ CSV_MODE_COMMENT,
+ CSV_MODE_VARIABLE,
+ CSV_MODE_THREAD,
+ CSV_MODE_STITCH
+} CSV_MODE;
+
+extern EMB_PRIVATE int EMB_CALL readCsv(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeCsv(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_CSV_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-dat.c b/Software/Visual_Studio/Embroidery/libembroidery/format-dat.c
new file mode 100644
index 000000000..3858f4f4f
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-dat.c
@@ -0,0 +1,90 @@
+#include "format-dat.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readDat(EmbPattern* pattern, const char* fileName)
+{
+ int fileLength, stitchesRemaining;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-dat.c readDat(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-dat.c readDat(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-dat.c readDat(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embPattern_loadExternalColorFile(pattern, fileName);
+ embFile_seek(file, 0x00, SEEK_END);
+ fileLength = embFile_tell(file);
+ embFile_seek(file, 0x02, SEEK_SET);
+ stitchesRemaining = binaryReadUInt16(file);
+ embFile_seek(file, 0x100, SEEK_SET);
+
+ while(embFile_tell(file) < fileLength)
+ {
+ int b1 = (int)binaryReadUInt8(file);
+ int b2 = (int)binaryReadUInt8(file);
+ unsigned char b0 = binaryReadByte(file);
+
+ int stitchType = NORMAL;
+ stitchesRemaining--;
+
+ if((b0 & 0x02) == 0) stitchType = TRIM;
+
+ if(b0 == 0x87)
+ {
+ stitchType = STOP;
+ }
+ if(b0 == 0xF8)
+ {
+ break;
+ }
+ if(b1 >= 0x80)
+ {
+ b1 = -(b1 & 0x7F);
+ }
+ if(b2 >= 0x80)
+ {
+ b2 = -(b2 & 0x7F);
+ }
+ embPattern_addStitchRel(pattern, b1 / 10.0, b2 / 10.0, stitchType, 1);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeDat(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-dat.c writeDat(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-dat.c writeDat(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-dat.c writeDat(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writeDat */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-dat.h b/Software/Visual_Studio/Embroidery/libembroidery/format-dat.h
new file mode 100644
index 000000000..aa3635a10
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-dat.h
@@ -0,0 +1,22 @@
+/*! @file format-dat.h */
+#ifndef FORMAT_DAT_H
+#define FORMAT_DAT_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readDat(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeDat(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_DAT_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-dem.c b/Software/Visual_Studio/Embroidery/libembroidery/format-dem.c
new file mode 100644
index 000000000..3b6f69af4
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-dem.c
@@ -0,0 +1,35 @@
+#include "format-dem.h"
+#include "emb-logging.h"
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readDem(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-dem.c readDem(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-dem.c readDem(), fileName argument is null\n"); return 0; }
+ return 0; /*TODO: finish readDem */
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeDem(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-dem.c writeDem(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-dem.c writeDem(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-dem.c writeDem(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writeDem */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-dem.h b/Software/Visual_Studio/Embroidery/libembroidery/format-dem.h
new file mode 100644
index 000000000..d6bb03248
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-dem.h
@@ -0,0 +1,22 @@
+/*! @file format-dem.h */
+#ifndef FORMAT_DEM_H
+#define FORMAT_DEM_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readDem(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeDem(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_DEM_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-dsb.c b/Software/Visual_Studio/Embroidery/libembroidery/format-dsb.c
new file mode 100644
index 000000000..681c08608
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-dsb.c
@@ -0,0 +1,87 @@
+#include "format-dsb.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-misc.h"
+#include <stdlib.h>
+#include <math.h>
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readDsb(EmbPattern* pattern, const char* fileName)
+{
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-dsb.c readDsb(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-dsb.c readDsb(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName,"rb");
+ if(!file)
+ {
+ embLog_error("format-dsb.c readDsb(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embPattern_loadExternalColorFile(pattern, fileName);
+ /*TODO: READ 512 BYTE HEADER INTO header[] */
+ /*
+ for(i = 0; i < 512; i++)
+ {
+ header[i] = embFile_getc(file);
+ }
+ */
+ embFile_seek(file, 0x200, SEEK_SET);
+ while(1)
+ {
+ int x, y;
+ unsigned char ctrl;
+ int stitchType = NORMAL;
+
+ ctrl =(unsigned char)embFile_getc(file);
+ if(embFile_eof(file)) break;
+ y = embFile_getc(file);
+ if(embFile_eof(file)) break;
+ x = embFile_getc(file);
+ if(embFile_eof(file)) break;
+ if(ctrl & 0x01) stitchType = TRIM;
+ if(ctrl & 0x20) x = -x;
+ if(ctrl & 0x40) y = -y;
+ /* ctrl & 0x02 - Speed change? */ /* TODO: review this line */
+ /* ctrl & 0x04 - Clutch? */ /* TODO: review this line */
+ if((ctrl & 0x05) == 0x05)
+ {
+ stitchType = STOP;
+ }
+ if(ctrl == 0xF8 || ctrl == 0x91 || ctrl == 0x87)
+ {
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+ break;
+ }
+ embPattern_addStitchRel(pattern, x / 10.0, y / 10.0, stitchType, 1);
+ }
+ embFile_close(file);
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeDsb(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-dsb.c writeDsb(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-dsb.c writeDsb(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-dsb.c writeDsb(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writeDsb */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-dsb.h b/Software/Visual_Studio/Embroidery/libembroidery/format-dsb.h
new file mode 100644
index 000000000..91836ed06
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-dsb.h
@@ -0,0 +1,22 @@
+/*! @file format-dsb.h */
+#ifndef FORMAT_DSB_H
+#define FORMAT_DSB_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readDsb(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeDsb(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_DSB_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-dst.c b/Software/Visual_Studio/Embroidery/libembroidery/format-dst.c
new file mode 100644
index 000000000..70232353f
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-dst.c
@@ -0,0 +1,505 @@
+/* .DST (Tajima) embroidery file read/write routines
+ * Format comments are thanks to tspilman@dalcoathletic.com who's
+ * notes appeared at http://www.wotsit.org under Tajima Format.
+ */
+
+#include "format-dst.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+#include "helpers-misc.h"
+#include <math.h>
+#include <string.h>
+#include <stdlib.h>
+
+static int decode_record_flags(unsigned char b2)
+{
+ int returnCode = 0;
+ if(b2 == 0xF3)
+ {
+ return END;
+ }
+ if(b2 & 0x80)
+ {
+ returnCode |= JUMP;
+ }
+ if(b2 & 0x40)
+ {
+ returnCode |= STOP;
+ }
+ return returnCode;
+}
+
+static unsigned char setbit(int pos)
+{
+ return (unsigned char)(1 << pos);
+}
+
+/* TODO: review this then remove since emb-pattern.c has a similar function */
+/* void combineJumpStitches(EmbPattern* p, int jumpsPerTrim)
+{
+ if(!p) { embLog_error("format-dst.c combineJumpStitches(), p argument is null\n"); return; }
+ EmbStitchList* pointer = p->stitchList;
+ int jumpCount = 0;
+ EmbStitchList* jumpListStart = 0;
+ char needleDown = 0;
+ while(pointer)
+ {
+ if((pointer->stitch.flags & JUMP) && !(pointer->stitch.flags & STOP))
+ {
+ if(jumpCount == 0)
+ {
+ jumpListStart = pointer;
+ }
+ jumpCount++;
+ if(needleDown && jumpCount >= jumpsPerTrim)
+ {
+ EmbStitchList* removePointer = jumpListStart->next;
+ jumpListStart->stitch.xx = pointer->stitch.xx;
+ jumpListStart->stitch.yy = pointer->stitch.yy;
+ jumpListStart->stitch.flags |= TRIM;
+ jumpListStart->next = pointer;
+
+ jumpCount-=2;
+ for(; jumpCount > 0; jumpCount--)
+ {
+ EmbStitchList* tempPointer = removePointer->next;
+ jumpListStart->stitch.flags |= removePointer->stitch.flags;
+ free(removePointer);
+ removePointer = 0;
+ removePointer = tempPointer;
+ }
+ jumpCount = 0;
+ needleDown = 0;
+ }
+ }
+ else
+ {
+ if(pointer->stitch.flags == NORMAL)
+ {
+ needleDown = 1;
+ jumpCount = 0;
+ }
+ }
+ pointer = pointer->next;
+ }
+}
+*/
+
+static void encode_record(EmbFile* file, int x, int y, int flags)
+{
+ char b0, b1, b2;
+ b0 = b1 = b2 = 0;
+
+ /* cannot encode values > +121 or < -121. */
+ if(x > 121 || x < -121) embLog_error("format-dst.c encode_record(), x is not in valid range [-121,121] , x = %d\n", x);
+ if(y > 121 || y < -121) embLog_error("format-dst.c encode_record(), y is not in valid range [-121,121] , y = %d\n", y);
+
+ if(x >= +41) { b2 += setbit(2); x -= 81; }
+ if(x <= -41) { b2 += setbit(3); x += 81; }
+ if(x >= +14) { b1 += setbit(2); x -= 27; }
+ if(x <= -14) { b1 += setbit(3); x += 27; }
+ if(x >= +5) { b0 += setbit(2); x -= 9; }
+ if(x <= -5) { b0 += setbit(3); x += 9; }
+ if(x >= +2) { b1 += setbit(0); x -= 3; }
+ if(x <= -2) { b1 += setbit(1); x += 3; }
+ if(x >= +1) { b0 += setbit(0); x -= 1; }
+ if(x <= -1) { b0 += setbit(1); x += 1; }
+ if(x != 0) { embLog_error("format-dst.c encode_record(), x should be zero yet x = %d\n", x); }
+ if(y >= +41) { b2 += setbit(5); y -= 81; }
+ if(y <= -41) { b2 += setbit(4); y += 81; }
+ if(y >= +14) { b1 += setbit(5); y -= 27; }
+ if(y <= -14) { b1 += setbit(4); y += 27; }
+ if(y >= +5) { b0 += setbit(5); y -= 9; }
+ if(y <= -5) { b0 += setbit(4); y += 9; }
+ if(y >= +2) { b1 += setbit(7); y -= 3; }
+ if(y <= -2) { b1 += setbit(6); y += 3; }
+ if(y >= +1) { b0 += setbit(7); y -= 1; }
+ if(y <= -1) { b0 += setbit(6); y += 1; }
+ if(y != 0) { embLog_error("format-dst.c encode_record(), y should be zero yet y = %d\n", y); }
+
+ b2 |= (char) 3;
+
+ if(flags & END)
+ {
+ b2 = (char) -13;
+ b0 = b1 = (char) 0;
+ }
+
+ /* if(flags & TRIM)
+ {
+ int v = 5;
+ int dx = (int)(x/v), dy = (int)(y/v);
+ for(i = 1; i < v; i++)
+ {
+ encode_record(file, dx, dy, JUMP);
+ }
+ encode_record(file, x - (dx * (v - 1)), y - (dy * (v - 1)), JUMP);
+ return;
+ } */
+ if(flags & (JUMP | TRIM))
+ {
+ b2 = (char) (b2 | 0x83);
+ }
+ if(flags & STOP)
+ {
+ b2 = (char) (b2 | 0xC3);
+ }
+
+ binaryWriteByte(file, (unsigned char)b0);
+ binaryWriteByte(file, (unsigned char)b1);
+ binaryWriteByte(file, (unsigned char)b2);
+}
+
+/*convert 2 characters into 1 int for case statement */
+/*#define cci(s) (s[0]*256+s[1]) */
+#define cci(c1,c2) (c1*256+c2)
+
+static void set_dst_variable(EmbPattern* pattern, char* var, char* val)
+{
+ unsigned int i;
+ EmbThread t;
+
+ for(i = 0; i <= (unsigned int)strlen(var); i++)
+ {
+ /* uppercase the var */
+ if(var[i] >= 'a' && var[i] <= 'z')
+ {
+ var[i] += 'A' - 'a';
+ }
+ }
+
+ /* macro converts 2 characters to 1 int, allows case statement... */
+ switch(cci(var[0],var[1]))
+ {
+ case cci('L','A'): /* Design Name (LA) */
+ /*pattern->set_variable("Design_Name",val); TODO: review this line. */
+ break;
+ case cci('S','T'): /* Stitch count, 7 digits padded by leading 0's */
+ case cci('C','O'): /* Color change count, 3 digits padded by leading 0's */
+ case cci('+','X'): /* Design extents (+/-X,+/-Y), 5 digits padded by leading 0's */
+ case cci('-','X'):
+ case cci('+','Y'):
+ case cci('-','Y'):
+ /* don't store these variables, they are recalculated at save */
+ break;
+ case cci('A','X'): /* Relative coordinates of last point, 6 digits, padded with leading spaces, first char may be +/- */
+ case cci('A','Y'):
+ case cci('M','X'): /* Coordinates of last point in previous file of multi-volume design, 6 digits, padded with leading spaces, first char may be +/- */
+ case cci('M','Y'):
+ /* store these variables as-is, they will be converted to numbers and back at save; */
+ /*pattern->set_variable(var,val); TODO: review this line. */
+ break;
+ case cci('P','D'):
+ /* store this string as-is, it will be saved as-is, 6 characters */
+ if(strlen(val) != 6)
+ {
+ /*pattern->messages.add("Warning: in DST file read, PD is not 6 characters, but ",(int)strlen(val)); */
+ }
+ /*pattern->set_variable(var,val);*/
+ break;
+ /* Begin extended fields section */
+ case cci('A','U'): /* Author string, arbitrary length */
+ case cci('C','P'): /* Copyright string, arbitrary length */
+ /*pattern->set_variable(var,val); TODO: review this line. */
+ break;
+ case cci('T','C'): /*Thread Color: #RRGGBB,Description,Catalog Number (1st field RGB hex values, 2nd&3rd fields optional arbitrary length) */
+ /* TODO: review these lines below.
+ description=split_cell_str(val,2);
+ catalog_number=split_cell_str(val,3);
+ */
+ t.color = embColor_fromHexStr(val);
+ t.description = "";
+ t.catalogNumber = "";
+ embPattern_addThread(pattern, t);
+ break;
+ default:
+ /* unknown field, just save it. */
+ /*pattern->set_variable(var,val); TODO: review this line. */
+ break;
+ }
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readDst(EmbPattern* pattern, const char* fileName)
+{
+ char var[3]; /* temporary storage variable name */
+ char val[512]; /* temporary storage variable value */
+ int valpos;
+ unsigned char b[3];
+ char header[512 + 1];
+ EmbFile* file = 0;
+ int i = 0;
+ int flags; /* for converting stitches from file encoding */
+
+ /*
+ * The header seems to contain information about the design.
+ * Seems to be ASCII text delimited by 0x0D (carriage returns).
+ * This must be in the file for most new software or hardware
+ * to consider it a good file! This is much more important
+ * than I originally believed. The header is 125 bytes in
+ * length and padded out by 0x20 to 512 bytes total.
+ * All entries in the header seem to be 2 ASCII characters
+ * followed by a colon, then it's value trailed by a carriage return.
+ *
+ * char LA[16+1]; First is the 'LA' entry, which is the design name with no
+ * path or extension information. The blank is 16 characters
+ * in total, but the name must not be longer that 8 characters
+ * and padded out with 0x20.
+ *
+ * char ST[7+1]; Next is the stitch count ST, this is a 7 digit number
+ * padded by leading zeros. This is the total stitch count
+ * including color changes, jumps, nups, and special records.
+ *
+ * char CO[3+1]; Next, is CO or colors, a 3 digit number padded by leading
+ * zeros. This is the number of color change records in the file.
+ *
+ * char POSX[5+1]; Next is +X or the positive X extent in centimeters, a 5
+ * digit non-decimal number padded by leading zeros.
+ *
+ * char NEGX[5+1]; Following is the -X or the negative X extent in millimeters,
+ * a 5 digit non-decimal number padded by leading zeros.
+ *
+ * char POSY[5+1]; Again, the +Y extents.
+ *
+ * char NEGY[5+1]; Again, the -Y extents.
+ *
+ * char AX[6+1]; AX and AY should express the relative coordinates of the
+ * char AY[6+1]; last point from the start point in 0.1 mm. If the start
+ * and last points are the same, the coordinates are (0,0).
+ *
+ * char MX[6+1]; MX and MY should express coordinates of the last point of
+ * char MY[6+1]; the previous file for a multi-volume design. A multi-
+ * volume design means a design consisted of two or more files.
+ * This was used for huge designs that can not be stored in a
+ * single paper tape roll. It is not used so much (almost
+ * never) nowadays.
+ *
+ * char PD[9+1]; PD is also storing some information for multi-volume design.
+ */
+
+ /* TODO: review commented code below
+ pattern->clear();
+ pattern->set_variable("file_name",filename);
+ */
+
+ if(!pattern) { embLog_error("format-dst.c readDst(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-dst.c readDst(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-dst.c readDst(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embPattern_loadExternalColorFile(pattern, fileName);
+ /* READ 512 BYTE HEADER INTO header[] */
+ for(i = 0; i < 512; i++)
+ {
+ header[i] = (char)embFile_getc(file);
+ }
+
+ /*TODO:It would probably be a good idea to validate file before accepting it. */
+
+ /* fill variables from header fields */
+ for(i = 0; i < 512; i++)
+ {
+ if(header[i] == ':' && i > 1)
+ {
+ var[0] = header[i - 2];
+ var[1] = header[i - 1];
+ var[2] = '\0';
+ valpos = i + 1;
+ for(i++; i < 512; i++)
+ {
+ /* don't accept : without CR because there's a bug below: i-valpos must be > 0 which is not the case if the : is before the third character. */
+ if(header[i] == 13/*||header[i]==':'*/) /* 0x0d = carriage return */
+ {
+ if(header[i] == ':') /* : indicates another variable, CR was missing! */
+ {
+ i -= 2;
+ }
+ strncpy(val, &header[valpos], (size_t)(i - valpos));
+ val[i - valpos] = '\0';
+ set_dst_variable(pattern, var, val);
+ break;
+ }
+ }
+ }
+ }
+
+ while(embFile_read(b, 1, 3, file) == 3)
+ {
+ int x = 0;
+ int y = 0;
+ if(b[0] & 0x01)
+ x += 1;
+ if(b[0] & 0x02)
+ x -= 1;
+ if(b[0] & 0x04)
+ x += 9;
+ if(b[0] & 0x08)
+ x -= 9;
+ if(b[0] & 0x80)
+ y += 1;
+ if(b[0] & 0x40)
+ y -= 1;
+ if(b[0] & 0x20)
+ y += 9;
+ if(b[0] & 0x10)
+ y -= 9;
+ if(b[1] & 0x01)
+ x += 3;
+ if(b[1] & 0x02)
+ x -= 3;
+ if(b[1] & 0x04)
+ x += 27;
+ if(b[1] & 0x08)
+ x -= 27;
+ if(b[1] & 0x80)
+ y += 3;
+ if(b[1] & 0x40)
+ y -= 3;
+ if(b[1] & 0x20)
+ y += 27;
+ if(b[1] & 0x10)
+ y -= 27;
+ if(b[2] & 0x04)
+ x += 81;
+ if(b[2] & 0x08)
+ x -= 81;
+ if(b[2] & 0x20)
+ y += 81;
+ if(b[2] & 0x10)
+ y -= 81;
+ flags = decode_record_flags(b[2]);
+ if(flags == END)
+ {
+ break;
+ }
+ embPattern_addStitchRel(pattern, x / 10.0, y / 10.0, flags, 1);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* combineJumpStitches(pattern, 5); */
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeDst(EmbPattern* pattern, const char* fileName)
+{
+ EmbRect boundingRect;
+ EmbFile* file = 0;
+ int xx, yy, dx, dy, flags;
+ int i;
+ int co = 1, st = 0;
+ int ax, ay, mx, my;
+ char* pd = 0;
+ EmbStitchList* pointer = 0;
+
+ if(!pattern) { embLog_error("format-dst.c writeDst(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-dst.c writeDst(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-dst.c writeDst(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ file = embFile_open(fileName, "wb");
+ if(!file)
+ {
+ embLog_error("format-dst.c writeDst(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+
+ embPattern_correctForMaxStitchLength(pattern, 12.1, 12.1);
+
+ xx = yy = 0;
+ co = 1;
+ co = embThreadList_count(pattern->threadList);
+ st = 0;
+ st = embStitchList_count(pattern->stitchList);
+ flags = NORMAL;
+ boundingRect = embPattern_calcBoundingBox(pattern);
+ /* TODO: review the code below
+ if(pattern->get_variable("design_name") != NULL)
+ {
+ char *la = stralloccopy(pattern->get_variable("design_name"));
+ if(strlen(la)>16) la[16]='\0';
+
+ embFile_printf(file,"LA:%-16s\x0d",la);
+ free(la);
+ }
+ else
+ {
+ */
+ embFile_printf(file, "LA:%-16s\x0d", "Untitled");
+ /*} */
+ embFile_printf(file, "ST:%7d\x0d", st);
+ embFile_printf(file, "CO:%3d\x0d", co - 1); /* number of color changes, not number of colors! */
+ embFile_printf(file, "+X:%5d\x0d", (int)(boundingRect.right * 10.0));
+ embFile_printf(file, "-X:%5d\x0d", (int)(fabs(boundingRect.left) * 10.0));
+ embFile_printf(file, "+Y:%5d\x0d", (int)(boundingRect.bottom * 10.0));
+ embFile_printf(file, "-Y:%5d\x0d", (int)(fabs(boundingRect.top) * 10.0));
+
+
+ ax = ay = mx = my = 0;
+ /* TODO: review the code below */
+ /*ax=pattern->get_variable_int("ax"); */ /* will return 0 if not defined */
+ /*ay=pattern->get_variable_int("ay"); */
+ /*mx=pattern->get_variable_int("mx"); */
+ /*my=pattern->get_variable_int("my"); */
+
+ /*pd=pattern->get_variable("pd");*/ /* will return null pointer if not defined */
+ pd = 0;
+ if(pd == 0 || strlen(pd) != 6)
+ {
+ /* pd is not valid, so fill in a default consisting of "******" */
+ pd = "******";
+ }
+ embFile_printf(file, "AX:+%5d\x0d", ax);
+ embFile_printf(file, "AY:+%5d\x0d", ay);
+ embFile_printf(file, "MX:+%5d\x0d", mx);
+ embFile_printf(file, "MY:+%5d\x0d", my);
+ embFile_printf(file, "PD:%6s\x0d", pd);
+ binaryWriteByte(file, 0x1a); /* 0x1a is the code for end of section. */
+
+ /* pad out header to proper length */
+ for(i = 125; i < 512; i++)
+ {
+ embFile_printf(file, " ");
+ }
+
+ /* write stitches */
+ xx = yy = 0;
+ pointer = pattern->stitchList;
+ while(pointer)
+ {
+ /* convert from mm to 0.1mm for file format */
+ dx = roundDouble(pointer->stitch.xx * 10.0) - xx;
+ dy = roundDouble(pointer->stitch.yy * 10.0) - yy;
+ xx = roundDouble(pointer->stitch.xx * 10.0);
+ yy = roundDouble(pointer->stitch.yy * 10.0);
+ flags = pointer->stitch.flags;
+ encode_record(file, dx, dy, flags);
+ pointer = pointer->next;
+ }
+ binaryWriteByte(file, 0xA1); /* finish file with a terminator character */
+ binaryWriteShort(file, 0);
+ embFile_close(file);
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-dst.h b/Software/Visual_Studio/Embroidery/libembroidery/format-dst.h
new file mode 100644
index 000000000..9237aa0c6
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-dst.h
@@ -0,0 +1,22 @@
+/*! @file format-dst.h */
+#ifndef FORMAT_DST_H
+#define FORMAT_DST_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readDst(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeDst(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_DST_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-dsz.c b/Software/Visual_Studio/Embroidery/libembroidery/format-dsz.c
new file mode 100644
index 000000000..2682cf31a
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-dsz.c
@@ -0,0 +1,83 @@
+#include "format-dsz.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readDsz(EmbPattern* pattern, const char* fileName)
+{
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-dsz.c readDsz(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-dsz.c readDsz(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName,"rb");
+ if(!file)
+ {
+ embLog_error("format-dsz.c readDsz(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embPattern_loadExternalColorFile(pattern, fileName);
+
+ embFile_seek(file, 0x200, SEEK_SET);
+ while(1)
+ {
+ int x, y;
+ unsigned char ctrl;
+ int stitchType = NORMAL;
+
+ y = embFile_getc(file);
+ if(embFile_eof(file)) break;
+ x = embFile_getc(file);
+ if(embFile_eof(file)) break;
+ ctrl = (unsigned char)embFile_getc(file);
+ if(embFile_eof(file)) break;
+ if(ctrl & 0x01) stitchType = TRIM;
+ if(ctrl & 0x20) y = -y;
+ if(ctrl & 0x40) x = -x;
+
+ if(ctrl & 0x0E)
+ {
+ int headNumber = (ctrl & 0x0E) >> 1;
+ stitchType = STOP;
+ }
+ if(ctrl & 0x10)
+ {
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+ break;
+ }
+ embPattern_addStitchRel(pattern, x / 10.0, y / 10.0, stitchType, 1);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeDsz(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-dsz.c writeDsz(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-dsz.c writeDsz(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-dsz.c writeDsz(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writeDsz */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-dsz.h b/Software/Visual_Studio/Embroidery/libembroidery/format-dsz.h
new file mode 100644
index 000000000..96c2adbd2
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-dsz.h
@@ -0,0 +1,22 @@
+/*! @file format-dsz.h */
+#ifndef FORMAT_DSZ_H
+#define FORMAT_DSZ_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readDsz(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeDsz(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_DSZ_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-dxf.c b/Software/Visual_Studio/Embroidery/libembroidery/format-dxf.c
new file mode 100644
index 000000000..40abb9ef3
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-dxf.c
@@ -0,0 +1,603 @@
+#include "format-dxf.h"
+#include "helpers-misc.h"
+#include "emb-hash.h"
+#include "emb-logging.h"
+
+#include "geom-arc.h"
+/*#include "geom-line.h" */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* DXF Version Identifiers */
+#define DXF_VERSION_R10 "AC1006"
+#define DXF_VERSION_R11 "AC1009"
+#define DXF_VERSION_R12 "AC1009"
+#define DXF_VERSION_R13 "AC1012"
+#define DXF_VERSION_R14 "AC1014"
+#define DXF_VERSION_R15 "AC1015"
+#define DXF_VERSION_R18 "AC1018"
+#define DXF_VERSION_R21 "AC1021"
+#define DXF_VERSION_R24 "AC1024"
+#define DXF_VERSION_R27 "AC1027"
+
+#define DXF_VERSION_2000 "AC1015"
+#define DXF_VERSION_2002 "AC1015"
+#define DXF_VERSION_2004 "AC1018"
+#define DXF_VERSION_2006 "AC1018"
+#define DXF_VERSION_2007 "AC1021"
+#define DXF_VERSION_2009 "AC1021"
+#define DXF_VERSION_2010 "AC1024"
+#define DXF_VERSION_2013 "AC1027"
+
+/* Based on the DraftSight color table */
+static const unsigned char _dxfColorTable[][3] = {
+{ 0, 0, 0 }, /* '0' (BYBLOCK) */
+{ 255, 0, 0 }, /* '1' (red) */
+{ 255, 255, 0 }, /* '2' (yellow) */
+{ 0, 255, 0 }, /* '3' (green) */
+{ 0, 255, 255 }, /* '4' (cyan) */
+{ 0, 0, 255 }, /* '5' (blue) */
+{ 255, 0, 255 }, /* '6' (magenta) */
+{ 255, 255, 255 }, /* '7' (white) */
+{ 128, 128, 128 }, /* '8' (dark gray) */
+{ 192, 192, 192 }, /* '9' (light gray) */
+{ 255, 0, 0 }, /* '10' */
+{ 255, 127, 127 }, /* '11' */
+{ 204, 0, 0 }, /* '12' */
+{ 204, 102, 102 }, /* '13' */
+{ 153, 0, 0 }, /* '14' */
+{ 153, 76, 76 }, /* '15' */
+{ 127, 0, 0 }, /* '16' */
+{ 127, 63, 63 }, /* '17' */
+{ 76, 0, 0 }, /* '18' */
+{ 76, 38, 38 }, /* '19' */
+{ 255, 63, 0 }, /* '20' */
+{ 255, 159, 127 }, /* '21' */
+{ 204, 51, 0 }, /* '22' */
+{ 204, 127, 102 }, /* '23' */
+{ 153, 38, 0 }, /* '24' */
+{ 153, 95, 76 }, /* '25' */
+{ 127, 31, 0 }, /* '26' */
+{ 127, 79, 63 }, /* '27' */
+{ 76, 19, 0 }, /* '28' */
+{ 76, 47, 38 }, /* '29' */
+{ 255, 127, 0 }, /* '30' */
+{ 255, 191, 127 }, /* '31' */
+{ 204, 102, 0 }, /* '32' */
+{ 204, 153, 102 }, /* '33' */
+{ 153, 76, 0 }, /* '34' */
+{ 153, 114, 76 }, /* '35' */
+{ 127, 63, 0 }, /* '36' */
+{ 127, 95, 63 }, /* '37' */
+{ 76, 38, 0 }, /* '38' */
+{ 76, 57, 38 }, /* '39' */
+{ 255, 191, 0 }, /* '40' */
+{ 255, 223, 127 }, /* '41' */
+{ 204, 153, 0 }, /* '42' */
+{ 204, 178, 102 }, /* '43' */
+{ 153, 114, 0 }, /* '44' */
+{ 153, 133, 76 }, /* '45' */
+{ 127, 95, 0 }, /* '46' */
+{ 127, 111, 63 }, /* '47' */
+{ 76, 57, 0 }, /* '48' */
+{ 76, 66, 38 }, /* '49' */
+{ 255, 255, 0 }, /* '50' */
+{ 255, 255, 127 }, /* '51' */
+{ 204, 204, 0 }, /* '52' */
+{ 204, 204, 102 }, /* '53' */
+{ 153, 153, 0 }, /* '54' */
+{ 153, 153, 76 }, /* '55' */
+{ 127, 127, 0 }, /* '56' */
+{ 127, 127, 63 }, /* '57' */
+{ 76, 76, 0 }, /* '58' */
+{ 76, 76, 38 }, /* '59' */
+{ 191, 255, 0 }, /* '60' */
+{ 223, 255, 127 }, /* '61' */
+{ 153, 204, 0 }, /* '62' */
+{ 178, 204, 102 }, /* '63' */
+{ 114, 153, 0 }, /* '64' */
+{ 133, 153, 76 }, /* '65' */
+{ 95, 127, 0 }, /* '66' */
+{ 111, 127, 63 }, /* '67' */
+{ 57, 76, 0 }, /* '68' */
+{ 66, 76, 38 }, /* '69' */
+{ 127, 255, 0 }, /* '70' */
+{ 191, 255, 127 }, /* '71' */
+{ 102, 204, 0 }, /* '72' */
+{ 153, 204, 102 }, /* '73' */
+{ 76, 153, 0 }, /* '74' */
+{ 114, 153, 76 }, /* '75' */
+{ 63, 127, 0 }, /* '76' */
+{ 95, 127, 63 }, /* '77' */
+{ 38, 76, 0 }, /* '78' */
+{ 57, 76, 38 }, /* '79' */
+{ 63, 255, 0 }, /* '80' */
+{ 159, 255, 127 }, /* '81' */
+{ 51, 204, 0 }, /* '82' */
+{ 127, 204, 102 }, /* '83' */
+{ 38, 153, 0 }, /* '84' */
+{ 95, 153, 76 }, /* '85' */
+{ 31, 127, 0 }, /* '86' */
+{ 79, 127, 63 }, /* '87' */
+{ 19, 76, 0 }, /* '88' */
+{ 47, 76, 38 }, /* '89' */
+{ 0, 255, 0 }, /* '90' */
+{ 127, 255, 127 }, /* '91' */
+{ 0, 204, 0 }, /* '92' */
+{ 102, 204, 102 }, /* '93' */
+{ 0, 153, 0 }, /* '94' */
+{ 76, 153, 76 }, /* '95' */
+{ 0, 127, 0 }, /* '96' */
+{ 63, 127, 63 }, /* '97' */
+{ 0, 76, 0 }, /* '98' */
+{ 38, 76, 38 }, /* '99' */
+{ 0, 255, 63 }, /* '100' */
+{ 127, 255, 159 }, /* '101' */
+{ 0, 204, 51 }, /* '102' */
+{ 102, 204, 127 }, /* '103' */
+{ 0, 153, 38 }, /* '104' */
+{ 76, 153, 95 }, /* '105' */
+{ 0, 127, 31 }, /* '106' */
+{ 63, 127, 79 }, /* '107' */
+{ 0, 76, 19 }, /* '108' */
+{ 38, 76, 47 }, /* '109' */
+{ 0, 255, 127 }, /* '110' */
+{ 127, 255, 191 }, /* '111' */
+{ 0, 204, 102 }, /* '112' */
+{ 102, 204, 153 }, /* '113' */
+{ 0, 153, 76 }, /* '114' */
+{ 76, 153, 114 }, /* '115' */
+{ 0, 127, 63 }, /* '116' */
+{ 63, 127, 95 }, /* '117' */
+{ 0, 76, 38 }, /* '118' */
+{ 38, 76, 57 }, /* '119' */
+{ 0, 255, 191 }, /* '120' */
+{ 127, 255, 223 }, /* '121' */
+{ 0, 204, 153 }, /* '122' */
+{ 102, 204, 178 }, /* '123' */
+{ 0, 153, 114 }, /* '124' */
+{ 76, 153, 133 }, /* '125' */
+{ 0, 127, 95 }, /* '126' */
+{ 63, 127, 111 }, /* '127' */
+{ 0, 76, 57 }, /* '128' */
+{ 38, 76, 66 }, /* '129' */
+{ 0, 255, 255 }, /* '130' */
+{ 127, 255, 255 }, /* '131' */
+{ 0, 204, 204 }, /* '132' */
+{ 102, 204, 204 }, /* '133' */
+{ 0, 153, 153 }, /* '134' */
+{ 76, 153, 153 }, /* '135' */
+{ 0, 127, 127 }, /* '136' */
+{ 63, 127, 127 }, /* '137' */
+{ 0, 76, 76 }, /* '138' */
+{ 38, 76, 76 }, /* '139' */
+{ 0, 191, 255 }, /* '140' */
+{ 127, 223, 255 }, /* '141' */
+{ 0, 153, 204 }, /* '142' */
+{ 102, 178, 204 }, /* '143' */
+{ 0, 114, 153 }, /* '144' */
+{ 76, 133, 153 }, /* '145' */
+{ 0, 95, 127 }, /* '146' */
+{ 63, 111, 127 }, /* '147' */
+{ 0, 57, 76 }, /* '148' */
+{ 38, 66, 76 }, /* '149' */
+{ 0, 127, 255 }, /* '150' */
+{ 127, 191, 255 }, /* '151' */
+{ 0, 102, 204 }, /* '152' */
+{ 102, 153, 204 }, /* '153' */
+{ 0, 76, 153 }, /* '154' */
+{ 76, 114, 153 }, /* '155' */
+{ 0, 63, 127 }, /* '156' */
+{ 63, 95, 127 }, /* '157' */
+{ 0, 38, 76 }, /* '158' */
+{ 38, 57, 76 }, /* '159' */
+{ 0, 63, 255 }, /* '160' */
+{ 127, 159, 255 }, /* '161' */
+{ 0, 51, 204 }, /* '162' */
+{ 102, 127, 204 }, /* '163' */
+{ 0, 38, 153 }, /* '164' */
+{ 76, 95, 153 }, /* '165' */
+{ 0, 31, 127 }, /* '166' */
+{ 63, 79, 127 }, /* '167' */
+{ 0, 19, 76 }, /* '168' */
+{ 38, 47, 76 }, /* '169' */
+{ 0, 0, 255 }, /* '170' */
+{ 127, 127, 255 }, /* '171' */
+{ 0, 0, 204 }, /* '172' */
+{ 102, 102, 204 }, /* '173' */
+{ 0, 0, 153 }, /* '174' */
+{ 76, 76, 153 }, /* '175' */
+{ 0, 0, 127 }, /* '176' */
+{ 63, 63, 127 }, /* '177' */
+{ 0, 0, 76 }, /* '178' */
+{ 38, 38, 76 }, /* '179' */
+{ 63, 0, 255 }, /* '180' */
+{ 159, 127, 255 }, /* '181' */
+{ 51, 0, 204 }, /* '182' */
+{ 127, 102, 204 }, /* '183' */
+{ 38, 0, 153 }, /* '184' */
+{ 95, 76, 153 }, /* '185' */
+{ 31, 0, 127 }, /* '186' */
+{ 79, 63, 127 }, /* '187' */
+{ 19, 0, 76 }, /* '188' */
+{ 47, 38, 76 }, /* '189' */
+{ 127, 0, 255 }, /* '190' */
+{ 191, 127, 255 }, /* '191' */
+{ 102, 0, 204 }, /* '192' */
+{ 153, 102, 204 }, /* '193' */
+{ 76, 0, 153 }, /* '194' */
+{ 114, 76, 153 }, /* '195' */
+{ 63, 0, 127 }, /* '196' */
+{ 95, 63, 127 }, /* '197' */
+{ 38, 0, 76 }, /* '198' */
+{ 57, 38, 76 }, /* '199' */
+{ 191, 0, 255 }, /* '200' */
+{ 223, 127, 255 }, /* '201' */
+{ 153, 0, 204 }, /* '202' */
+{ 178, 102, 204 }, /* '203' */
+{ 114, 0, 153 }, /* '204' */
+{ 133, 76, 153 }, /* '205' */
+{ 95, 0, 127 }, /* '206' */
+{ 111, 63, 127 }, /* '207' */
+{ 57, 0, 76 }, /* '208' */
+{ 66, 38, 76 }, /* '209' */
+{ 255, 0, 255 }, /* '210' */
+{ 255, 127, 255 }, /* '211' */
+{ 204, 0, 204 }, /* '212' */
+{ 204, 102, 204 }, /* '213' */
+{ 153, 0, 153 }, /* '214' */
+{ 153, 76, 153 }, /* '215' */
+{ 127, 0, 127 }, /* '216' */
+{ 127, 63, 127 }, /* '217' */
+{ 76, 0, 76 }, /* '218' */
+{ 76, 38, 76 }, /* '219' */
+{ 255, 0, 191 }, /* '220' */
+{ 255, 127, 223 }, /* '221' */
+{ 204, 0, 153 }, /* '222' */
+{ 204, 102, 178 }, /* '223' */
+{ 153, 0, 114 }, /* '224' */
+{ 153, 76, 133 }, /* '225' */
+{ 127, 0, 95 }, /* '226' */
+{ 127, 63, 111 }, /* '227' */
+{ 76, 0, 57 }, /* '228' */
+{ 76, 38, 66 }, /* '229' */
+{ 255, 0, 127 }, /* '230' */
+{ 255, 127, 191 }, /* '231' */
+{ 204, 0, 102 }, /* '232' */
+{ 204, 102, 153 }, /* '233' */
+{ 153, 0, 76 }, /* '234' */
+{ 153, 76, 114 }, /* '235' */
+{ 127, 0, 63 }, /* '236' */
+{ 127, 63, 95 }, /* '237' */
+{ 76, 0, 38 }, /* '238' */
+{ 76, 38, 57 }, /* '239' */
+{ 255, 0, 63 }, /* '240' */
+{ 255, 127, 159 }, /* '241' */
+{ 204, 0, 51 }, /* '242' */
+{ 204, 102, 127 }, /* '243' */
+{ 153, 0, 38 }, /* '244' */
+{ 153, 76, 95 }, /* '245' */
+{ 127, 0, 31 }, /* '246' */
+{ 127, 63, 79 }, /* '247' */
+{ 76, 0, 19 }, /* '248' */
+{ 76, 38, 47 }, /* '249' */
+{ 51, 51, 51 }, /* '250' */
+{ 91, 91, 91 }, /* '251' */
+{ 132, 132, 132 }, /* '252' */
+{ 173, 173, 173 }, /* '253' */
+{ 214, 214, 214 }, /* '254' */
+{ 255, 255, 255 }, /* '255' */
+{ 0, 0, 0 } /* '256' (BYLAYER) */
+};
+
+char* readLine(FILE* file)
+{
+ char str[255];
+ /* TODO: replace all scanf code */
+ fscanf(file, "%s", str);
+ return lTrim(str, ' ');
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readDxf(EmbPattern* pattern, const char* fileName)
+{
+
+ FILE* file = 0;
+ char* buff = "";
+
+ char* dxfVersion = "";
+ char* section = "";
+ char* tableName = "";
+ char* layerName = "";
+ char* entityType = "";
+ EmbHash* layerColorHash = 0; /* hash <layerName, EmbColor> */
+
+ int eof = 0; /* End Of File */
+
+ double bulge = 0.0, firstX = 0.0, firstY = 0.0, x = 0.0, y, prevX = 0.0, prevY = 0.0;
+ char firstStitch = 1;
+ char bulgeFlag = 0;
+ int fileLength = 0;
+ unsigned char colorNum = 0;
+
+ if(!pattern) { embLog_error("format-dxf.c readDxf(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-dxf.c readDxf(), fileName argument is null\n"); return 0; }
+
+ layerColorHash = embHash_create();
+ if(!layerColorHash) { embLog_error("format-dxf.c readDxf(), unable to allocate memory for layerColorHash\n"); return 0; }
+
+ file = fopen(fileName, "r");
+ if(!file)
+ {
+ embLog_error("format-dxf.c readDxf(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ fseek(file, 0L, SEEK_END);
+
+ fileLength = ftell(file);
+ fseek(file, 0L, SEEK_SET);
+
+ while(ftell(file) < fileLength)
+ {
+ buff = readLine(file);
+ /*printf("%s\n", buff);*/
+ if( (!strcmp(buff, "HEADER")) ||
+ (!strcmp(buff, "CLASSES")) ||
+ (!strcmp(buff, "TABLES")) ||
+ (!strcmp(buff, "BLOCKS")) ||
+ (!strcmp(buff, "ENTITIES")) ||
+ (!strcmp(buff, "OBJECTS")) ||
+ (!strcmp(buff, "THUMBNAILIMAGE")))
+ {
+ section = buff;
+ printf("SECTION:%s\n", buff);
+ }
+ if(!strcmp(buff, "ENDSEC"))
+ {
+ section = "";
+ printf("ENDSEC:%s\n", buff);
+ }
+ if( (!strcmp(buff, "ARC")) ||
+ (!strcmp(buff, "CIRCLE")) ||
+ (!strcmp(buff, "ELLIPSE")) ||
+ (!strcmp(buff, "LINE")) ||
+ (!strcmp(buff, "LWPOLYLINE")) ||
+ (!strcmp(buff, "POINT")))
+ {
+ entityType = buff;
+ }
+ if(!strcmp(buff, "EOF"))
+ {
+ eof = 1;
+ }
+
+ if(!strcmp(section, "HEADER"))
+ {
+ if(!strcmp(buff, "$ACADVER"))
+ {
+ buff = readLine(file);
+ dxfVersion = readLine(file);
+ /* TODO: Allow these versions when POLYLINE is handled. */
+ if((!strcmp(dxfVersion, DXF_VERSION_R10))
+ || (!strcmp(dxfVersion, DXF_VERSION_R11))
+ || (!strcmp(dxfVersion, DXF_VERSION_R12))
+ || (!strcmp(dxfVersion, DXF_VERSION_R13)))
+ return 0;
+ }
+ }
+ else if(!strcmp(section,"TABLES"))
+ {
+ if(!strcmp(buff,"ENDTAB"))
+ {
+ tableName = NULL;
+ }
+
+ if(tableName == NULL)
+ {
+ if(!strcmp(buff,"2")) /* Table Name */
+ {
+ tableName = readLine(file);
+ }
+ }
+ else if(!strcmp(tableName, "LAYER"))
+ {
+ /* Common Group Codes for Tables */
+ if(!strcmp(buff,"5")) /* Handle */
+ {
+ buff = readLine(file);
+ continue;
+ }
+ else if(!strcmp(buff,"330")) /* Soft Pointer */
+ {
+ buff = readLine(file);
+ continue;
+ }
+ else if(!strcmp(buff,"100")) /* Subclass Marker */
+ {
+ buff = readLine(file);
+ continue;
+ }
+ else if(!strcmp(buff,"70")) /* Number of Entries in Table */
+ {
+ buff = readLine(file);
+ continue;
+ }
+ /* The meaty stuff */
+ else if(!strcmp(buff,"2")) /* Layer Name */
+ {
+ layerName = readLine(file);
+ }
+ else if(!strcmp(buff,"62")) /* Color Number */
+ {
+ buff = readLine(file);
+ colorNum = atoi(buff);
+/*
+ TODO: finish this
+ unsigned char colorNum = atoi(buff);
+ EmbColor* co = embColor_create(_dxfColorTable[colorNum][0], _dxfColorTable[colorNum][1], _dxfColorTable[colorNum][2]);
+ if(!co) { / TODO: error allocating memory for EmbColor return 0; }
+ printf("inserting:%s,%d,%d,%d\n", layerName, co->r, co->g, co->b);
+ if(embHash_insert(layerColorHash, emb_strdup(layerName), co))
+ {
+ TODO: log error: failed inserting into layerColorHash
+ }
+*/
+ layerName = NULL;
+ }
+ }
+ }
+ else if(!strcmp(section,"ENTITIES"))
+ {
+ /* Common Group Codes for Entities */
+ if(!strcmp(buff, "5")) /* Handle */
+ {
+ buff = readLine(file);
+ continue;
+ }
+ else if(!strcmp(buff, "330")) /* Soft Pointer */
+ {
+ buff = readLine(file);
+ continue;
+ }
+ else if(!strcmp(buff, "100")) /* Subclass Marker */
+ {
+ buff = readLine(file);
+ continue;
+ }
+ else if(!strcmp(buff, "8")) /* Layer Name */
+ {
+ buff = readLine(file);
+ /* embPattern_changeColor(pattern, colorIndexMap[buff]); TODO: port to C */
+ continue;
+ }
+
+ if(!strcmp(entityType,"LWPOLYLINE"))
+ {
+ double* arcMidX = 0;
+ double* arcMidY = 0;
+ /* The not so important group codes */
+ if(!strcmp(buff, "90")) /* Vertices */
+ {
+ buff = readLine(file);
+ continue;
+ }
+ else if(!strcmp(buff,"70")) /* Polyline Flag */
+ {
+ buff = readLine(file);
+ continue;
+ }
+ /* TODO: Try to use the widths at some point */
+ else if(!strcmp(buff,"40")) /* Starting Width */
+ {
+ buff = readLine(file);
+ continue;
+ }
+ else if(!strcmp(buff,"41")) /* Ending Width */
+ {
+ buff = readLine(file);
+ continue;
+ }
+ else if(!strcmp(buff,"43")) /* Constant Width */
+ {
+ buff = readLine(file);
+ continue;
+ }
+ /* The meaty stuff */
+ else if(!strcmp(buff,"42")) /* Bulge */
+ {
+ buff = readLine(file);
+ bulge = atof(buff);
+ bulgeFlag = 1;
+ }
+ else if(!strcmp(buff,"10")) /* X */
+ {
+ buff = readLine(file);
+ x = atof(buff);
+ }
+ else if(!strcmp(buff,"20")) /* Y */
+ {
+ buff = readLine(file);
+ y = atof(buff);
+
+ if(bulgeFlag)
+ {
+ bulgeFlag = 0;
+ if(!getArcDataFromBulge(bulge, prevX, prevY, x, y, arcMidX, arcMidY, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
+ {
+ /*TODO: error */
+ return 0;
+ }
+ if(firstStitch)
+ {
+ /* embPattern_addStitchAbs(pattern, x, y, TRIM, 1); TODO: Add moveTo point to embPath pointList */
+ }
+ /* embPattern_addStitchAbs(pattern, x, y, ARC, 1); TODO: Add arcTo point to embPath pointList */
+ }
+ else
+ {
+ /*if(firstStitch) embPattern_addStitchAbs(pattern, x, y, TRIM, 1); TODO: Add moveTo point to embPath pointList */
+ /*else embPattern_addStitchAbs(pattern, x, y, NORMAL, 1); TODO: Add lineTo point to embPath pointList */
+ }
+ prevX = x;
+ prevY = y;
+ if(firstStitch)
+ {
+ firstX = x;
+ firstY = y;
+ firstStitch = 0;
+ }
+ }
+ else if(!strcmp(buff,"0"))
+ {
+ entityType = NULL;
+ firstStitch = 1;
+ if(bulgeFlag)
+ {
+ bulgeFlag = 0;
+ if(!getArcDataFromBulge(bulge, prevX, prevY, firstX, firstY, arcMidX, arcMidY, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
+ {
+ /*TODO: error */
+ return 0;
+ }
+ /* embPattern_addStitchAbs(pattern, prevX, prevY, ARC, 1); TODO: Add arcTo point to embPath pointList */
+ }
+ else
+ {
+ /* embPattern_addStitchAbs(pattern, firstX, firstY, NORMAL, 1); TODO: Add lineTo point to embPath pointList */
+ }
+ }
+ } /* end LWPOLYLINE */
+ } /* end ENTITIES section */
+ } /* end while loop */
+
+ fclose(file);
+
+ /*
+ EmbColor* testColor = 0;
+ testColor = embHash_value(layerColorHash, "OMEGA");
+ if(!testColor) printf("NULL POINTER!!!!!!!!!!!!!!\n");
+ else printf("LAYERCOLOR: %d,%d,%d\n", testColor->r, testColor->g, testColor->b);
+ */
+
+ if(!eof)
+ {
+ /* NOTE: The EOF item must be present at the end of file to be considered a valid DXF file. */
+ embLog_error("format-dxf.c readDxf(), missing EOF at end of DXF file\n");
+ }
+ return eof;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeDxf(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-dxf.c writeDxf(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-dxf.c writeDxf(), fileName argument is null\n"); return 0; }
+ return 0; /*TODO: finish writeDxf */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-dxf.h b/Software/Visual_Studio/Embroidery/libembroidery/format-dxf.h
new file mode 100644
index 000000000..2d80cd339
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-dxf.h
@@ -0,0 +1,22 @@
+/*! @file format-dxf.h */
+#ifndef FORMAT_DXF_H
+#define FORMAT_DXF_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readDxf(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeDxf(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_DXF_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-edr.c b/Software/Visual_Studio/Embroidery/libembroidery/format-edr.c
new file mode 100644
index 000000000..9c081fb4e
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-edr.c
@@ -0,0 +1,78 @@
+#include "format-edr.h"
+#include "helpers-binary.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include <stdlib.h>
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readEdr(EmbPattern* pattern, const char* fileName)
+{
+ int numberOfColors;
+ int i;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-edr.c readEdr(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-edr.c readEdr(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ /* NOTE: The .edr format is an optional color file. Do not log an error if the file does not exist */
+ return 0;
+ }
+ embFile_seek(file, 0x00, SEEK_END);
+ numberOfColors = embFile_tell(file) / 4;
+ embFile_seek(file, 0x00, SEEK_SET);
+
+ embThreadList_free(pattern->threadList);
+ pattern->threadList = 0;
+ pattern->lastThread = 0;
+
+ for(i = 0; i < numberOfColors; i++)
+ {
+ EmbThread t;
+ t.color.r = binaryReadByte(file);
+ t.color.g = binaryReadByte(file);
+ t.color.b = binaryReadByte(file);
+ t.catalogNumber = "";
+ t.description = "";
+ binaryReadByte(file);
+ embPattern_addThread(pattern, t);
+ }
+ embFile_close(file);
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeEdr(EmbPattern* pattern, const char* fileName)
+{
+ EmbThreadList* pointer = 0;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-edr.c writeEdr(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-edr.c writeEdr(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "wb");
+ if(!file)
+ {
+ embLog_error("format-edr.c writeEdr(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+ pointer = pattern->threadList;
+ while(pointer)
+ {
+ EmbColor c;
+ c = pointer->thread.color;
+ binaryWriteByte(file, c.r);
+ binaryWriteByte(file, c.g);
+ binaryWriteByte(file, c.b);
+ binaryWriteByte(file, 0);
+ pointer = pointer->next;
+ }
+ embFile_close(file);
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-edr.h b/Software/Visual_Studio/Embroidery/libembroidery/format-edr.h
new file mode 100644
index 000000000..070fe96dd
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-edr.h
@@ -0,0 +1,22 @@
+/*! @file format-edr.h */
+#ifndef FORMAT_EDR_H
+#define FORMAT_EDR_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readEdr(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeEdr(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_EDR_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-emd.c b/Software/Visual_Studio/Embroidery/libembroidery/format-emd.c
new file mode 100644
index 000000000..930a67a0d
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-emd.c
@@ -0,0 +1,107 @@
+#include "format-emd.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+
+static char emdDecode(unsigned char inputByte)
+{
+ return (inputByte >= 0x80) ? ((-~inputByte) - 1) : inputByte; /* TODO: eliminate ternary return statement */
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readEmd(EmbPattern* pattern, const char* fileName)
+{
+ unsigned char b0 = 0, b1 = 0;
+ char dx = 0, dy = 0;
+ int flags = NORMAL;
+ char endOfStream = 0;
+ unsigned char jemd0[6]; /* TODO: more descriptive name */
+ int width, height, colors;
+ int i;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-emd.c readEmd(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-emd.c readEmd(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-emd.c readEmd(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embPattern_loadExternalColorFile(pattern, fileName);
+
+ binaryReadBytes(file, jemd0, 6); /* TODO: check return value */
+ width = binaryReadInt16(file);
+ height = binaryReadInt16(file);
+ colors = binaryReadInt16(file);
+
+ embFile_seek(file, 0x30, SEEK_SET);
+
+ for(i = 0; !endOfStream; i++)
+ {
+ flags = NORMAL;
+ b0 = binaryReadUInt8(file);
+ b1 = binaryReadUInt8(file);
+
+ if(b0 == 0x80)
+ {
+ if(b1 == 0x2A)
+ {
+ embPattern_addStitchRel(pattern, 0, 0, STOP, 1);
+ continue;
+ }
+ else if(b1 == 0x80)
+ {
+ b0 = binaryReadUInt8(file);
+ b1 = binaryReadUInt8(file);
+ flags = TRIM;
+ }
+ else if(b1 == 0xFD)
+ {
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+ break;
+ }
+ else
+ {
+ continue;
+ }
+ }
+ dx = emdDecode(b0);
+ dy = emdDecode(b1);
+ embPattern_addStitchRel(pattern, dx / 10.0, dy / 10.0, flags, 1);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeEmd(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-emd.c writeEmd(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-emd.c writeEmd(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-emd.c writeEmd(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writeEmd */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-emd.h b/Software/Visual_Studio/Embroidery/libembroidery/format-emd.h
new file mode 100644
index 000000000..c16305c66
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-emd.h
@@ -0,0 +1,22 @@
+/*! @file format-emd.h */
+#ifndef FORMAT_EMD_H
+#define FORMAT_EMD_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readEmd(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeEmd(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_EMD_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-exp.c b/Software/Visual_Studio/Embroidery/libembroidery/format-exp.c
new file mode 100644
index 000000000..bd05ab387
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-exp.c
@@ -0,0 +1,192 @@
+#include "format-exp.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "emb-stitch.h"
+#include "helpers-binary.h"
+#include "helpers-misc.h"
+#include <stdio.h>
+
+static char expDecode(unsigned char a1)
+{
+ return (a1 > 0x80) ? ((-~a1) - 1) : a1;
+}
+
+static void expEncode(unsigned char* b, char dx, char dy, int flags)
+{
+ if(!b)
+ {
+ embLog_error("format-exp.c expEncode(), b argument is null\n");
+ return;
+ }
+ /* TODO: How to encode JUMP stitches? JUMP must be handled. Also check this for the KSM format since it appears to be similar */
+ if(flags == STOP)
+ {
+ b[0] = 0x80;
+ b[1] = 1;
+ b[2] = dx;
+ b[3] = dy;
+ }
+ else if (flags == END)
+ {
+ b[0] = 0x80;
+ b[1] = 0x10;
+ b[2] = 0;
+ b[3] = 0;
+ }
+ else if(flags == TRIM || flags == JUMP)
+ {
+ b[0] = 0x80;
+ b[1] = 2;
+ b[2] = dx;
+ b[3] = dy;
+ }
+ else
+ {
+ b[0] = dx;
+ b[1] = dy;
+ }
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readExp(EmbPattern* pattern, const char* fileName)
+{
+ EmbFile* file = 0;
+ int i = 0;
+ unsigned char b0 = 0, b1 = 0;
+ char dx = 0, dy = 0;
+ int flags = 0;
+
+ if(!pattern) { embLog_error("format-exp.c readExp(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-exp.c readExp(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-exp.c readExp(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+ embPattern_loadExternalColorFile(pattern, fileName);
+
+ for(i = 0; !embFile_eof(file); i++)
+ {
+ flags = NORMAL;
+ b0 = (unsigned char)embFile_getc(file);
+ if(embFile_eof(file))
+ break;
+ b1 = (unsigned char)embFile_getc(file);
+ if(embFile_eof(file))
+ break;
+ if(b0 == 0x80)
+ {
+ if(b1 & 1)
+ {
+ b0 = (unsigned char)embFile_getc(file);
+ if(embFile_eof(file))
+ break;
+ b1 = (unsigned char)embFile_getc(file);
+ if(embFile_eof(file))
+ break;
+ flags = STOP;
+ }
+ else if((b1 == 2) || (b1 == 4) || b1 == 6)
+ {
+ flags = TRIM;
+ if(b1 == 2) flags = NORMAL;
+ b0 = (unsigned char)embFile_getc(file);
+ if(embFile_eof(file))
+ break;
+ b1 = (unsigned char)embFile_getc(file);
+ if(embFile_eof(file))
+ break;
+ }
+ else if(b1 == 0x80)
+ {
+ b0 = (unsigned char)embFile_getc(file);
+ if(embFile_eof(file))
+ break;
+ b1 = (unsigned char)embFile_getc(file);
+ if(embFile_eof(file))
+ break;
+ /* Seems to be b0=0x07 and b1=0x00
+ * Maybe used as extension functions */
+ b0 = 0;
+ b1 = 0;
+ flags = TRIM;
+ }
+ }
+ dx = expDecode(b0);
+ dy = expDecode(b1);
+ embPattern_addStitchRel(pattern, dx / 10.0, dy / 10.0, flags, 1);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeExp(EmbPattern* pattern, const char* fileName)
+{
+#ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+return 0; /* ARDUINO TODO: This is temporary. Remove when complete. */
+#else /* ARDUINO TODO: This is temporary. Remove when complete. */
+
+ EmbFile* file = 0;
+ EmbStitchList* stitches = 0;
+ double dx = 0.0, dy = 0.0;
+ double xx = 0.0, yy = 0.0;
+ int flags = 0;
+ unsigned char b[4];
+
+ if(!pattern) { embLog_error("format-exp.c writeExp(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-exp.c writeExp(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-exp.c writeExp(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ file = embFile_open(fileName, "wb");
+ if(!file)
+ {
+ embLog_error("format-exp.c writeExp(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+
+ /* write stitches */
+ stitches = pattern->stitchList;
+ while(stitches)
+ {
+ dx = stitches->stitch.xx * 10.0 - xx;
+ dy = stitches->stitch.yy * 10.0 - yy;
+ xx = stitches->stitch.xx * 10.0;
+ yy = stitches->stitch.yy * 10.0;
+ flags = stitches->stitch.flags;
+ expEncode(b, (char)roundDouble(dx), (char)roundDouble(dy), flags);
+ if((b[0] == 0x80) && ((b[1] == 1) || (b[1] == 2) || (b[1] == 4) || (b[1] == 0x10)))
+ {
+ embFile_printf(file, "%c%c%c%c", b[0], b[1], b[2], b[3]);
+ }
+ else
+ {
+ embFile_printf(file, "%c%c", b[0], b[1]);
+ }
+ stitches = stitches->next;
+ }
+ embFile_printf(file, "\x1a");
+ embFile_close(file);
+ return 1;
+#endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-exp.h b/Software/Visual_Studio/Embroidery/libembroidery/format-exp.h
new file mode 100644
index 000000000..4b4b0e1c1
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-exp.h
@@ -0,0 +1,22 @@
+/*! @file format-exp.h */
+#ifndef FORMAT_EXP_H
+#define FORMAT_EXP_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readExp(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeExp(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_EXP_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-exy.c b/Software/Visual_Studio/Embroidery/libembroidery/format-exy.c
new file mode 100644
index 000000000..730f606d4
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-exy.c
@@ -0,0 +1,124 @@
+#include "format-exy.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+
+static int exyDecodeFlags(unsigned char b2)
+{
+ int returnCode = 0;
+ if(b2 == 0xF3)
+ return (END);
+ if((b2 & 0xC3) == 0xC3)
+ return TRIM | STOP;
+ if(b2 & 0x80)
+ returnCode |= TRIM;
+ if(b2 & 0x40)
+ returnCode |= STOP;
+ return returnCode;
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readExy(EmbPattern* pattern, const char* fileName)
+{
+ unsigned char b[3];
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-exy.c readExy(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-exy.c readExy(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-exy.c readExy(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embPattern_loadExternalColorFile(pattern, fileName);
+
+ embFile_seek(file, 0x100, SEEK_SET);
+
+ while(embFile_read(b, 1, 3, file) == 3)
+ {
+ int flags;
+ int x = 0;
+ int y = 0;
+ if(b[0] & 0x01)
+ x += 1;
+ if(b[0] & 0x02)
+ x -= 1;
+ if(b[0] & 0x04)
+ x += 9;
+ if(b[0] & 0x08)
+ x -= 9;
+ if(b[0] & 0x80)
+ y += 1;
+ if(b[0] & 0x40)
+ y -= 1;
+ if(b[0] & 0x20)
+ y += 9;
+ if(b[0] & 0x10)
+ y -= 9;
+ if(b[1] & 0x01)
+ x += 3;
+ if(b[1] & 0x02)
+ x -= 3;
+ if(b[1] & 0x04)
+ x += 27;
+ if(b[1] & 0x08)
+ x -= 27;
+ if(b[1] & 0x80)
+ y += 3;
+ if(b[1] & 0x40)
+ y -= 3;
+ if(b[1] & 0x20)
+ y += 27;
+ if(b[1] & 0x10)
+ y -= 27;
+ if(b[2] & 0x04)
+ x += 81;
+ if(b[2] & 0x08)
+ x -= 81;
+ if(b[2] & 0x20)
+ y += 81;
+ if(b[2] & 0x10)
+ y -= 81;
+ flags = exyDecodeFlags(b[2]);
+ if((flags & END) == END)
+ {
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+ break;
+ }
+ embPattern_addStitchRel(pattern, x / 10.0, y / 10.0, flags, 1);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeExy(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-exy.c writeExy(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-exy.c writeExy(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-exy.c writeExy(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writeExy */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-exy.h b/Software/Visual_Studio/Embroidery/libembroidery/format-exy.h
new file mode 100644
index 000000000..ee1cfc99f
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-exy.h
@@ -0,0 +1,22 @@
+/*! @file format-exy.h */
+#ifndef FORMAT_EXY_H
+#define FORMAT_EXY_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readExy(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeExy(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_EXY_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-eys.c b/Software/Visual_Studio/Embroidery/libembroidery/format-eys.c
new file mode 100644
index 000000000..f45af404e
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-eys.c
@@ -0,0 +1,35 @@
+#include "format-eys.h"
+#include "emb-logging.h"
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readEys(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-eys.c readEys(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-eys.c readEys(), fileName argument is null\n"); return 0; }
+ return 0; /*TODO: finish readEys */
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeEys(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-eys.c writeEys(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-eys.c writeEys(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-eys.c writeEys(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writeEys */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-eys.h b/Software/Visual_Studio/Embroidery/libembroidery/format-eys.h
new file mode 100644
index 000000000..b68d38755
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-eys.h
@@ -0,0 +1,22 @@
+/*! @file format-eys.h */
+#ifndef FORMAT_EYS_H
+#define FORMAT_EYS_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readEys(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeEys(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_EYS_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-fxy.c b/Software/Visual_Studio/Embroidery/libembroidery/format-fxy.c
new file mode 100644
index 000000000..60a996e73
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-fxy.c
@@ -0,0 +1,78 @@
+#include "format-fxy.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readFxy(EmbPattern* pattern, const char* fileName)
+{
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-fxy.c readFxy(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-fxy.c readFxy(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-fxy.c readFxy(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embPattern_loadExternalColorFile(pattern, fileName);
+ embFile_seek(file, 0x100, SEEK_SET); /* TODO: review for combining code. This line appears to be the only difference from the GT format. */
+
+ while(1)
+ {
+ int stitchType = NORMAL;
+ int b1 = (int)binaryReadByte(file);
+ int b2 = (int)binaryReadByte(file);
+ unsigned char commandByte = binaryReadByte(file);
+
+ if(commandByte == 0x91)
+ {
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+ break;
+ }
+ if((commandByte & 0x01) == 0x01)
+ stitchType = TRIM;
+ if((commandByte & 0x02) == 0x02)
+ stitchType = STOP;
+ if((commandByte & 0x20) == 0x20)
+ b1 = -b1;
+ if((commandByte & 0x40) == 0x40)
+ b2 = -b2;
+ embPattern_addStitchRel(pattern, b2 / 10.0, b1 / 10.0, stitchType, 1);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeFxy(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-fxy.c writeFxy(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-fxy.c writeFxy(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-fxy.c writeFxy(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writeFxy */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-fxy.h b/Software/Visual_Studio/Embroidery/libembroidery/format-fxy.h
new file mode 100644
index 000000000..9877a05a7
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-fxy.h
@@ -0,0 +1,22 @@
+/*! @file format-fxy.h */
+#ifndef FORMAT_FXY_H
+#define FORMAT_FXY_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readFxy(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeFxy(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_FXY_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-gc.c b/Software/Visual_Studio/Embroidery/libembroidery/format-gc.c
new file mode 100644
index 000000000..607310d31
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-gc.c
@@ -0,0 +1,36 @@
+/* Smoothie G-Code */
+#include "format-gc.h"
+#include "emb-logging.h"
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readGc(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-gc.c readGc(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-gc.c readGc(), fileName argument is null\n"); return 0; }
+ return 0; /*TODO: finish readGc */
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeGc(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-gc.c writeGc(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-gc.c writeGc(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-gc.c writeGc(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writeGc */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-gc.h b/Software/Visual_Studio/Embroidery/libembroidery/format-gc.h
new file mode 100644
index 000000000..8a9b1bd39
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-gc.h
@@ -0,0 +1,23 @@
+/* Smoothie G-Code */
+/*! @file format-gc.h */
+#ifndef FORMAT_GC_H
+#define FORMAT_GC_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readGc(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeGc(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_GC_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-gnc.c b/Software/Visual_Studio/Embroidery/libembroidery/format-gnc.c
new file mode 100644
index 000000000..e944331ea
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-gnc.c
@@ -0,0 +1,35 @@
+#include "format-gnc.h"
+#include "emb-logging.h"
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readGnc(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-gnc.c readGnc(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-gnc.c readGnc(), fileName argument is null\n"); return 0; }
+ return 0; /*TODO: finish readGnc */
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeGnc(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-gnc.c writeGnc(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-gnc.c writeGnc(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-gnc.c writeGnc(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writeGnc */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-gnc.h b/Software/Visual_Studio/Embroidery/libembroidery/format-gnc.h
new file mode 100644
index 000000000..b1a3474e6
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-gnc.h
@@ -0,0 +1,22 @@
+/*! @file format-gnc.h */
+#ifndef FORMAT_GNC_H
+#define FORMAT_GNC_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readGnc(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeGnc(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_GNC_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-gt.c b/Software/Visual_Studio/Embroidery/libembroidery/format-gt.c
new file mode 100644
index 000000000..659091ea1
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-gt.c
@@ -0,0 +1,78 @@
+#include "format-gt.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readGt(EmbPattern* pattern, const char* fileName)
+{
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-gt.c readGt(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-gt.c readGt(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-gt.c readGt(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embPattern_loadExternalColorFile(pattern, fileName);
+ embFile_seek(file, 0x200, SEEK_SET); /* TODO: review for combining code. This line appears to be the only difference from the FXY format. */
+
+ while(1)
+ {
+ int stitchType = NORMAL;
+ int b1 = (int)binaryReadByte(file);
+ int b2 = (int)binaryReadByte(file);
+ unsigned char commandByte = binaryReadByte(file);
+
+ if(commandByte == 0x91)
+ {
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+ break;
+ }
+ if((commandByte & 0x01) == 0x01)
+ stitchType = TRIM;
+ if((commandByte & 0x02) == 0x02)
+ stitchType = STOP;
+ if((commandByte & 0x20) == 0x20)
+ b1 = -b1;
+ if((commandByte & 0x40) == 0x40)
+ b2 = -b2;
+ embPattern_addStitchRel(pattern, b2 / 10.0, b1 / 10.0, stitchType, 1);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeGt(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-gt.c writeGt(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-gt.c writeGt(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-gt.c writeGt(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writeGt */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-gt.h b/Software/Visual_Studio/Embroidery/libembroidery/format-gt.h
new file mode 100644
index 000000000..b0695ccb4
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-gt.h
@@ -0,0 +1,22 @@
+/*! @file format-gt.h */
+#ifndef FORMAT_GT_H
+#define FORMAT_GT_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readGt(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeGt(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_GT_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-hus.c b/Software/Visual_Studio/Embroidery/libembroidery/format-hus.c
new file mode 100644
index 000000000..4710805dc
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-hus.c
@@ -0,0 +1,300 @@
+#include "format-hus.h"
+#include "emb-compress.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+#include "helpers-misc.h"
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <limits.h>
+
+/*TODO: 'husDecode' is defined but not used. Either remove it or use it. */
+/*
+static short husDecode(unsigned char a1, unsigned char a2)
+{
+ unsigned short res = (a2 << 8) + a1;
+ if(res >= 0x8000)
+ {
+ return ((-~res) - 1);
+ }
+ else
+ {
+ return (res);
+ }
+}
+*/
+
+static int husDecodeStitchType(unsigned char b)
+{
+ switch(b)
+ {
+ case 0x80:
+ return NORMAL;
+ case 0x81:
+ return JUMP;
+ case 0x84:
+ return STOP;
+ case 0x90:
+ return END;
+ default:
+ return NORMAL;
+ }
+}
+
+static unsigned char* husDecompressData(unsigned char* input, int compressedInputLength, int decompressedContentLength)
+{
+ unsigned char* decompressedData = (unsigned char*)malloc(sizeof(unsigned char)*decompressedContentLength);
+ if(!decompressedData) { embLog_error("format-hus.c husDecompressData(), cannot allocate memory for decompressedData\n"); return 0; }
+ husExpand((unsigned char*) input, decompressedData, compressedInputLength, 10);
+ return decompressedData;
+}
+
+static unsigned char* husCompressData(unsigned char* input, int decompressedInputSize, int* compressedSize)
+{
+ unsigned char* compressedData = (unsigned char*)malloc(sizeof(unsigned char)*decompressedInputSize*2);
+ if(!compressedData) { embLog_error("format-hus.c husCompressData(), cannot allocate memory for compressedData\n"); return 0; }
+ *compressedSize = husCompress(input, (unsigned long) decompressedInputSize, compressedData, 10, 0);
+ return compressedData;
+}
+
+static int husDecodeByte(unsigned char b)
+{
+ return (char)b;
+}
+
+static unsigned char husEncodeByte(double f)
+{
+ return (unsigned char)(int)roundDouble(f);
+}
+
+static unsigned char husEncodeStitchType(int st)
+{
+ switch(st)
+ {
+ case NORMAL:
+ return (0x80);
+ case JUMP:
+ case TRIM:
+ return (0x81);
+ case STOP:
+ return (0x84);
+ case END:
+ return (0x90);
+ default:
+ return (0x80);
+ }
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readHus(EmbPattern* pattern, const char* fileName)
+{
+ int fileLength;
+ int magicCode, numberOfStitches, numberOfColors;
+ int postitiveXHoopSize, postitiveYHoopSize, negativeXHoopSize, negativeYHoopSize;
+
+ int attributeOffset, xOffset, yOffset;
+ unsigned char* attributeData = 0;
+ unsigned char* attributeDataDecompressed = 0;
+
+ unsigned char* xData = 0;
+ unsigned char* xDecompressed = 0;
+
+ unsigned char* yData = 0;
+ unsigned char* yDecompressed = 0;
+ unsigned char* stringVal = 0;
+ int unknown, i = 0;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-hus.c readHus(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-hus.c readHus(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-hus.c readHus(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embFile_seek(file, 0x00, SEEK_END);
+ fileLength = embFile_tell(file);
+ embFile_seek(file, 0x00, SEEK_SET);
+
+ magicCode = binaryReadInt32(file);
+ numberOfStitches = binaryReadInt32(file);
+ numberOfColors = binaryReadInt32(file);
+
+ postitiveXHoopSize = binaryReadInt16(file);
+ postitiveYHoopSize = binaryReadInt16(file);
+ negativeXHoopSize = binaryReadInt16(file);
+ negativeYHoopSize = binaryReadInt16(file);
+
+ attributeOffset = binaryReadInt32(file);
+ xOffset = binaryReadInt32(file);
+ yOffset = binaryReadInt32(file);
+
+ stringVal = (unsigned char*)malloc(sizeof(unsigned char)*8);
+ if(!stringVal) { embLog_error("format-hus.c readHus(), cannot allocate memory for stringVal\n"); return 0; }
+ binaryReadBytes(file, stringVal, 8); /* TODO: check return value */
+
+ unknown = binaryReadInt16(file);
+ for(i = 0; i < numberOfColors; i++)
+ {
+ int pos = binaryReadInt16(file);
+ embPattern_addThread(pattern, husThreads[pos]);
+ }
+
+ attributeData = (unsigned char*)malloc(sizeof(unsigned char)*(xOffset - attributeOffset + 1));
+ if(!attributeData) { embLog_error("format-hus.c readHus(), cannot allocate memory for attributeData\n"); return 0; }
+ binaryReadBytes(file, attributeData, xOffset - attributeOffset); /* TODO: check return value */
+ attributeDataDecompressed = husDecompressData(attributeData, xOffset - attributeOffset, numberOfStitches + 1);
+
+ xData = (unsigned char*)malloc(sizeof(unsigned char)*(yOffset - xOffset + 1));
+ if(!xData) { embLog_error("format-hus.c readHus(), cannot allocate memory for xData\n"); return 0; }
+ binaryReadBytes(file, xData, yOffset - xOffset); /* TODO: check return value */
+ xDecompressed = husDecompressData(xData, yOffset - xOffset, numberOfStitches);
+
+ yData = (unsigned char*)malloc(sizeof(unsigned char)*(fileLength - yOffset + 1));
+ if(!yData) { embLog_error("format-hus.c readHus(), cannot allocate memory for yData\n"); return 0; }
+ binaryReadBytes(file, yData, fileLength - yOffset); /* TODO: check return value */
+ yDecompressed = husDecompressData(yData, fileLength - yOffset, numberOfStitches);
+
+ for(i = 0; i < numberOfStitches; i++)
+ {
+ embPattern_addStitchRel(pattern,
+ husDecodeByte(xDecompressed[i]) / 10.0,
+ husDecodeByte(yDecompressed[i]) / 10.0,
+ husDecodeStitchType(attributeDataDecompressed[i]), 1);
+ }
+
+ if(stringVal) { free(stringVal); stringVal = 0; }
+ if(xData) { free(xData); xData = 0; }
+ if(xDecompressed) { free(xDecompressed); xDecompressed = 0; }
+ if(yData) { free(yData); yData = 0; }
+ if(yDecompressed) { free(yDecompressed); yDecompressed = 0; }
+ if(attributeData) { free(attributeData); attributeData = 0; }
+ if(attributeDataDecompressed) { free(attributeDataDecompressed); attributeDataDecompressed = 0; }
+
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeHus(EmbPattern* pattern, const char* fileName)
+{
+ EmbRect boundingRect;
+ int stitchCount, minColors, patternColor;
+ int attributeSize = 0;
+ int xCompressedSize = 0;
+ int yCompressedSize = 0;
+ double previousX = 0;
+ double previousY = 0;
+ unsigned char* xValues = 0, *yValues = 0, *attributeValues = 0;
+ EmbStitchList* pointer = 0;
+ double xx = 0.0;
+ double yy = 0.0;
+ int flags = 0;
+ int i = 0;
+ unsigned char* attributeCompressed = 0, *xCompressed = 0, *yCompressed = 0;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-hus.c writeHus(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-hus.c writeHus(), fileName argument is null\n"); return 0; }
+
+ stitchCount = embStitchList_count(pattern->stitchList);
+ if(!stitchCount)
+ {
+ embLog_error("format-hus.c writeHus(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ {
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+ stitchCount++;
+ }
+
+ file = embFile_open(fileName, "wb");
+ if(!file)
+ {
+ embLog_error("format-hus.c writeHus(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+
+ /* embPattern_correctForMaxStitchLength(pattern, 0x7F, 0x7F); */
+ minColors = embThreadList_count(pattern->threadList);
+ patternColor = minColors;
+ if(minColors > 24) minColors = 24;
+ binaryWriteUInt(file, 0x00C8AF5B);
+ binaryWriteUInt(file, stitchCount);
+ binaryWriteUInt(file, minColors);
+
+ boundingRect = embPattern_calcBoundingBox(pattern);
+ binaryWriteShort(file, (short) roundDouble(boundingRect.right * 10.0));
+ binaryWriteShort(file, (short) -roundDouble(boundingRect.top * 10.0 - 1.0));
+ binaryWriteShort(file, (short) roundDouble(boundingRect.left * 10.0));
+ binaryWriteShort(file, (short) -roundDouble(boundingRect.bottom * 10.0 - 1.0));
+
+ binaryWriteUInt(file, 0x2A + 2 * minColors);
+
+ xValues = (unsigned char*)malloc(sizeof(unsigned char)*(stitchCount));
+ if(!xValues) { embLog_error("format-hus.c writeHus(), cannot allocate memory for xValues\n"); return 0; }
+ yValues = (unsigned char*)malloc(sizeof(unsigned char)*(stitchCount));
+ if(!yValues) { embLog_error("format-hus.c writeHus(), cannot allocate memory for yValues\n"); return 0; }
+ attributeValues = (unsigned char*)malloc(sizeof(unsigned char)*(stitchCount));
+ if(!attributeValues) { embLog_error("format-hus.c writeHus(), cannot allocate memory for attributeValues\n"); return 0; }
+
+ pointer = pattern->stitchList;
+ while(pointer)
+ {
+ xx = pointer->stitch.xx;
+ yy = pointer->stitch.yy;
+ flags = pointer->stitch.flags;
+ xValues[i] = husEncodeByte((xx - previousX) * 10.0);
+ previousX = xx;
+ yValues[i] = husEncodeByte((yy - previousY) * 10.0);
+ previousY = yy;
+ attributeValues[i] = husEncodeStitchType(flags);
+ pointer = pointer->next;
+ i++;
+ }
+ attributeCompressed = husCompressData(attributeValues, stitchCount, &attributeSize);
+ xCompressed = husCompressData(xValues, stitchCount, &xCompressedSize);
+ yCompressed = husCompressData(yValues, stitchCount, &yCompressedSize);
+ /* TODO: error if husCompressData returns zero? */
+
+ binaryWriteUInt(file, (unsigned int) (0x2A + 2 * patternColor + attributeSize));
+ binaryWriteUInt(file, (unsigned int) (0x2A + 2 * patternColor + attributeSize + xCompressedSize));
+ binaryWriteUInt(file, 0x00000000);
+ binaryWriteUInt(file, 0x00000000);
+ binaryWriteUShort(file, 0x0000);
+
+ for(i = 0; i < patternColor; i++)
+ {
+ binaryWriteShort(file, (short)embThread_findNearestColorInArray(embThreadList_getAt(pattern->threadList, i).color, (EmbThread*)husThreads, husThreadCount));
+ }
+
+ binaryWriteBytes(file, (char*) attributeCompressed, attributeSize);
+ binaryWriteBytes(file, (char*) xCompressed, xCompressedSize);
+ binaryWriteBytes(file, (char*) yCompressed, yCompressedSize);
+
+ free(xValues); xValues = 0;
+ free(xCompressed); xCompressed = 0;
+ free(yValues); yValues = 0;
+ free(yCompressed); yCompressed = 0;
+ free(attributeValues); attributeValues = 0;
+ free(attributeCompressed); attributeCompressed = 0;
+
+ embFile_close(file);
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-hus.h b/Software/Visual_Studio/Embroidery/libembroidery/format-hus.h
new file mode 100644
index 000000000..853a11fd6
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-hus.h
@@ -0,0 +1,61 @@
+/*! @file format-hus.h */
+#ifndef FORMAT_HUS_H
+#define FORMAT_HUS_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*****************************************
+ * EmbReaderWriter Functions
+ ****************************************/
+extern EMB_PRIVATE int EMB_CALL readHus(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeHus(EmbPattern* pattern, const char* fileName);
+
+/*****************************************
+ * HUS Colors
+ ****************************************/
+static const int husThreadCount = 29;
+static const EmbThread husThreads[] = {
+{{ 0, 0, 0 }, "Black", "TODO:HUS_CATALOG_NUMBER"},
+{{ 0, 0, 255 }, "Blue", "TODO:HUS_CATALOG_NUMBER"},
+{{ 0, 255, 0 }, "Light Green", "TODO:HUS_CATALOG_NUMBER"},
+{{ 255, 0, 0 }, "Red", "TODO:HUS_CATALOG_NUMBER"},
+{{ 255, 0, 255 }, "Purple", "TODO:HUS_CATALOG_NUMBER"},
+{{ 255, 255, 0 }, "Yellow", "TODO:HUS_CATALOG_NUMBER"},
+{{ 127, 127, 127 }, "Gray", "TODO:HUS_CATALOG_NUMBER"},
+{{ 51, 154, 255 }, "Light Blue", "TODO:HUS_CATALOG_NUMBER"},
+{{ 51, 204, 102 }, "Green", "TODO:HUS_CATALOG_NUMBER"},
+{{ 255, 127, 0 }, "Orange", "TODO:HUS_CATALOG_NUMBER"},
+{{ 255, 160, 180 }, "Pink", "TODO:HUS_CATALOG_NUMBER"},
+{{ 153, 75, 0 }, "Brown", "TODO:HUS_CATALOG_NUMBER"},
+{{ 255, 255, 255 }, "White", "TODO:HUS_CATALOG_NUMBER"},
+{{ 0, 0, 127 }, "Dark Blue", "TODO:HUS_CATALOG_NUMBER"},
+{{ 0, 127, 0 }, "Dark Green", "TODO:HUS_CATALOG_NUMBER"},
+{{ 127, 0, 0 }, "Dark Red", "TODO:HUS_CATALOG_NUMBER"},
+{{ 255, 127, 127 }, "Light Red", "TODO:HUS_CATALOG_NUMBER"},
+{{ 127, 0, 127 }, "Dark Purple", "TODO:HUS_CATALOG_NUMBER"},
+{{ 255, 127, 255 }, "Light Purple", "TODO:HUS_CATALOG_NUMBER"},
+{{ 200, 200, 0 }, "Dark Yellow", "TODO:HUS_CATALOG_NUMBER"},
+{{ 255, 255, 153 }, "Light Yellow", "TODO:HUS_CATALOG_NUMBER"},
+{{ 60, 60, 60 }, "Dark Gray", "TODO:HUS_CATALOG_NUMBER"},
+{{ 192, 192, 192 }, "Light Gray", "TODO:HUS_CATALOG_NUMBER"},
+{{ 232, 63, 0 }, "Dark Orange", "TODO:HUS_CATALOG_NUMBER"},
+{{ 255, 165, 65 }, "Light Orange", "TODO:HUS_CATALOG_NUMBER"},
+{{ 255, 102, 122 }, "Dark Pink", "TODO:HUS_CATALOG_NUMBER"},
+{{ 255, 204, 204 }, "Light Pink", "TODO:HUS_CATALOG_NUMBER"},
+{{ 115, 40, 0 }, "Dark Brown", "TODO:HUS_CATALOG_NUMBER"},
+{{ 175, 90, 10 }, "Light Brown", "TODO:HUS_CATALOG_NUMBER"}
+};
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_HUS_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-inb.c b/Software/Visual_Studio/Embroidery/libembroidery/format-inb.c
new file mode 100644
index 000000000..13b5d00be
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-inb.c
@@ -0,0 +1,115 @@
+#include "format-inb.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readInb(EmbPattern* pattern, const char* fileName)
+{
+ EmbFile* file = 0;
+ unsigned char fileDescription[8];
+ unsigned char nullVal;
+ int stitchCount;
+ short width;
+ short height;
+ short colorCount;
+ short unknown3;
+ short unknown2;
+ short imageWidth;
+ short imageHeight;
+ unsigned char bytesUnknown[300]; /* TODO: determine what this represents */
+ short nullbyte;
+ short left;
+ short right;
+ short top;
+ short bottom;
+ int x = 0;
+ int y = 0;
+ int i;
+ int fileLength;
+
+ if(!pattern) { embLog_error("format-inb.c readInb(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-inb.c readInb(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-inb.c readInb(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embPattern_loadExternalColorFile(pattern, fileName);
+ embFile_seek(file, 0, SEEK_END);
+ fileLength = embFile_tell(file);
+ binaryReadBytes(file, fileDescription, 8); /* TODO: check return value */
+ nullVal = binaryReadByte(file);
+ binaryReadInt16(file);
+ stitchCount = binaryReadInt32(file);
+ width = binaryReadInt16(file);
+ height = binaryReadInt16(file);
+ colorCount = binaryReadInt16(file);
+ unknown3 = binaryReadInt16(file);
+ unknown2 = binaryReadInt16(file);
+ imageWidth = binaryReadInt16(file);
+ imageHeight = binaryReadInt16(file);
+ binaryReadBytes(file, bytesUnknown, 300); /* TODO: check return value */
+ nullbyte = binaryReadInt16(file);
+ left = binaryReadInt16(file);
+ right = binaryReadInt16(file);
+ top = binaryReadInt16(file);
+ bottom = binaryReadInt16(file);
+ embFile_seek(file, 0x2000, SEEK_SET);
+ /* Calculate stitch count since header has been seen to be blank */
+ stitchCount = (int)((fileLength - 0x2000) / 3);
+ for(i = 0; i < stitchCount; i++)
+ {
+ unsigned char type;
+ int stitch = NORMAL;
+ x = binaryReadByte(file);
+ y = binaryReadByte(file);
+ type = binaryReadByte(file);
+ if((type & 0x40) > 0)
+ x = -x;
+ if((type & 0x10) > 0)
+ y = -y;
+ if((type & 1) > 0)
+ stitch = STOP;
+ if((type & 2) > 0)
+ stitch = TRIM;
+ embPattern_addStitchRel(pattern, x / 10.0, y / 10.0, stitch, 1);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ embPattern_flipVertical(pattern);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeInb(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-inb.c writeInb(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-inb.c writeInb(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-inb.c writeInb(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writeInb */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-inb.h b/Software/Visual_Studio/Embroidery/libembroidery/format-inb.h
new file mode 100644
index 000000000..a9a66fbe9
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-inb.h
@@ -0,0 +1,22 @@
+/*! @file format-inb.h */
+#ifndef FORMAT_INB_H
+#define FORMAT_INB_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readInb(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeInb(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_INB_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-inf.c b/Software/Visual_Studio/Embroidery/libembroidery/format-inf.c
new file mode 100644
index 000000000..d6de545f2
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-inf.c
@@ -0,0 +1,106 @@
+#include "format-inf.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+#include <stdlib.h>
+#include <string.h>
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readInf(EmbPattern* pattern, const char* fileName)
+{
+ int numberOfColors;
+ int i;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-inf.c readInf(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-inf.c readInf(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ /* NOTE: The .inf format is an optional color file. Do not log an error if the file does not exist */
+ return 0;
+ }
+
+ binaryReadUInt32BE(file);
+ binaryReadUInt32BE(file);
+ binaryReadUInt32BE(file);
+ numberOfColors = binaryReadUInt32BE(file);
+
+ embThreadList_free(pattern->threadList);
+ pattern->threadList = 0;
+ pattern->lastThread = 0;
+
+ for(i = 0; i < numberOfColors; i++)
+ {
+ char colorType[50];
+ char colorDescription[50];
+ EmbThread t;
+ binaryReadUInt16(file);
+ binaryReadUInt16(file);
+ t.color.r = binaryReadByte(file);
+ t.color.g = binaryReadByte(file);
+ t.color.b = binaryReadByte(file);
+ t.catalogNumber = "";
+ t.description = "";
+ embPattern_addThread(pattern, t);
+ binaryReadUInt16(file);
+ binaryReadString(file, colorType, 50);
+ binaryReadString(file, colorDescription, 50);
+ }
+ embFile_close(file);
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeInf(EmbPattern* pattern, const char* fileName)
+{
+ EmbThreadList* pointer = 0;
+ int i = 1, bytesRemaining;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-inf.c writeInf(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-inf.c writeInf(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "wb");
+ if(!file)
+ {
+ embLog_error("format-inf.c writeInf(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+ binaryWriteUIntBE(file, 0x01);
+ binaryWriteUIntBE(file, 0x08);
+ /* write place holder offset */
+ binaryWriteUIntBE(file, 0x00);
+ binaryWriteUIntBE(file, embThreadList_count(pattern->threadList));
+
+ pointer = pattern->threadList;
+ while(pointer)
+ {
+ char buffer[50];
+ EmbColor c;
+ c = pointer->thread.color;
+ sprintf(buffer, "RGB(%d,%d,%d)", (int)c.r, (int)c.g, (int)c.b);
+ binaryWriteUShortBE(file, (unsigned short)(14 + strlen(buffer))); /* record length */
+ binaryWriteUShortBE(file, (unsigned short)i); /* record number */
+ binaryWriteByte(file, c.r);
+ binaryWriteByte(file, c.g);
+ binaryWriteByte(file, c.b);
+ binaryWriteUShortBE(file, (unsigned short)i); /* needle number */
+ binaryWriteBytes(file, "RGB\0", 4);
+ embFile_printf(file, buffer);
+ binaryWriteByte(file, 0);
+ pointer = pointer->next;
+ i++;
+ }
+ embFile_seek(file, -8, SEEK_END);
+ bytesRemaining = embFile_tell(file);
+ embFile_seek(file, 8, SEEK_SET);
+ binaryWriteUIntBE(file, bytesRemaining);
+ embFile_close(file);
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-inf.h b/Software/Visual_Studio/Embroidery/libembroidery/format-inf.h
new file mode 100644
index 000000000..70fa9e3ad
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-inf.h
@@ -0,0 +1,22 @@
+/*! @file format-inf.h */
+#ifndef FORMAT_INF_H
+#define FORMAT_INF_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readInf(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeInf(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_INF_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-jef.c b/Software/Visual_Studio/Embroidery/libembroidery/format-jef.c
new file mode 100644
index 000000000..4ca1b818b
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-jef.c
@@ -0,0 +1,400 @@
+#include "format-jef.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "emb-time.h"
+#include "helpers-binary.h"
+#include "helpers-misc.h"
+#include "emb-stitch.h"
+#include <stdio.h>
+
+#define HOOP_110X110 0
+#define HOOP_50X50 1
+#define HOOP_140X200 2
+#define HOOP_126X110 3
+#define HOOP_200X200 4
+
+static int jefGetHoopSize(int width, int height)
+{
+ if(width < 500 && height < 500) { return HOOP_50X50; }
+ if(width < 1260 && height < 1100) { return HOOP_126X110; }
+ if(width < 1400 && height < 2000) { return HOOP_140X200; }
+ if(width < 2000 && height < 2000) { return HOOP_200X200; }
+ return ((int) HOOP_110X110);
+}
+
+static char jefDecode(unsigned char inputByte)
+{
+ if(inputByte >= 0x80)
+ return (char) ((-~inputByte) - 1);
+ return ((char) inputByte);
+}
+
+static void jefSetHoopFromId(EmbPattern* pattern, int hoopCode)
+{
+ if(!pattern) { embLog_error("format-jef.c jefSetHoopFromId(), pattern argument is null\n"); return; }
+
+ switch(hoopCode)
+ {
+ case HOOP_126X110:
+ pattern->hoop.height = 126.0;
+ pattern->hoop.width = 110.0;
+ break;
+ case HOOP_50X50:
+ pattern->hoop.height = 50.0;
+ pattern->hoop.width = 50.0;
+ break;
+ case HOOP_110X110:
+ pattern->hoop.height = 110.0;
+ pattern->hoop.width = 110.0;
+ break;
+ case HOOP_140X200:
+ pattern->hoop.height = 140.0;
+ pattern->hoop.width = 200.0;
+ break;
+ case HOOP_200X200:
+ pattern->hoop.height = 200.0;
+ pattern->hoop.width = 200.0;
+ break;
+ }
+}
+
+struct hoop_padding
+{
+ int left;
+ int right;
+ int top;
+ int bottom;
+};
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readJef(EmbPattern* pattern, const char* fileName)
+{
+ int stitchOffset, formatFlags, numberOfColors, numberOfStitchBytes;
+ int hoopSize, i;
+ struct hoop_padding bounds, rectFrom110x110, rectFrom50x50, rectFrom200x140, rect_from_custom;
+ int stitchBytes;
+ char date[8], time[8];
+
+ EmbFile* file = 0;
+
+ unsigned char b0 = 0, b1 = 0;
+ char dx = 0, dy = 0;
+ int flags = 0;
+
+
+ if(!pattern) { embLog_error("format-jef.c readJef(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-jef.c readJef(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-jef.c readJef(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ stitchOffset = binaryReadInt32(file);
+ formatFlags = binaryReadInt32(file); /* TODO: find out what this means */
+
+ binaryReadBytes(file, (unsigned char*) date, 8); /* TODO: check return value */
+ binaryReadBytes(file, (unsigned char*) time, 8); /* TODO: check return value */
+ numberOfColors = binaryReadInt32(file);
+ numberOfStitchBytes = binaryReadInt32(file) * 2;
+ hoopSize = binaryReadInt32(file);
+ jefSetHoopFromId(pattern, hoopSize);
+
+ bounds.left = binaryReadInt32(file);
+ bounds.top = binaryReadInt32(file);
+ bounds.right = binaryReadInt32(file);
+ bounds.bottom = binaryReadInt32(file);
+
+ rectFrom110x110.left = binaryReadInt32(file);
+ rectFrom110x110.top = binaryReadInt32(file);
+ rectFrom110x110.right = binaryReadInt32(file);
+ rectFrom110x110.bottom = binaryReadInt32(file);
+
+ rectFrom50x50.left = binaryReadInt32(file);
+ rectFrom50x50.top = binaryReadInt32(file);
+ rectFrom50x50.right = binaryReadInt32(file);
+ rectFrom50x50.bottom = binaryReadInt32(file);
+
+ rectFrom200x140.left = binaryReadInt32(file);
+ rectFrom200x140.top = binaryReadInt32(file);
+ rectFrom200x140.right = binaryReadInt32(file);
+ rectFrom200x140.bottom = binaryReadInt32(file);
+
+ rect_from_custom.left = binaryReadInt32(file);
+ rect_from_custom.top = binaryReadInt32(file);
+ rect_from_custom.right = binaryReadInt32(file);
+ rect_from_custom.bottom = binaryReadInt32(file);
+
+ for(i = 0; i < numberOfColors; i++)
+ {
+ embPattern_addThread(pattern, jefThreads[binaryReadInt32(file) % 79]);
+ }
+ embFile_seek(file, stitchOffset, SEEK_SET);
+ stitchBytes = 0;
+ while(stitchBytes < numberOfStitchBytes)
+ {
+ flags = NORMAL;
+ b0 = (unsigned char)embFile_getc(file);
+ if(embFile_eof(file))
+ {
+ break;
+ }
+ b1 = (unsigned char)embFile_getc(file);
+ if(embFile_eof(file))
+ {
+ break;
+ }
+ stitchBytes += 2;
+ if(b0 == 0x80)
+ {
+ if(b1 & 1)
+ {
+ b0 = (unsigned char)embFile_getc(file);
+ if(embFile_eof(file))
+ break;
+ b1 = (unsigned char)embFile_getc(file);
+ if(embFile_eof(file))
+ break;
+ stitchBytes += 2;
+ flags = STOP;
+ }
+ else if((b1 == 2) || (b1 == 4) || b1 == 6)
+ {
+ flags = TRIM;
+ b0 = (unsigned char)embFile_getc(file);
+ if (embFile_eof(file))
+ {
+ break;
+ }
+ b1 = (unsigned char)embFile_getc(file);
+ if (embFile_eof(file))
+ {
+ break;
+ }
+ stitchBytes += 2;
+ }
+ else if(b1 == 0x10)
+ {
+ embPattern_addStitchRel(pattern, 0.0, 0.0, END, 1);
+ stitchBytes += 1;
+ break;
+ }
+ }
+ dx = jefDecode(b0);
+ dy = jefDecode(b1);
+ embPattern_addStitchRel(pattern, dx / 10.0, dy / 10.0, flags, 1);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if (pattern->lastStitch->stitch.flags != END)
+ {
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+ }
+ return 1;
+}
+
+static void jefEncode(unsigned char* b, char dx, char dy, int flags)
+{
+ if(!b)
+ {
+ embLog_error("format-jef.c expEncode(), b argument is null\n");
+ return;
+ }
+ if(flags == STOP)
+ {
+ b[0] = 0x80;
+ b[1] = 1;
+ b[2] = dx;
+ b[3] = dy;
+ }
+ else if (flags == END)
+ {
+ b[0] = 0x80;
+ b[1] = 0x10;
+ b[2] = 0;
+ b[3] = 0;
+ }
+ else if(flags == TRIM)
+ {
+ b[0] = 0x80;
+ b[1] = 2;
+ b[2] = dx;
+ b[3] = dy;
+ }
+ else if (flags == JUMP)
+ {
+ b[0] = 0x80;
+ b[1] = 4;
+ b[2] = dx;
+ b[3] = dy;
+ }
+ else
+ {
+ b[0] = dx;
+ b[1] = dy;
+ }
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeJef(EmbPattern* pattern, const char* fileName)
+{
+ int colorlistSize, designWidth, designHeight, i, jumpAndStopCount;
+ EmbRect boundingRect;
+ EmbFile* file = 0;
+ EmbTime time;
+ EmbThreadList* threadPointer = 0;
+ EmbStitchList* stitches = 0;
+ double dx = 0.0, dy = 0.0;
+ double xx = 0.0, yy = 0.0;
+ int flags = 0;
+ unsigned char b[4];
+
+ if(!pattern) { embLog_error("format-jef.c writeJef(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-jef.c writeJef(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-jef.c writeJef(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if (pattern->lastStitch->stitch.flags != END)
+ {
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+ }
+ file = embFile_open(fileName, "wb");
+ if(!file)
+ {
+ embLog_error("format-jef.c writeJef(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+
+ embPattern_correctForMaxStitchLength(pattern, 12.7, 12.7);
+
+ colorlistSize = embThreadList_count(pattern->threadList);
+ binaryWriteInt(file, 0x74 + (colorlistSize * 8));
+ binaryWriteInt(file, 0x14);
+
+ embTime_initNow(&time);
+
+ embFile_printf(file, "%04d%02d%02d%02d%02d%02d", (int)(time.year + 1900),
+ (int)(time.month + 1), (int)(time.day), (int)(time.hour),
+ (int)(time.minute), (int)(time.second));
+ binaryWriteByte(file, 0x00);
+ binaryWriteByte(file, 0x00);
+ binaryWriteInt(file, embThreadList_count(pattern->threadList));
+
+ stitches = pattern->stitchList;
+ jumpAndStopCount = 0;
+ while (stitches)
+ {
+ flags = stitches->stitch.flags;
+ if ((flags & (STOP | TRIM | JUMP)) > 0) {
+ jumpAndStopCount++;
+ }
+ stitches = stitches->next;
+ }
+ binaryWriteInt(file, embStitchList_count(pattern->stitchList) + jumpAndStopCount);
+
+ boundingRect = embPattern_calcBoundingBox(pattern);
+
+ designWidth = (int)(embRect_width(boundingRect) * 10.0);
+ designHeight = (int)(embRect_height(boundingRect) * 10.0);
+
+ binaryWriteInt(file, jefGetHoopSize(designWidth, designHeight));
+
+ /* Distance from center of Hoop */
+ binaryWriteInt(file, (int) (designWidth / 2)); /* left */
+ binaryWriteInt(file, (int) (designHeight / 2)); /* top */
+ binaryWriteInt(file, (int) (designWidth / 2)); /* right */
+ binaryWriteInt(file, (int) (designHeight / 2)); /* bottom */
+
+ /* Distance from default 110 x 110 Hoop */
+ if(min(550 - designWidth / 2, 550 - designHeight / 2) >= 0)
+ {
+ binaryWriteInt(file, (int) max(-1, (1100 - designWidth) / 2)); /* left */
+ binaryWriteInt(file, (int)max(-1, (1100 - designWidth) / 2)); /* right */
+ binaryWriteInt(file, (int) max(-1, (1100 - designHeight) / 2)); /* top */
+ binaryWriteInt(file, (int) max(-1, (1100 - designHeight) / 2)); /* bottom */
+ }
+ else
+ {
+ binaryWriteInt(file, -1);
+ binaryWriteInt(file, -1);
+ binaryWriteInt(file, -1);
+ binaryWriteInt(file, -1);
+ }
+
+ /* Distance from default 50 x 50 Hoop */
+ if(min((500 - designWidth) / 2, (500 - designHeight) / 2) >= 0)
+ {
+ binaryWriteInt(file, (int) max(-1, (500 - designWidth) / 2)); /* left */
+ binaryWriteInt(file, (int)max(-1, (500 - designWidth) / 2)); /* right */
+ binaryWriteInt(file, (int) max(-1, (500 - designHeight) / 2)); /* top */
+ binaryWriteInt(file, (int) max(-1, (500 - designHeight) / 2)); /* bottom */
+ }
+ else
+ {
+ binaryWriteInt(file, -1);
+ binaryWriteInt(file, -1);
+ binaryWriteInt(file, -1);
+ binaryWriteInt(file, -1);
+ }
+
+ /* Distance from default 140 x 200 Hoop */
+ binaryWriteInt(file, (int)max(-1, ((1400 - designWidth) / 2))); /* left */
+ binaryWriteInt(file, (int)max(-1, ((2000 - designHeight) / 2))); /* top */
+ binaryWriteInt(file, (int)max(-1, ((1400 - designWidth) / 2))); /* right */
+ binaryWriteInt(file, (int)max(-1, ((2000 - designHeight) / 2))); /* bottom */
+
+ /* repeated Distance from default 140 x 200 Hoop */
+ /* TODO: Actually should be distance to custom hoop */
+ binaryWriteInt(file, (int)max(-1, ((1400 - designWidth) / 2))); /* left */
+ binaryWriteInt(file, (int)max(-1, ((2000 - designHeight) / 2))); /* top */
+ binaryWriteInt(file, (int)max(-1, ((1400 - designWidth) / 2))); /* right */
+ binaryWriteInt(file, (int)max(-1, ((2000 - designHeight) / 2))); /* bottom */
+
+ threadPointer = pattern->threadList;
+
+ while(threadPointer)
+ {
+ binaryWriteInt(file, embThread_findNearestColorInArray(threadPointer->thread.color, (EmbThread*)jefThreads, 79));
+ threadPointer = threadPointer->next;
+ }
+ for(i = 0; i < colorlistSize; i++)
+ {
+ binaryWriteInt(file, 0x0D);
+ }
+ stitches = pattern->stitchList;
+ while(stitches)
+ {
+ dx = stitches->stitch.xx * 10.0 - xx;
+ dy = stitches->stitch.yy * 10.0 - yy;
+ xx = stitches->stitch.xx * 10.0;
+ yy = stitches->stitch.yy * 10.0;
+ flags = stitches->stitch.flags;
+ jefEncode(b, (char)roundDouble(dx), (char)roundDouble(dy), flags);
+ if((b[0] == 0x80) && ((b[1] == 1) || (b[1] == 2) || (b[1] == 4)))
+ {
+ embFile_printf(file, "%c%c%c%c", b[0], b[1], b[2], b[3]);
+ }
+ else
+ {
+ embFile_printf(file, "%c%c", b[0], b[1]);
+ }
+ if (flags & END) {
+ break;
+ }
+ stitches = stitches->next;
+ }
+ embFile_close(file);
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-jef.h b/Software/Visual_Studio/Embroidery/libembroidery/format-jef.h
new file mode 100644
index 000000000..5d169b7c4
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-jef.h
@@ -0,0 +1,103 @@
+/*! @file format-jef.h */
+#ifndef FORMAT_JEF_H
+#define FORMAT_JEF_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readJef(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeJef(EmbPattern* pattern, const char* fileName);
+
+static const EmbThread jefThreads[] = {
+ {{0, 0 ,0}, "Black", ""},
+ {{0, 0, 0}, "Black", ""},
+ {{255, 255, 255}, "White", ""},
+ {{255, 255, 23}, "Yellow", ""},
+ {{250, 160, 96}, "Orange", ""},
+ {{92, 118, 73}, "Olive Green", ""},
+ {{64, 192, 48}, "Green", ""},
+ {{101, 194, 200}, "Sky", ""},
+ {{172, 128, 190}, "Purple", ""},
+ {{245, 188, 203}, "Pink", ""},
+ {{255, 0, 0}, "Red", ""},
+ {{192, 128, 0}, "Brown", ""},
+ {{0, 0, 240}, "Blue", ""},
+ {{228, 195, 93}, "Gold", ""},
+ {{165, 42, 42}, "Dark Brown", ""},
+ {{213, 176, 212}, "Pale Violet", ""},
+ {{252, 242, 148}, "Pale Yellow", ""},
+ {{240, 208, 192}, "Pale Pink", ""},
+ {{255, 192, 0}, "Peach", ""},
+ {{201, 164, 128}, "Beige", ""},
+ {{155, 61, 75}, "Wine Red", ""},
+ {{160, 184, 204}, "Pale Sky", ""},
+ {{127, 194, 28}, "Yellow Green", ""},
+ {{185, 185, 185}, "Silver Grey", ""},
+ {{160, 160, 160}, "Grey", ""},
+ {{152, 214, 189}, "Pale Aqua", ""},
+ {{184, 240, 240}, "Baby Blue", ""},
+ {{54, 139, 160}, "Powder Blue", ""},
+ {{79, 131, 171}, "Bright Blue", ""},
+ {{56, 106, 145}, "Slate Blue", ""},
+ {{0, 32, 107}, "Nave Blue", ""},
+ {{229, 197, 202}, "Salmon Pink", ""},
+ {{249, 103, 107}, "Coral", ""},
+ {{227, 49, 31}, "Burnt Orange", ""},
+ {{226, 161, 136}, "Cinnamon", ""},
+ {{181, 148, 116}, "Umber", ""},
+ {{228, 207, 153}, "Blonde", ""},
+ {{225, 203, 0}, "Sunflower", ""},
+ {{225, 173, 212}, "Orchid Pink", ""},
+ {{195, 0, 126}, "Peony Purple", ""},
+ {{128, 0, 75}, "Burgundy", ""},
+ {{160, 96, 176}, "Royal Purple", ""},
+ {{192, 64, 32}, "Cardinal Red", ""},
+ {{202, 224, 192}, "Opal Green", ""},
+ {{137, 152, 86}, "Moss Green", ""},
+ {{0, 170, 0}, "Meadow Green", ""},
+ {{33, 138, 33}, "Dark Green", ""},
+ {{93, 174, 148}, "Aquamarine", ""},
+ {{76, 191, 143}, "Emerald Green", ""},
+ {{0, 119, 114}, "Peacock Green", ""},
+ {{112, 112, 112}, "Dark Grey", ""},
+ {{242, 255, 255}, "Ivory White", ""},
+ {{177, 88, 24}, "Hazel", ""},
+ {{203, 138, 7}, "Toast", ""},
+ {{247, 146, 123}, "Salmon", ""},
+ {{152, 105, 45}, "Cocoa Brown", ""},
+ {{162, 113, 72}, "Sienna", ""},
+ {{123, 85, 74}, "Sepia", ""},
+ {{79, 57, 70}, "Dark Sepia", ""},
+ {{82, 58, 151}, "Violet Blue", ""},
+ {{0, 0, 160}, "Blue Ink", ""},
+ {{0, 150, 222}, "Solar Blue", ""},
+ {{178, 221, 83}, "Green Dust", ""},
+ {{250, 143, 187}, "Crimson", ""},
+ {{222, 100, 158}, "Floral Pink", ""},
+ {{181, 80, 102}, "Wine", ""},
+ {{94, 87, 71}, "Olive Drab", ""},
+ {{76, 136, 31}, "Meadow", ""},
+ {{228, 220, 121}, "Mustard", ""},
+ {{203, 138, 26}, "Yellow Ochre", ""},
+ {{198, 170, 66}, "Old Gold", ""},
+ {{236, 176, 44}, "Honeydew", ""},
+ {{248, 128, 64}, "Tangerine", ""},
+ {{255, 229, 5}, "Canary Yellow", ""},
+ {{250, 122, 122}, "Vermillion", ""},
+ {{107, 224, 0}, "Bright Green", ""},
+ {{56, 108, 174}, "Ocean Blue", ""},
+ {{227, 196, 180}, "Beige Grey", ""},
+ {{227, 172, 129}, "Bamboo", ""}};
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_JEF_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-ksm.c b/Software/Visual_Studio/Embroidery/libembroidery/format-ksm.c
new file mode 100644
index 000000000..043da396b
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-ksm.c
@@ -0,0 +1,136 @@
+#include "format-ksm.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+
+static void ksmEncode(unsigned char* b, char dx, char dy, int flags)
+{
+ if(!b)
+ {
+ embLog_error("format-ksm.c ksmEncode(), b argument is null\n");
+ return;
+ }
+ /* TODO: How to encode JUMP stitches? JUMP must be handled. Also check this for the EXP format since it appears to be similar */
+ if(flags == TRIM)
+ {
+ b[0] = 128;
+ b[1] = 2;
+ b[2] = dx;
+ b[3] = dy;
+ }
+ else if(flags == STOP)
+ {
+ b[0] = 128;
+ b[1] = 1;
+ b[2] = dx;
+ b[3] = dy;
+ }
+ else
+ {
+ b[0] = dx;
+ b[1] = dy;
+ }
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readKsm(EmbPattern* pattern, const char* fileName)
+{
+ int prevStitchType = NORMAL;
+ char b[3];
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-ksm.c readKsm(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-ksm.c readKsm(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-ksm.c readKsm(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embFile_seek(file, 0x200, SEEK_SET);
+
+ while(embFile_read(b, 1, 3, file) == 3)
+ {
+ int flags = NORMAL;
+
+ if(((prevStitchType & 0x08) == 0x08) && (b[2] & 0x08) == 0x08)
+ {
+ flags = STOP;
+ }
+ else if((b[2] & 0x1F) != 0)
+ {
+ flags = TRIM;
+ }
+ prevStitchType = b[2];
+ if(b[2] & 0x40)
+ b[1] = -b[1];
+ if(b[2] & 0x20)
+ b[0] = -b[0];
+ embPattern_addStitchRel(pattern, b[1] / 10.0, b[0] / 10.0, flags, 1);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeKsm(EmbPattern* pattern, const char* fileName)
+{
+ EmbFile* file = 0;
+ EmbStitchList* pointer = 0;
+ double xx = 0, yy = 0, dx = 0, dy = 0;
+ int flags = 0;
+ int i = 0;
+ unsigned char b[4];
+
+ if(!pattern) { embLog_error("format-ksm.c writeKsm(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-ksm.c writeKsm(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-ksm.c writeKsm(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ file = embFile_open(fileName, "wb");
+ if(!file)
+ {
+ embLog_error("format-ksm.c writeKsm(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+ for(i = 0; i < 0x80; i++)
+ {
+ binaryWriteInt(file, 0);
+ }
+ /* write stitches */
+ xx = yy = 0;
+ pointer = pattern->stitchList;
+ while(pointer)
+ {
+ dx = pointer->stitch.xx - xx;
+ dy = pointer->stitch.yy - yy;
+ xx = pointer->stitch.xx;
+ yy = pointer->stitch.yy;
+ flags = pointer->stitch.flags;
+ ksmEncode(b, (char)(dx * 10.0), (char)(dy * 10.0), flags);
+ embFile_printf(file, "%c%c", b[0], b[1]);
+ pointer = pointer->next;
+ }
+ embFile_printf(file, "\x1a");
+ embFile_close(file);
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-ksm.h b/Software/Visual_Studio/Embroidery/libembroidery/format-ksm.h
new file mode 100644
index 000000000..7e6fadfec
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-ksm.h
@@ -0,0 +1,22 @@
+/*! @file format-ksm.h */
+#ifndef FORMAT_KSM_H
+#define FORMAT_KSM_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readKsm(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeKsm(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_KSM_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-max.c b/Software/Visual_Studio/Embroidery/libembroidery/format-max.c
new file mode 100644
index 000000000..cc320904d
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-max.c
@@ -0,0 +1,134 @@
+#include "format-max.h"
+#include "format-pcd.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+#include "helpers-misc.h"
+
+/* Pfaff MAX embroidery file format */
+
+static double maxDecode(unsigned char a1, unsigned char a2, unsigned char a3)
+{
+ int res = a1 + (a2 << 8) + (a3 << 16);
+ if(res > 0x7FFFFF)
+ {
+ return (-((~(res) & 0x7FFFFF) - 1));
+ }
+ return res;
+}
+
+static void maxEncode(EmbFile* file, int x, int y)
+{
+ if(!file) { embLog_error("format-max.c maxEncode(), file argument is null\n"); return; }
+
+ binaryWriteByte(file, (unsigned char)0);
+ binaryWriteByte(file, (unsigned char)(x & 0xFF));
+ binaryWriteByte(file, (unsigned char)((x >> 8) & 0xFF));
+ binaryWriteByte(file, (unsigned char)((x >> 16) & 0xFF));
+
+ binaryWriteByte(file, (unsigned char)0);
+ binaryWriteByte(file, (unsigned char)(y & 0xFF));
+ binaryWriteByte(file, (unsigned char)((y >> 8) & 0xFF));
+ binaryWriteByte(file, (unsigned char)((y >> 16) & 0xFF));
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readMax(EmbPattern* pattern, const char* fileName)
+{
+ int i = 0;
+ unsigned char b[8];
+ double dx = 0, dy = 0;
+ int flags = 0;
+ int stitchCount;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-max.c readMax(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-max.c readMax(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-max.c readMax(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embFile_seek(file, 0xD5, SEEK_SET);
+ stitchCount = binaryReadUInt32(file);
+
+ /* READ STITCH RECORDS */
+ for(i = 0; i < stitchCount; i++)
+ {
+ flags = NORMAL;
+ if(embFile_read(b, 1, 8, file) != 8)
+ break;
+
+ dx = maxDecode(b[0], b[1], b[2]);
+ dy = maxDecode(b[4], b[5], b[6]);
+ embPattern_addStitchAbs(pattern, dx / 10.0, dy / 10.0, flags, 1);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ embPattern_flipVertical(pattern);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeMax(EmbPattern* pattern, const char* fileName)
+{
+ EmbFile* file = 0;
+ EmbStitchList* pointer = 0;
+ char header[] = {
+ 0x56,0x43,0x53,0x4D,0xFC,0x03,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
+ 0xF6,0x25,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x05,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x31,0x33,0x37,0x38,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4D,0x61,0x64,0x65,0x69,0x72,0x61,0x20,
+ 0x52,0x61,0x79,0x6F,0x6E,0x20,0x34,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x01,0x38,0x09,0x31,0x33,0x30,0x2F,0x37,0x30,0x35,0x20,0x48,0xFA,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00 };
+
+ if(!pattern) { embLog_error("format-max.c writeMax(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-max.c writeMax(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-max.c writeMax(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ file = embFile_open(fileName, "wb");
+ if(!file)
+ {
+ embLog_error("format-max.c writeMax(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+
+ binaryWriteBytes(file, header, 0xD5);
+ pointer = pattern->stitchList;
+ while(pointer)
+ {
+ maxEncode(file, roundDouble(pointer->stitch.xx * 10.0), roundDouble(pointer->stitch.yy * 10.0));
+ pointer = pointer->next;
+ }
+ embFile_close(file);
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-max.h b/Software/Visual_Studio/Embroidery/libembroidery/format-max.h
new file mode 100644
index 000000000..1912643b0
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-max.h
@@ -0,0 +1,22 @@
+/*! @file format-max.h */
+#ifndef FORMAT_MAX_H
+#define FORMAT_MAX_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readMax(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeMax(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_MAX_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-mit.c b/Software/Visual_Studio/Embroidery/libembroidery/format-mit.c
new file mode 100644
index 000000000..4df19a95f
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-mit.c
@@ -0,0 +1,104 @@
+#include "format-mit.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+
+static int mitDecodeStitch(unsigned char value)
+{
+ if (value & 0x80)
+ {
+ return -(value & 0x1F);
+ }
+ return value;
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readMit(EmbPattern* pattern, const char* fileName)
+{
+ unsigned char data[2];
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-mit.c readMit(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-mit.c readMit(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-mit.c readMit(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ /* embPattern_loadExternalColorFile(pattern, fileName); TODO: review this and uncomment or remove it */
+
+ while(binaryReadBytes(file, data, 2) == 2)
+ {
+ embPattern_addStitchRel(pattern, mitDecodeStitch(data[0]) / 10.0, mitDecodeStitch(data[1]) / 10.0, NORMAL, 1);
+ }
+
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+static unsigned char mitEncodeStitch(double value)
+{
+ if (value < 0)
+ {
+ return 0x80 | (unsigned char)(-value);
+ }
+ return (unsigned char)value;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeMit(EmbPattern* pattern, const char* fileName)
+{
+ EmbFile* file = 0;
+ EmbStitchList* pointer = 0;
+ double xx = 0, yy = 0, dx = 0, dy = 0;
+ int flags = 0;
+
+ if(!pattern) { embLog_error("format-mit.c writeMit(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-mit.c writeMit(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-mit.c writeMit(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if (pattern->lastStitch->stitch.flags != END)
+ {
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+ }
+ file = embFile_open(fileName, "wb");
+ if (!file)
+ {
+ embLog_error("format-mit.c writeMit(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+ embPattern_correctForMaxStitchLength(pattern, 0x1F, 0x1F);
+ xx = yy = 0;
+ pointer = pattern->stitchList;
+ while (pointer)
+ {
+ dx = pointer->stitch.xx - xx;
+ dy = pointer->stitch.yy - yy;
+ xx = pointer->stitch.xx;
+ yy = pointer->stitch.yy;
+ flags = pointer->stitch.flags;
+ embFile_putc(mitEncodeStitch(dx), file);
+ embFile_putc(mitEncodeStitch(dy), file);
+ pointer = pointer->next;
+ }
+ embFile_close(file);
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-mit.h b/Software/Visual_Studio/Embroidery/libembroidery/format-mit.h
new file mode 100644
index 000000000..51ca307c5
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-mit.h
@@ -0,0 +1,22 @@
+/*! @file format-mit.h */
+#ifndef FORMAT_MIT_H
+#define FORMAT_MIT_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readMit(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeMit(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_MIT_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-new.c b/Software/Visual_Studio/Embroidery/libembroidery/format-new.c
new file mode 100644
index 000000000..1a005f346
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-new.c
@@ -0,0 +1,100 @@
+#include "format-new.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+
+static int decodeNewStitch(unsigned char value)
+{
+ return (int)value;
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readNew(EmbPattern* pattern, const char* fileName)
+{
+ unsigned int stitchCount;
+ unsigned char data[3];
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-new.c readNew(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-new.c readNew(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-new.c readNew(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embPattern_loadExternalColorFile(pattern, fileName);
+ stitchCount = binaryReadUInt16(file);
+ while(binaryReadBytes(file, data, 3) == 3)
+ {
+ int x = decodeNewStitch(data[0]);
+ int y = decodeNewStitch(data[1]);
+ int flag = NORMAL;
+ char val = data[2];
+ if(data[2] & 0x40)
+ {
+ x = -x;
+ }
+ if(data[2] & 0x20)
+ {
+ y = -y;
+ }
+ if(data[2] & 0x10)
+ {
+ flag = TRIM;
+ }
+ if(data[2] & 0x01)
+ {
+ flag = JUMP;
+ }
+ if((val & 0x1E) == 0x02)
+ {
+ flag = STOP;
+ }
+ /* Unknown values, possibly TRIM
+ 155 = 1001 1011 = 0x9B
+ 145 = 1001 0001 = 0x91
+ */
+ /*val = (data[2] & 0x1C);
+ if(val != 0 && data[2] != 0x9B && data[2] != 0x91)
+ {
+ int z = 1;
+ }*/
+ embPattern_addStitchRel(pattern, x / 10.0, y / 10.0, flag, 1);
+ }
+
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeNew(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-new.c writeNew(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-new.c writeNew(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-new.c writeNew(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writeNew */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-new.h b/Software/Visual_Studio/Embroidery/libembroidery/format-new.h
new file mode 100644
index 000000000..426773591
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-new.h
@@ -0,0 +1,22 @@
+/*! @file format-new.h */
+#ifndef FORMAT_NEW_H
+#define FORMAT_NEW_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readNew(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeNew(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_NEW_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-ofm.c b/Software/Visual_Studio/Embroidery/libembroidery/format-ofm.c
new file mode 100644
index 000000000..e45933f07
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-ofm.c
@@ -0,0 +1,277 @@
+#include "format-ofm.h"
+#include "compound-file.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+#include <stdlib.h>
+#include <string.h>
+
+static char* ofmReadLibrary(EmbFile* file)
+{
+ int stringLength = 0;
+ char* libraryName = 0;
+ /* FF FE FF */
+ unsigned char leadIn[3];
+
+ if(!file) { embLog_error("format-ofm.c ofmReadLibrary(), file argument is null\n"); return 0; }
+
+ binaryReadBytes(file, leadIn, 3); /* TODO: check return value */
+ stringLength = binaryReadByte(file);
+ libraryName = (char*)malloc(sizeof(char) * stringLength * 2);
+ if(!libraryName) { embLog_error("format-ofm.c ofmReadLibrary(), unable to allocate memory for libraryName\n"); return 0; }
+ binaryReadBytes(file, (unsigned char*)libraryName, stringLength * 2); /* TODO: check return value */
+ return libraryName;
+}
+
+static int ofmReadClass(EmbFile* file)
+{
+ int len;
+ char* s = 0;
+
+ if(!file) { embLog_error("format-ofm.c ofmReadClass(), file argument is null\n"); return 0; }
+
+ binaryReadInt16(file);
+ len = binaryReadInt16(file);
+
+ s = (char*)malloc(sizeof(char) * len + 1);
+ if(!s) { embLog_error("format-ofm.c ofmReadClass(), unable to allocate memory for s\n"); return 0; }
+ binaryReadBytes(file, (unsigned char*)s, len); /* TODO: check return value */
+ s[len] = '\0';
+ if(strcmp(s, "CExpStitch") == 0)
+ return 0x809C;
+ if(strcmp(s, "CColorChange") == 0)
+ return 0xFFFF;
+ return 0;
+}
+
+static void ofmReadBlockHeader(EmbFile* file)
+{
+ int val1, val2, val3, val4, val5, val6, val7, val8, val9, val10; /* TODO: determine what these represent */
+ unsigned char len;
+ char* s = 0;
+ unsigned short short1;
+ short unknown1 = 0; /* TODO: determine what this represents */
+ short unknown2 = 0; /* TODO: determine what this represents */
+ int unknown3 = 0; /* TODO: determine what this represents */
+
+ if(!file) { embLog_error("format-ofm.c ofmReadBlockHeader(), file argument is null\n"); return; }
+
+ unknown1 = binaryReadInt16(file);
+ unknown2 = (short)binaryReadInt32(file);
+ unknown3 = binaryReadInt32(file);
+
+ /* int v = binaryReadBytes(3); TODO: review */
+ binaryReadInt16(file);
+ binaryReadByte(file);
+ len = binaryReadByte(file);
+ s = (char*)malloc(2 * len);
+ if(!s) { embLog_error("format-ofm.c ofmReadBlockHeader(), unable to allocate memory for s\n"); return; }
+ binaryReadBytes(file, (unsigned char *)s, 2 * len); /* TODO: check return value */
+ val1 = binaryReadInt32(file); /* 0 */
+ val2 = binaryReadInt32(file); /* 0 */
+ val3 = binaryReadInt32(file); /* 0 */
+ val4 = binaryReadInt32(file); /* 0 */
+ val5 = binaryReadInt32(file); /* 1 */
+ val6 = binaryReadInt32(file); /* 1 */
+ val7 = binaryReadInt32(file); /* 1 */
+ val8 = binaryReadInt32(file); /* 0 */
+ val9 = binaryReadInt32(file); /* 64 */
+ val10 = binaryReadInt32(file); /* 64 */
+ short1 = binaryReadInt16(file); /* 0 */
+}
+
+static void ofmReadColorChange(EmbFile* file, EmbPattern* pattern)
+{
+ if(!file) { embLog_error("format-ofm.c ofmReadColorChange(), file argument is null\n"); return; }
+ if(!pattern) { embLog_error("format-ofm.c ofmReadColorChange(), pattern argument is null\n"); return; }
+
+ ofmReadBlockHeader(file);
+ embPattern_addStitchRel(pattern, 0.0, 0.0, STOP, 1);
+}
+
+static void ofmReadThreads(EmbFile* file, EmbPattern* p)
+{
+ int i, numberOfColors, stringLen, numberOfLibraries;
+ char* primaryLibraryName = 0;
+ char* expandedString = 0;
+
+ if(!file) { embLog_error("format-ofm.c ofmReadThreads(), file argument is null\n"); return; }
+ if(!p) { embLog_error("format-ofm.c ofmReadThreads(), p argument is null\n"); return; }
+
+ /* FF FE FF 00 */
+ binaryReadInt32(file);
+
+ numberOfColors = binaryReadInt16(file);
+
+ binaryReadInt16(file);
+ binaryReadInt16(file);
+ stringLen = binaryReadInt16(file);
+ expandedString = (char*)malloc(stringLen);
+ if(!expandedString) { embLog_error("format-ofm.c ofmReadThreads(), unable to allocate memory for expandedString\n"); return; }
+ binaryReadBytes(file, (unsigned char*)expandedString, stringLen); /* TODO: check return value */
+ for(i = 0; i < numberOfColors; i++)
+ {
+ EmbThread thread;
+ char colorNumberText[10];
+ int threadLibrary = 0, colorNameLength, colorNumber;
+ char* colorName = 0;
+ int r = binaryReadByte(file);
+ int g = binaryReadByte(file);
+ int b = binaryReadByte(file);
+ binaryReadByte(file);
+ threadLibrary = binaryReadInt16(file);
+ binaryReadInt16(file);
+ colorNumber = binaryReadInt32(file);
+ binaryReadByte(file);
+ binaryReadInt16(file);
+ colorNameLength = binaryReadByte(file);
+ colorName = (char*)malloc(colorNameLength * 2);
+ if(!colorName) { embLog_error("format-ofm.c ofmReadThreads(), unable to allocate memory for colorName\n"); return; }
+ binaryReadBytes(file, (unsigned char*)colorName, colorNameLength*2); /* TODO: check return value */
+ binaryReadInt16(file);
+ /* itoa(colorNumber, colorNumberText, 10); TODO: never use itoa, it's non-standard, use sprintf: http://stackoverflow.com/questions/5242524/converting-int-to-string-in-c */
+ thread.color.r = (unsigned char)r;
+ thread.color.g = (unsigned char)g;
+ thread.color.b = (unsigned char)b;
+ thread.catalogNumber = colorNumberText;
+ thread.description = colorName;
+ embPattern_addThread(p, thread);
+ }
+ binaryReadInt16(file);
+ primaryLibraryName = ofmReadLibrary(file);
+ numberOfLibraries = binaryReadInt16(file);
+ for(i = 0; i < numberOfLibraries; i++)
+ {
+ /*libraries.Add( TODO: review */
+ char* libName = ofmReadLibrary(file);
+ free(libName);
+ libName = 0;
+ }
+}
+
+static double ofmDecode(unsigned char b1, unsigned char b2)
+{
+ double val = (double)(short)(b1 << 8 | b2);
+ return val;
+}
+
+static void ofmReadExpanded(EmbFile* file, EmbPattern* p)
+{
+ int i, numberOfStitches = 0;
+
+ if(!file) { embLog_error("format-ofm.c ofmReadExpanded(), file argument is null\n"); return; }
+ if(!p) { embLog_error("format-ofm.c ofmReadExpanded(), p argument is null\n"); return; }
+
+ ofmReadBlockHeader(file);
+ numberOfStitches = binaryReadInt32(file);
+
+ for(i = 0; i < numberOfStitches; i++)
+ {
+ unsigned char stitch[5];
+ binaryReadBytes(file, stitch, 5); /* TODO: check return value */
+ if(stitch[0] == 0)
+ {
+ embPattern_addStitchAbs(p, ofmDecode(stitch[1], stitch[2]) / 10.0, ofmDecode(stitch[3], stitch[4]) / 10.0, i == 0 ? JUMP : NORMAL, 1);
+ }
+ else if(stitch[0] == 32)
+ {
+ embPattern_addStitchAbs(p, ofmDecode(stitch[1], stitch[2]) / 10.0, ofmDecode(stitch[3], stitch[4]) / 10.0, i == 0 ? TRIM : NORMAL, 1);
+ }
+ }
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readOfm(EmbPattern* pattern, const char* fileName)
+{
+ int unknownCount = 0;
+ int key = 0, classNameLength;
+ char* s = 0;
+ EmbFile* fileCompound = 0;
+ EmbFile* file = 0;
+ bcf_file* bcfFile = 0;
+
+ if(!pattern) { embLog_error("format-ofm.c readOfm(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-ofm.c readOfm(), fileName argument is null\n"); return 0; }
+
+ fileCompound = embFile_open(fileName, "rb");
+ if(!fileCompound)
+ {
+ embLog_error("format-ofm.c readOfm(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ bcfFile = (bcf_file*)malloc(sizeof(bcf_file));
+ if(!bcfFile) { embLog_error("format-ofm.c readOfm(), unable to allocate memory for bcfFile\n"); return 0; }
+ bcfFile_read(fileCompound, bcfFile);
+ file = GetFile(bcfFile, fileCompound, "EdsIV Object");
+ bcf_file_free(bcfFile);
+ bcfFile = 0;
+ embFile_seek(file, 0x1C6, SEEK_SET);
+ ofmReadThreads(file, pattern);
+ embFile_seek(file, 0x110, SEEK_CUR);
+ binaryReadInt32(file);
+ classNameLength = binaryReadInt16(file);
+ s = (char*)malloc(sizeof(char) * classNameLength);
+ if(!s) { embLog_error("format-ofm.c readOfm(), unable to allocate memory for s\n"); return 0; }
+ binaryReadBytes(file, (unsigned char*)s, classNameLength); /* TODO: check return value */
+ unknownCount = binaryReadInt16(file); /* TODO: determine what unknown count represents */
+
+ binaryReadInt16(file);
+ key = ofmReadClass(file);
+ while(1)
+ {
+ if(key == 0xFEFF)
+ {
+ break;
+ }
+ if(key == 0x809C)
+ {
+ ofmReadExpanded(file, pattern);
+ }
+ else
+ {
+ ofmReadColorChange(file, pattern);
+ }
+ key = binaryReadUInt16(file);
+ if(key == 0xFFFF)
+ {
+ ofmReadClass(file);
+ }
+ }
+
+ embFile_close(fileCompound);
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ embPattern_flip(pattern, 1, 1);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeOfm(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-ofm.c writeOfm(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-ofm.c writeOfm(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-ofm.c writeOfm(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writeOfm */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-ofm.h b/Software/Visual_Studio/Embroidery/libembroidery/format-ofm.h
new file mode 100644
index 000000000..433c332eb
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-ofm.h
@@ -0,0 +1,22 @@
+/*! @file format-ofm.h */
+#ifndef FORMAT_OFM_H
+#define FORMAT_OFM_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readOfm(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeOfm(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_OFM_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-pcd.c b/Software/Visual_Studio/Embroidery/libembroidery/format-pcd.c
new file mode 100644
index 000000000..de7d88958
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-pcd.c
@@ -0,0 +1,187 @@
+#include "format-pcd.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+#include "helpers-misc.h"
+
+static double pcdDecode(unsigned char a1, unsigned char a2, unsigned char a3)
+{
+ int res = a1 + (a2 << 8) + (a3 << 16);
+ if(res > 0x7FFFFF)
+ {
+ return (-((~(res) & 0x7FFFFF) - 1));
+ }
+ return res;
+}
+
+static void pcdEncode(EmbFile* file, int dx, int dy, int flags)
+{
+ unsigned char flagsToWrite = 0;
+
+ if(!file) { embLog_error("format-pcd.c pcdEncode(), file argument is null\n"); return; }
+
+ binaryWriteByte(file, (unsigned char)0);
+ binaryWriteByte(file, (unsigned char)(dx & 0xFF));
+ binaryWriteByte(file, (unsigned char)((dx >> 8) & 0xFF));
+ binaryWriteByte(file, (unsigned char)((dx >> 16) & 0xFF));
+
+ binaryWriteByte(file, (unsigned char)0);
+ binaryWriteByte(file, (unsigned char)(dy & 0xFF));
+ binaryWriteByte(file, (unsigned char)((dy >> 8) & 0xFF));
+ binaryWriteByte(file, (unsigned char)((dy >> 16) & 0xFF));
+ if(flags & STOP)
+ {
+ flagsToWrite |= 0x01;
+ }
+ if(flags & TRIM)
+ {
+ flagsToWrite |= 0x04;
+ }
+ binaryWriteByte(file, flagsToWrite);
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readPcd(EmbPattern* pattern, const char* fileName)
+{
+ char allZeroColor = 1;
+ int i = 0;
+ unsigned char b[9];
+ double dx = 0, dy = 0;
+ int flags = 0, st = 0;
+ unsigned char version, hoopSize;
+ unsigned short colorCount = 0;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-pcd.c readPcd(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-pcd.c readPcd(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-pcd.c readPcd(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ version = binaryReadByte(file);
+ hoopSize = binaryReadByte(file); /* 0 for PCD, 1 for PCQ (MAXI), 2 for PCS with small hoop(80x80), */
+ /* and 3 for PCS with large hoop (115x120) */
+ colorCount = binaryReadUInt16(file);
+
+ for(i = 0; i < colorCount; i++)
+ {
+ EmbThread t;
+ t.color.r = (unsigned char)embFile_getc(file);
+ t.color.g = (unsigned char)embFile_getc(file);
+ t.color.b = (unsigned char)embFile_getc(file);
+ t.catalogNumber = "";
+ t.description = "";
+ if(t.color.r || t.color.g || t.color.b)
+ {
+ allZeroColor = 0;
+ }
+ embPattern_addThread(pattern, t);
+ embFile_getc(file);
+ }
+ if(allZeroColor)
+ embPattern_loadExternalColorFile(pattern, fileName);
+ st = binaryReadUInt16(file);
+ /* READ STITCH RECORDS */
+ for(i = 0; i < st; i++)
+ {
+ flags = NORMAL;
+ if(embFile_read(b, 1, 9, file) != 9)
+ break;
+
+ if(b[8] & 0x01)
+ {
+ flags = STOP;
+ }
+ else if(b[8] & 0x04)
+ {
+ flags = TRIM;
+ }
+ else if(b[8] != 0)
+ {
+ /* TODO: ONLY INTERESTED IN THIS CASE TO LEARN MORE ABOUT THE FORMAT */
+ }
+ dx = pcdDecode(b[1], b[2], b[3]);
+ dy = pcdDecode(b[5], b[6], b[7]);
+ embPattern_addStitchAbs(pattern, dx / 10.0, dy / 10.0, flags, 1);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writePcd(EmbPattern* pattern, const char* fileName)
+{
+ EmbStitchList* pointer = 0;
+ EmbThreadList* threadPointer = 0;
+ EmbFile* file = 0;
+ int i;
+ unsigned char colorCount;
+ double xx = 0.0, yy = 0.0;
+
+ if(!pattern) { embLog_error("format-pcd.c writePcd(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-pcd.c writePcd(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-pcd.c writePcd(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ file = embFile_open(fileName, "wb");
+ if(!file)
+ {
+ embLog_error("format-pcd.c writePcd(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+
+ binaryWriteByte(file, (unsigned char)'2');
+ binaryWriteByte(file, 3); /* TODO: select hoop size defaulting to Large PCS hoop */
+ colorCount = (unsigned char)embThreadList_count(pattern->threadList);
+ binaryWriteUShort(file, (unsigned short)colorCount);
+ threadPointer = pattern->threadList;
+ i = 0;
+ while(threadPointer)
+ {
+ EmbColor color = threadPointer->thread.color;
+ binaryWriteByte(file, color.r);
+ binaryWriteByte(file, color.g);
+ binaryWriteByte(file, color.b);
+ binaryWriteByte(file, 0);
+ threadPointer = threadPointer->next;
+ i++;
+ }
+
+ for(; i < 16; i++)
+ {
+ binaryWriteUInt(file, 0); /* write remaining colors to reach 16 */
+ }
+
+ binaryWriteUShort(file, (unsigned short)embStitchList_count(pattern->stitchList));
+ /* write stitches */
+ xx = yy = 0;
+ pointer = pattern->stitchList;
+ while(pointer)
+ {
+ pcdEncode(file, roundDouble(pointer->stitch.xx * 10.0), roundDouble(pointer->stitch.yy * 10.0), pointer->stitch.flags);
+ pointer = pointer->next;
+ }
+ embFile_close(file);
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-pcd.h b/Software/Visual_Studio/Embroidery/libembroidery/format-pcd.h
new file mode 100644
index 000000000..55f0fb198
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-pcd.h
@@ -0,0 +1,22 @@
+/*! @file format-pcd.h */
+#ifndef FORMAT_PCD_H
+#define FORMAT_PCD_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readPcd(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writePcd(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_PCD_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-pcm.c b/Software/Visual_Studio/Embroidery/libembroidery/format-pcm.c
new file mode 100644
index 000000000..6d18260ae
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-pcm.c
@@ -0,0 +1,101 @@
+#include "format-pcm.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+#include "helpers-misc.h"
+
+static double pcmDecode(unsigned char a1, unsigned char a2, unsigned char a3)
+{
+ int res = a1 + (a2 << 8) + (a3 << 16);
+ if(res > 0x7FFFFF)
+ {
+ return (-((~(res) & 0x7FFFFF) - 1));
+ }
+ return res;
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readPcm(EmbPattern* pattern, const char* fileName)
+{
+ int i = 0;
+ unsigned char b[9];
+ double dx = 0, dy = 0;
+ int flags = 0, st = 0;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-pcm.c readPcm(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-pcm.c readPcm(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-pcm.c readPcm(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embFile_seek(file, 4, SEEK_SET);
+
+ for(i = 0; i < 16; i++)
+ {
+ int colorNumber;
+ (void)embFile_getc(file); /* zero */
+ colorNumber = embFile_getc(file);
+ embPattern_addThread(pattern, pcmThreads[colorNumber]);
+ }
+ st = binaryReadUInt16BE(file);
+ /* READ STITCH RECORDS */
+ for(i = 0; i < st; i++)
+ {
+ flags = NORMAL;
+ if(embFile_read(b, 1, 9, file) != 9)
+ break;
+
+ if(b[8] & 0x01)
+ {
+ flags = STOP;
+ }
+ else if(b[8] & 0x04)
+ {
+ flags = TRIM;
+ }
+ else if(b[8] != 0)
+ {
+ /* TODO: ONLY INTERESTED IN THIS CASE TO LEARN MORE ABOUT THE FORMAT */
+ }
+ dx = pcmDecode(b[2], b[1], b[0]);
+ dy = pcmDecode(b[6], b[5], b[4]);
+ embPattern_addStitchAbs(pattern, dx / 10.0, dy / 10.0, flags, 1);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writePcm(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-pcm.c writePcm(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-pcm.c writePcm(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-pcm.c writePcm(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writePcm */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-pcm.h b/Software/Visual_Studio/Embroidery/libembroidery/format-pcm.h
new file mode 100644
index 000000000..ba951536e
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-pcm.h
@@ -0,0 +1,42 @@
+/*! @file format-pcm.h */
+#ifndef FORMAT_PCM_H
+#define FORMAT_PCM_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readPcm(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writePcm(EmbPattern* pattern, const char* fileName);
+
+static const int pcmThreadCount = 65;
+static const EmbThread pcmThreads[] = {
+ {{0x00, 0x00, 0x00}, "PCM Color 1", ""},
+ {{0x00, 0x00, 0x80}, "PCM Color 2", ""},
+ {{0x00, 0x00, 0xFF}, "PCM Color 3", ""},
+ {{0x00, 0x80, 0x80}, "PCM Color 4", ""},
+ {{0x00, 0xFF, 0xFF}, "PCM Color 5", ""},
+ {{0x80, 0x00, 0x80}, "PCM Color 6", ""},
+ {{0xFF, 0x00, 0xFF}, "PCM Color 7", ""},
+ {{0x80, 0x00, 0x00}, "PCM Color 8", ""},
+ {{0xFF, 0x00, 0x00}, "PCM Color 9", ""},
+ {{0x00, 0x80, 0x00}, "PCM Color 10", ""},
+ {{0x00, 0xFF, 0x00}, "PCM Color 11", ""},
+ {{0x80, 0x80, 0x00}, "PCM Color 12", ""},
+ {{0xFF, 0xFF, 0x00}, "PCM Color 13", ""},
+ {{0x80, 0x80, 0x80}, "PCM Color 14", ""},
+ {{0xC0, 0xC0, 0xC0}, "PCM Color 15", ""},
+ {{0xFF, 0xFF, 0xFF}, "PCM Color 16", ""}};
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_PCM_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-pcq.c b/Software/Visual_Studio/Embroidery/libembroidery/format-pcq.c
new file mode 100644
index 000000000..a199dcbf6
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-pcq.c
@@ -0,0 +1,187 @@
+#include "format-pcq.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+#include "helpers-misc.h"
+
+static double pcqDecode(unsigned char a1, unsigned char a2, unsigned char a3)
+{
+ int res = a1 + (a2 << 8) + (a3 << 16);
+ if(res > 0x7FFFFF)
+ {
+ return (-((~(res) & 0x7FFFFF) - 1));
+ }
+ return res;
+}
+
+static void pcqEncode(EmbFile* file, int dx, int dy, int flags)
+{
+ unsigned char flagsToWrite = 0;
+
+ if(!file) { embLog_error("format-pcq.c pcqEncode(), file argument is null\n"); return; }
+
+ binaryWriteByte(file, (unsigned char)0);
+ binaryWriteByte(file, (unsigned char)(dx & 0xFF));
+ binaryWriteByte(file, (unsigned char)((dx >> 8) & 0xFF));
+ binaryWriteByte(file, (unsigned char)((dx >> 16) & 0xFF));
+
+ binaryWriteByte(file, (unsigned char)0);
+ binaryWriteByte(file, (unsigned char)(dy & 0xFF));
+ binaryWriteByte(file, (unsigned char)((dy >> 8) & 0xFF));
+ binaryWriteByte(file, (unsigned char)((dy >> 16) & 0xFF));
+ if(flags & STOP)
+ {
+ flagsToWrite |= 0x01;
+ }
+ if(flags & TRIM)
+ {
+ flagsToWrite |= 0x04;
+ }
+ binaryWriteByte(file, flagsToWrite);
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readPcq(EmbPattern* pattern, const char* fileName)
+{
+ char allZeroColor = 1;
+ int i = 0;
+ unsigned char b[9];
+ double dx = 0, dy = 0;
+ int flags = 0, st = 0;
+ unsigned char version, hoopSize;
+ unsigned short colorCount;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-pcq.c readPcq(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-pcq.c readPcq(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-pcq.c readPcq(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ version = binaryReadByte(file);
+ hoopSize = binaryReadByte(file); /* 0 for PCD, 1 for PCQ (MAXI), 2 for PCS with small hoop(80x80), */
+ /* and 3 for PCS with large hoop (115x120) */
+ colorCount = binaryReadUInt16(file);
+
+ for(i = 0; i < colorCount; i++)
+ {
+ EmbThread t;
+ t.color.r = (unsigned char)embFile_getc(file);
+ t.color.g = (unsigned char)embFile_getc(file);
+ t.color.b = (unsigned char)embFile_getc(file);
+ t.catalogNumber = "";
+ t.description = "";
+ if(t.color.r || t.color.g || t.color.b)
+ {
+ allZeroColor = 0;
+ }
+ embPattern_addThread(pattern, t);
+ embFile_getc(file);
+ }
+ if(allZeroColor)
+ embPattern_loadExternalColorFile(pattern, fileName);
+ st = binaryReadUInt16(file);
+ /* READ STITCH RECORDS */
+ for(i = 0; i < st; i++)
+ {
+ flags = NORMAL;
+ if(embFile_read(b, 1, 9, file) != 9)
+ break;
+
+ if(b[8] & 0x01)
+ {
+ flags = STOP;
+ }
+ else if(b[8] & 0x04)
+ {
+ flags = TRIM;
+ }
+ else if(b[8] != 0)
+ {
+ /* TODO: ONLY INTERESTED IN THIS CASE TO LEARN MORE ABOUT THE FORMAT */
+ }
+ dx = pcqDecode(b[1], b[2], b[3]);
+ dy = pcqDecode(b[5], b[6], b[7]);
+ embPattern_addStitchAbs(pattern, dx / 10.0, dy / 10.0, flags, 1);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writePcq(EmbPattern* pattern, const char* fileName)
+{
+ EmbStitchList* pointer = 0;
+ EmbThreadList* threadPointer = 0;
+ EmbFile* file = 0;
+ int i;
+ unsigned char colorCount;
+ double xx = 0.0, yy = 0.0;
+
+ if(!pattern) { embLog_error("format-pcq.c writePcq(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-pcq.c writePcq(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-pcq.c writePcq(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ file = embFile_open(fileName, "wb");
+ if(!file)
+ {
+ embLog_error("format-pcq.c writePcq(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+
+ binaryWriteByte(file, (unsigned char)'2');
+ binaryWriteByte(file, 3); /* TODO: select hoop size defaulting to Large PCS hoop */
+ colorCount = (unsigned char)embThreadList_count(pattern->threadList);
+ binaryWriteUShort(file, (unsigned short)colorCount);
+ threadPointer = pattern->threadList;
+ i = 0;
+ while(threadPointer)
+ {
+ EmbColor color = threadPointer->thread.color;
+ binaryWriteByte(file, color.r);
+ binaryWriteByte(file, color.g);
+ binaryWriteByte(file, color.b);
+ binaryWriteByte(file, 0);
+ threadPointer = threadPointer->next;
+ i++;
+ }
+
+ for(; i < 16; i++)
+ {
+ binaryWriteUInt(file, 0); /* write remaining colors to reach 16 */
+ }
+
+ binaryWriteUShort(file, (unsigned short)embStitchList_count(pattern->stitchList));
+ /* write stitches */
+ xx = yy = 0;
+ pointer = pattern->stitchList;
+ while(pointer)
+ {
+ pcqEncode(file, roundDouble(pointer->stitch.xx * 10.0), roundDouble(pointer->stitch.yy * 10.0), pointer->stitch.flags);
+ pointer = pointer->next;
+ }
+ embFile_close(file);
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-pcq.h b/Software/Visual_Studio/Embroidery/libembroidery/format-pcq.h
new file mode 100644
index 000000000..e5d23ec4a
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-pcq.h
@@ -0,0 +1,22 @@
+/*! @file format-pcq.h */
+#ifndef FORMAT_PCQ_H
+#define FORMAT_PCQ_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readPcq(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writePcq(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_PCQ_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-pcs.c b/Software/Visual_Studio/Embroidery/libembroidery/format-pcs.c
new file mode 100644
index 000000000..2fe13dcbd
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-pcs.c
@@ -0,0 +1,199 @@
+#include "format-pcs.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+#include "helpers-misc.h"
+
+static double pcsDecode(unsigned char a1, unsigned char a2, unsigned char a3)
+{
+ int res = a1 + (a2 << 8) + (a3 << 16);
+ if(res > 0x7FFFFF)
+ {
+ return (-((~(res) & 0x7FFFFF) - 1));
+ }
+ return res;
+}
+
+static void pcsEncode(EmbFile* file, int dx, int dy, int flags)
+{
+ unsigned char flagsToWrite = 0;
+
+ if(!file) { embLog_error("format-pcs.c pcsEncode(), file argument is null\n"); return; }
+
+ binaryWriteByte(file, (unsigned char)0);
+ binaryWriteByte(file, (unsigned char)(dx & 0xFF));
+ binaryWriteByte(file, (unsigned char)((dx >> 8) & 0xFF));
+ binaryWriteByte(file, (unsigned char)((dx >> 16) & 0xFF));
+
+ binaryWriteByte(file, (unsigned char)0);
+ binaryWriteByte(file, (unsigned char)(dy & 0xFF));
+ binaryWriteByte(file, (unsigned char)((dy >> 8) & 0xFF));
+ binaryWriteByte(file, (unsigned char)((dy >> 16) & 0xFF));
+ if(flags & STOP)
+ {
+ flagsToWrite |= 0x01;
+ }
+ if(flags & TRIM)
+ {
+ flagsToWrite |= 0x04;
+ }
+ binaryWriteByte(file, flagsToWrite);
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readPcs(EmbPattern* pattern, const char* fileName)
+{
+ char allZeroColor = 1;
+ int i = 0;
+ unsigned char b[9];
+ double dx = 0, dy = 0;
+ int flags = 0, st = 0;
+ unsigned char version, hoopSize;
+ unsigned short colorCount;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-pcs.c readPcs(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-pcs.c readPcs(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-pcs.c readPcs(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+ version = binaryReadByte(file);
+ hoopSize = binaryReadByte(file); /* 0 for PCD, 1 for PCQ (MAXI), 2 for PCS with small hoop(80x80), */
+ /* and 3 for PCS with large hoop (115x120) */
+
+ switch(hoopSize)
+ {
+ case 2:
+ pattern->hoop.width = 80.0;
+ pattern->hoop.height = 80.0;
+ break;
+ case 3:
+ pattern->hoop.width = 115;
+ pattern->hoop.height = 120.0;
+ break;
+ }
+
+ colorCount = binaryReadUInt16(file);
+
+ for(i = 0; i < colorCount; i++)
+ {
+ EmbThread t;
+ t.color.r = binaryReadByte(file);
+ t.color.g = binaryReadByte(file);
+ t.color.b = binaryReadByte(file);
+ t.catalogNumber = "";
+ t.description = "";
+ if(t.color.r || t.color.g || t.color.b)
+ {
+ allZeroColor = 0;
+ }
+ embPattern_addThread(pattern, t);
+ binaryReadByte(file);
+ }
+ if(allZeroColor)
+ embPattern_loadExternalColorFile(pattern, fileName);
+ st = binaryReadUInt16(file);
+ /* READ STITCH RECORDS */
+ for(i = 0; i < st; i++)
+ {
+ flags = NORMAL;
+ if(embFile_read(b, 1, 9, file) != 9)
+ break;
+
+ if(b[8] & 0x01)
+ {
+ flags = STOP;
+ }
+ else if(b[8] & 0x04)
+ {
+ flags = TRIM;
+ }
+ else if(b[8] != 0)
+ {
+ /* TODO: ONLY INTERESTED IN THIS CASE TO LEARN MORE ABOUT THE FORMAT */
+ }
+ dx = pcsDecode(b[1], b[2], b[3]);
+ dy = pcsDecode(b[5], b[6], b[7]);
+ embPattern_addStitchAbs(pattern, dx / 10.0, dy / 10.0, flags, 1);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writePcs(EmbPattern* pattern, const char* fileName)
+{
+ EmbStitchList* pointer = 0;
+ EmbThreadList* threadPointer = 0;
+ EmbFile* file = 0;
+ int i = 0;
+ unsigned char colorCount = 0;
+ double xx = 0.0, yy = 0.0;
+
+ if(!pattern) { embLog_error("format-pcs.c writePcs(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-pcs.c writePcs(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-pcs.c writePcs(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ file = embFile_open(fileName, "wb");
+ if(!file)
+ {
+ embLog_error("format-pcs.c writePcs(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+
+ binaryWriteByte(file, (unsigned char)'2');
+ binaryWriteByte(file, 3); /* TODO: select hoop size defaulting to Large PCS hoop */
+ colorCount = (unsigned char)embThreadList_count(pattern->threadList);
+ binaryWriteUShort(file, (unsigned short)colorCount);
+ threadPointer = pattern->threadList;
+ i = 0;
+ while(threadPointer)
+ {
+ EmbColor color = threadPointer->thread.color;
+ binaryWriteByte(file, color.r);
+ binaryWriteByte(file, color.g);
+ binaryWriteByte(file, color.b);
+ binaryWriteByte(file, 0);
+ threadPointer = threadPointer->next;
+ i++;
+ }
+
+ for(; i < 16; i++)
+ {
+ binaryWriteUInt(file, 0); /* write remaining colors to reach 16 */
+ }
+
+ binaryWriteUShort(file, (unsigned short)embStitchList_count(pattern->stitchList));
+ /* write stitches */
+ xx = yy = 0;
+ pointer = pattern->stitchList;
+ while(pointer)
+ {
+ pcsEncode(file, roundDouble(pointer->stitch.xx * 10.0), roundDouble(pointer->stitch.yy * 10.0), pointer->stitch.flags);
+ pointer = pointer->next;
+ }
+ embFile_close(file);
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-pcs.h b/Software/Visual_Studio/Embroidery/libembroidery/format-pcs.h
new file mode 100644
index 000000000..0a64713b5
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-pcs.h
@@ -0,0 +1,22 @@
+/*! @file format-pcs.h */
+#ifndef FORMAT_PCS_H
+#define FORMAT_PCS_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readPcs(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writePcs(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_PCS_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-pec.c b/Software/Visual_Studio/Embroidery/libembroidery/format-pec.c
new file mode 100644
index 000000000..ccef4e162
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-pec.c
@@ -0,0 +1,426 @@
+#include "format-pec.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+#include "helpers-misc.h"
+#include <stdlib.h>
+#include <string.h>
+
+void readPecStitches(EmbPattern* pattern, EmbFile* file)
+{
+ int stitchNumber = 0;
+
+ if(!pattern) { embLog_error("format-pec.c readPecStitches(), pattern argument is null\n"); return; }
+ if(!file) { embLog_error("format-pec.c readPecStitches(), file argument is null\n"); return; }
+
+ while(!embFile_eof(file))
+ {
+ int val1 = (int)binaryReadUInt8(file);
+ int val2 = (int)binaryReadUInt8(file);
+
+ int stitchType = NORMAL;
+ if(val1 == 0xFF && val2 == 0x00)
+ {
+ embPattern_addStitchRel(pattern, 0.0, 0.0, END, 1);
+ break;
+ }
+ if(val1 == 0xFE && val2 == 0xB0)
+ {
+ (void)binaryReadByte(file);
+ embPattern_addStitchRel(pattern, 0.0, 0.0, STOP, 1);
+ stitchNumber++;
+ continue;
+ }
+ /* High bit set means 12-bit offset, otherwise 7-bit signed delta */
+ if(val1 & 0x80)
+ {
+ if(val1 & 0x20) stitchType = TRIM;
+ if(val1 & 0x10) stitchType = JUMP;
+ val1 = ((val1 & 0x0F) << 8) + val2;
+
+ /* Signed 12-bit arithmetic */
+ if(val1 & 0x800)
+ {
+ val1 -= 0x1000;
+ }
+
+ val2 = binaryReadUInt8(file);
+ }
+ else if(val1 >= 0x40)
+ {
+ val1 -= 0x80;
+ }
+ if(val2 & 0x80)
+ {
+ if(val2 & 0x20) stitchType = TRIM;
+ if(val2 & 0x10) stitchType = JUMP;
+ val2 = ((val2 & 0x0F) << 8) + binaryReadUInt8(file);
+
+ /* Signed 12-bit arithmetic */
+ if(val2 & 0x800)
+ {
+ val2 -= 0x1000;
+ }
+ }
+ else if(val2 >= 0x40)
+ {
+ val2 -= 0x80;
+ }
+ embPattern_addStitchRel(pattern, val1 / 10.0, val2 / 10.0, stitchType, 1);
+ stitchNumber++;
+ }
+}
+
+static void pecEncodeJump(EmbFile* file, int x, int types)
+{
+ int outputVal = abs(x) & 0x7FF;
+ unsigned int orPart = 0x80;
+
+ if(!file) { embLog_error("format-pec.c pecEncodeJump(), file argument is null\n"); return; }
+
+ if(types & TRIM)
+ {
+ orPart |= 0x20;
+ }
+ if(types & JUMP)
+ {
+ orPart |= 0x10;
+ }
+
+ if(x < 0)
+ {
+ outputVal = x + 0x1000 & 0x7FF;
+ outputVal |= 0x800;
+ }
+ binaryWriteByte(file, (unsigned char)(((outputVal >> 8) & 0x0F) | orPart));
+ binaryWriteByte(file, (unsigned char)(outputVal & 0xFF));
+}
+
+static void pecEncodeStop(EmbFile* file, unsigned char val)
+{
+ if(!file) { embLog_error("format-pec.c pecEncodeStop(), file argument is null\n"); return; }
+ binaryWriteByte(file, 0xFE);
+ binaryWriteByte(file, 0xB0);
+ binaryWriteByte(file, val);
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readPec(EmbPattern* pattern, const char* fileName)
+{
+ unsigned int graphicsOffset;
+ unsigned char colorChanges;
+ int i;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-pec.c readPec(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-pec.c readPec(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-pec.c readPec(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embFile_seek(file, 0x38, SEEK_SET);
+ colorChanges = (unsigned char)binaryReadByte(file);
+ for(i = 0; i <= colorChanges; i++)
+ {
+ embPattern_addThread(pattern, pecThreads[binaryReadByte(file) % 65]);
+ }
+
+ /* Get Graphics offset */
+ embFile_seek(file, 0x20A, SEEK_SET);
+
+ graphicsOffset = (unsigned int)(binaryReadUInt8(file));
+ graphicsOffset |= (binaryReadUInt8(file) << 8);
+ graphicsOffset |= (binaryReadUInt8(file) << 16);
+
+ (void)binaryReadByte(file); /* 0x31 */
+ (void)binaryReadByte(file); /* 0xFF */
+ (void)binaryReadByte(file); /* 0xF0 */
+ /* Get X and Y size in .1 mm */
+ /* 0x210 */
+ binaryReadInt16(file); /* x size */
+ binaryReadInt16(file); /* y size */
+
+ binaryReadInt16(file); /* 0x01E0 */
+ binaryReadInt16(file); /* 0x01B0 */
+ binaryReadInt16(file); /* distance left from start */
+ binaryReadInt16(file); /* distance up from start */
+
+ /* Begin Stitch Data */
+ /* 0x21C */
+ /*unsigned int end = graphicsOffset + 0x208; */
+ readPecStitches(pattern, file);
+
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ embPattern_flipVertical(pattern);
+
+ return 1;
+}
+
+static void pecEncode(EmbFile* file, EmbPattern* p)
+{
+ double thisX = 0.0;
+ double thisY = 0.0;
+ unsigned char stopCode = 2;
+ EmbStitchList* list = 0;
+
+ if(!file) { embLog_error("format-pec.c pecEncode(), file argument is null\n"); return; }
+ if(!p) { embLog_error("format-pec.c pecEncode(), p argument is null\n"); return; }
+
+ list = p->stitchList;
+ while(list)
+ {
+ int deltaX, deltaY;
+ EmbStitch s = list->stitch;
+
+ deltaX = roundDouble(s.xx - thisX);
+ deltaY = roundDouble(s.yy - thisY);
+ thisX += (double)deltaX;
+ thisY += (double)deltaY;
+
+ if(s.flags & STOP)
+ {
+ pecEncodeStop(file, stopCode);
+ if(stopCode == (unsigned char)2)
+ {
+ stopCode = (unsigned char)1;
+ }
+ else
+ {
+ stopCode = (unsigned char)2;
+ }
+ }
+ else if(s.flags & END)
+ {
+ binaryWriteByte(file, 0xFF);
+ break;
+ }
+ else if(deltaX < 63 && deltaX > -64 && deltaY < 63 && deltaY > -64 && (!(s.flags & (JUMP | TRIM))))
+ {
+ binaryWriteByte(file, (deltaX < 0) ? (unsigned char)(deltaX + 0x80) : (unsigned char)deltaX);
+ binaryWriteByte(file, (deltaY < 0) ? (unsigned char)(deltaY + 0x80) : (unsigned char)deltaY);
+ }
+ else
+ {
+ pecEncodeJump(file, deltaX, s.flags);
+ pecEncodeJump(file, deltaY, s.flags);
+ }
+ list = list->next;
+ }
+}
+
+static void clearImage(unsigned char image[][48])
+{
+ memcpy(image, imageWithFrame, 48*38);
+}
+
+static void writeImage(EmbFile* file, unsigned char image[][48])
+{
+ int i, j;
+
+ if(!file) { embLog_error("format-pec.c writeImage(), file argument is null\n"); return; }
+
+ for(i = 0; i < 38; i++)
+ {
+ for(j = 0; j < 6; j++)
+ {
+ int offset = j * 8;
+ unsigned char output = 0;
+ output |= (unsigned char)(image[i][offset] != 0);
+ output |= (unsigned char)(image[i][offset + 1] != (unsigned char)0) << 1;
+ output |= (unsigned char)(image[i][offset + 2] != (unsigned char)0) << 2;
+ output |= (unsigned char)(image[i][offset + 3] != (unsigned char)0) << 3;
+ output |= (unsigned char)(image[i][offset + 4] != (unsigned char)0) << 4;
+ output |= (unsigned char)(image[i][offset + 5] != (unsigned char)0) << 5;
+ output |= (unsigned char)(image[i][offset + 6] != (unsigned char)0) << 6;
+ output |= (unsigned char)(image[i][offset + 7] != (unsigned char)0) << 7;
+ binaryWriteByte(file, output);
+ }
+ }
+}
+
+void writePecStitches(EmbPattern* pattern, EmbFile* file, const char* fileName)
+{
+ EmbStitchList* tempStitches = 0;
+ EmbRect bounds;
+ unsigned char image[38][48];
+ int i, flen, currentThreadCount, graphicsOffsetLocation, graphicsOffsetValue, height, width;
+ double xFactor, yFactor;
+ const char* forwardSlashPos = strrchr(fileName, '/');
+ const char* backSlashPos = strrchr(fileName, '\\');
+ const char* dotPos = strrchr(fileName, '.');
+ const char* start = 0;
+
+ if(!pattern) { embLog_error("format-pec.c writePecStitches(), pattern argument is null\n"); return; }
+ if(!file) { embLog_error("format-pec.c writePecStitches(), file argument is null\n"); return; }
+ if(!fileName) { embLog_error("format-pec.c writePecStitches(), fileName argument is null\n"); return; }
+
+ if(forwardSlashPos)
+ {
+ start = forwardSlashPos + 1;
+ }
+ if(backSlashPos && backSlashPos > start)
+ {
+ start = backSlashPos + 1;
+ }
+ if(!start)
+ {
+ start = fileName;
+ }
+ binaryWriteBytes(file, "LA:", 3);
+ flen = (int)(dotPos - start);
+
+ while(start < dotPos)
+ {
+ binaryWriteByte(file, (unsigned char)*start);
+ start++;
+ }
+ for(i = 0; i < (int)(16-flen); i++)
+ {
+ binaryWriteByte(file, (unsigned char)0x20);
+ }
+ binaryWriteByte(file, 0x0D);
+ for(i = 0; i < 12; i++)
+ {
+ binaryWriteByte(file, (unsigned char)0x20);
+ }
+ binaryWriteByte(file, (unsigned char)0xFF);
+ binaryWriteByte(file, (unsigned char)0x00);
+ binaryWriteByte(file, (unsigned char)0x06);
+ binaryWriteByte(file, (unsigned char)0x26);
+
+ for(i = 0; i < 12; i++)
+ {
+ binaryWriteByte(file, (unsigned char)0x20);
+ }
+ currentThreadCount = embThreadList_count(pattern->threadList);
+ binaryWriteByte(file, (unsigned char)(currentThreadCount-1));
+
+ for(i = 0; i < currentThreadCount; i++)
+ {
+ binaryWriteByte(file, (unsigned char)embThread_findNearestColorInArray(embThreadList_getAt(pattern->threadList, i).color, (EmbThread*)pecThreads, pecThreadCount));
+ }
+ for(i = 0; i < (int)(0x1CF - currentThreadCount); i++)
+ {
+ binaryWriteByte(file, (unsigned char)0x20);
+ }
+ binaryWriteShort(file, (short)0x0000);
+
+ graphicsOffsetLocation = embFile_tell(file);
+ /* placeholder bytes to be overwritten */
+ binaryWriteByte(file, (unsigned char)0x00);
+ binaryWriteByte(file, (unsigned char)0x00);
+ binaryWriteByte(file, (unsigned char)0x00);
+
+ binaryWriteByte(file, (unsigned char)0x31);
+ binaryWriteByte(file, (unsigned char)0xFF);
+ binaryWriteByte(file, (unsigned char)0xF0);
+
+ bounds = embPattern_calcBoundingBox(pattern);
+
+ height = roundDouble(embRect_height(bounds));
+ width = roundDouble(embRect_width(bounds));
+ /* write 2 byte x size */
+ binaryWriteShort(file, (short)width);
+ /* write 2 byte y size */
+ binaryWriteShort(file, (short)height);
+
+ /* Write 4 miscellaneous int16's */
+ binaryWriteShort(file, (short)0x1E0);
+ binaryWriteShort(file, (short)0x1B0);
+
+ binaryWriteUShortBE(file, (unsigned short)(0x9000 | -roundDouble(bounds.left)));
+ binaryWriteUShortBE(file, (unsigned short)(0x9000 | -roundDouble(bounds.top)));
+
+ pecEncode(file, pattern);
+ graphicsOffsetValue = embFile_tell(file) - graphicsOffsetLocation + 2;
+ embFile_seek(file, graphicsOffsetLocation, SEEK_SET);
+
+ binaryWriteByte(file, (unsigned char)(graphicsOffsetValue & 0xFF));
+ binaryWriteByte(file, (unsigned char)((graphicsOffsetValue >> 8) & 0xFF));
+ binaryWriteByte(file, (unsigned char)((graphicsOffsetValue >> 16) & 0xFF));
+
+ embFile_seek(file, 0x00, SEEK_END);
+
+ /* Writing all colors */
+ clearImage(image);
+ tempStitches = pattern->stitchList;
+
+ yFactor = 32.0 / height;
+ xFactor = 42.0 / width;
+ while(tempStitches->next)
+ {
+ int x = roundDouble((tempStitches->stitch.xx - bounds.left) * xFactor) + 3;
+ int y = roundDouble((tempStitches->stitch.yy - bounds.top) * yFactor) + 3;
+ image[y][x] = 1;
+ tempStitches = tempStitches->next;
+ }
+ writeImage(file, image);
+
+ /* Writing each individual color */
+ tempStitches = pattern->stitchList;
+ for(i = 0; i < currentThreadCount; i++)
+ {
+ clearImage(image);
+ while(tempStitches->next)
+ {
+ int x = roundDouble((tempStitches->stitch.xx - bounds.left) * xFactor) + 3;
+ int y = roundDouble((tempStitches->stitch.yy - bounds.top) * yFactor) + 3;
+ if(tempStitches->stitch.flags & STOP)
+ {
+ tempStitches = tempStitches->next;
+ break;
+ }
+ image[y][x] = 1;
+ tempStitches = tempStitches->next;
+ }
+ writeImage(file, image);
+ }
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writePec(EmbPattern* pattern, const char* fileName)
+{
+ EmbFile* file = 0;
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-pec.c writePec(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ file = embFile_open(fileName, "wb");
+ if(!file)
+ {
+ embLog_error("format-pec.c writePec(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+
+ embPattern_flipVertical(pattern); /* TODO: There needs to be a matching flipVertical() call after the write to ensure multiple writes from the same pattern work properly */
+ embPattern_fixColorCount(pattern);
+ embPattern_correctForMaxStitchLength(pattern,12.7, 204.7);
+ embPattern_scale(pattern, 10.0);
+
+ binaryWriteBytes(file, "#PEC0001", 8);
+
+ writePecStitches(pattern, file, fileName);
+
+ embFile_close(file);
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-pec.h b/Software/Visual_Studio/Embroidery/libembroidery/format-pec.h
new file mode 100644
index 000000000..83436a264
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-pec.h
@@ -0,0 +1,135 @@
+/*! @file format-pec.h */
+#ifndef FORMAT_PEC_H
+#define FORMAT_PEC_H
+
+#include "emb-file.h"
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readPec(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writePec(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE void EMB_CALL readPecStitches(EmbPattern* pattern, EmbFile* file);
+extern EMB_PRIVATE void EMB_CALL writePecStitches(EmbPattern* pattern, EmbFile* file, const char* filename);
+
+static const int pecThreadCount = 65;
+static const EmbThread pecThreads[] = {
+{{ 0, 0, 0}, "Unknown", ""}, /* Index 0 */
+{{ 14, 31, 124}, "Prussian Blue", ""}, /* Index 1 */
+{{ 10, 85, 163}, "Blue", ""}, /* Index 2 */
+{{ 0, 135, 119}, "Teal Green", ""}, /* Index 3 */ /* TODO: Verify RGB value is correct */
+{{ 75, 107, 175}, "Cornflower Blue", ""}, /* Index 4 */
+{{237, 23, 31}, "Red", ""}, /* Index 5 */
+{{209, 92, 0}, "Reddish Brown", ""}, /* Index 6 */
+{{145, 54, 151}, "Magenta", ""}, /* Index 7 */
+{{228, 154, 203}, "Light Lilac", ""}, /* Index 8 */
+{{145, 95, 172}, "Lilac", ""}, /* Index 9 */
+{{158, 214, 125}, "Mint Green", ""}, /* Index 10 */ /* TODO: Verify RGB value is correct */
+{{232, 169, 0}, "Deep Gold", ""}, /* Index 11 */
+{{254, 186, 53}, "Orange", ""}, /* Index 12 */
+{{255, 255, 0}, "Yellow", ""}, /* Index 13 */
+{{112, 188, 31}, "Lime Green", ""}, /* Index 14 */
+{{186, 152, 0}, "Brass", ""}, /* Index 15 */
+{{168, 168, 168}, "Silver", ""}, /* Index 16 */
+{{125, 111, 0}, "Russet Brown", ""}, /* Index 17 */ /* TODO: Verify RGB value is correct */
+{{255, 255, 179}, "Cream Brown", ""}, /* Index 18 */
+{{ 79, 85, 86}, "Pewter", ""}, /* Index 19 */
+{{ 0, 0, 0}, "Black", ""}, /* Index 20 */
+{{ 11, 61, 145}, "Ultramarine", ""}, /* Index 21 */
+{{119, 1, 118}, "Royal Purple", ""}, /* Index 22 */
+{{ 41, 49, 51}, "Dark Gray", ""}, /* Index 23 */
+{{ 42, 19, 1}, "Dark Brown", ""}, /* Index 24 */
+{{246, 74, 138}, "Deep Rose", ""}, /* Index 25 */
+{{178, 118, 36}, "Light Brown", ""}, /* Index 26 */
+{{252, 187, 197}, "Salmon Pink", ""}, /* Index 27 */ /* TODO: Verify RGB value is correct */
+{{254, 55, 15}, "Vermillion", ""}, /* Index 28 */
+{{240, 240, 240}, "White", ""}, /* Index 29 */
+{{106, 28, 138}, "Violet", ""}, /* Index 30 */
+{{168, 221, 196}, "Seacrest", ""}, /* Index 31 */
+{{ 37, 132, 187}, "Sky Blue", ""}, /* Index 32 */
+{{254, 179, 67}, "Pumpkin", ""}, /* Index 33 */
+{{255, 243, 107}, "Cream Yellow", ""}, /* Index 34 */
+{{208, 166, 96}, "Khaki", ""}, /* Index 35 */
+{{209, 84, 0}, "Clay Brown", ""}, /* Index 36 */
+{{102, 186, 73}, "Leaf Green", ""}, /* Index 37 */
+{{ 19, 74, 70}, "Peacock Blue", ""}, /* Index 38 */
+{{135, 135, 135}, "Gray", ""}, /* Index 39 */
+{{216, 204, 198}, "Warm Gray", ""}, /* Index 40 */ /* TODO: Verify RGB value is correct */
+{{ 67, 86, 7}, "Dark Olive", ""}, /* Index 41 */
+{{253, 217, 222}, "Flesh Pink", ""}, /* Index 42 */ /* TODO: Verify RGB value is correct */
+{{249, 147, 188}, "Pink", ""}, /* Index 43 */
+{{ 0, 56, 34}, "Deep Green", ""}, /* Index 44 */
+{{178, 175, 212}, "Lavender", ""}, /* Index 45 */
+{{104, 106, 176}, "Wisteria Violet", ""}, /* Index 46 */
+{{239, 227, 185}, "Beige", ""}, /* Index 47 */
+{{247, 56, 102}, "Carmine", ""}, /* Index 48 */
+{{181, 75, 100}, "Amber Red", ""}, /* Index 49 */ /* TODO: Verify RGB value is correct */
+{{ 19, 43, 26}, "Olive Green", ""}, /* Index 50 */
+{{199, 1, 86}, "Dark Fuschia", ""}, /* Index 51 */ /* TODO: Verify RGB value is correct */
+{{254, 158, 50}, "Tangerine", ""}, /* Index 52 */
+{{168, 222, 235}, "Light Blue", ""}, /* Index 53 */
+{{ 0, 103, 62}, "Emerald Green", ""}, /* Index 54 */ /* TODO: Verify RGB value is correct */
+{{ 78, 41, 144}, "Purple", ""}, /* Index 55 */
+{{ 47, 126, 32}, "Moss Green", ""}, /* Index 56 */
+{{255, 204, 204}, "Flesh Pink", ""}, /* Index 57 */ /* TODO: Verify RGB value is correct */ /* TODO: Flesh Pink is Index 42, is this Index incorrect? */
+{{255, 217, 17}, "Harvest Gold", ""}, /* Index 58 */
+{{ 9, 91, 166}, "Electric Blue", ""}, /* Index 59 */
+{{240, 249, 112}, "Lemon Yellow", ""}, /* Index 60 */
+{{227, 243, 91}, "Fresh Green", ""}, /* Index 61 */
+{{255, 153, 0}, "Orange", ""}, /* Index 62 */ /* TODO: Verify RGB value is correct */ /* TODO: Orange is Index 12, is this Index incorrect? */
+{{255, 240, 141}, "Cream Yellow", ""}, /* Index 63 */ /* TODO: Verify RGB value is correct */ /* TODO: Cream Yellow is Index 34, is this Index incorrect? */
+{{255, 200, 200}, "Applique", ""} /* Index 64 */
+};
+
+static const char imageWithFrame[38][48] = {
+{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+{0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0},
+{0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0},
+{0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0},
+{0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0},
+{0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0},
+{0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0},
+{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
+};
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_PEC_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-pel.c b/Software/Visual_Studio/Embroidery/libembroidery/format-pel.c
new file mode 100644
index 000000000..9bdc6f3e7
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-pel.c
@@ -0,0 +1,35 @@
+#include "format-pel.h"
+#include "emb-logging.h"
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readPel(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-pel.c readPel(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-pel.c readPel(), fileName argument is null\n"); return 0; }
+ return 0; /*TODO: finish readPel */
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writePel(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-pel.c writePel(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-pel.c writePel(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-pel.c writePel(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writePel */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-pel.h b/Software/Visual_Studio/Embroidery/libembroidery/format-pel.h
new file mode 100644
index 000000000..bdca5b89c
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-pel.h
@@ -0,0 +1,22 @@
+/*! @file format-pel.h */
+#ifndef FORMAT_PEL_H
+#define FORMAT_PEL_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readPel(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writePel(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_PEL_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-pem.c b/Software/Visual_Studio/Embroidery/libembroidery/format-pem.c
new file mode 100644
index 000000000..f297d945d
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-pem.c
@@ -0,0 +1,35 @@
+#include "format-pem.h"
+#include "emb-logging.h"
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readPem(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-pem.c readPem(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-pem.c readPem(), fileName argument is null\n"); return 0; }
+ return 0; /*TODO: finish ReadPem */
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writePem(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-pem.c writePem(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-pem.c writePem(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-pem.c writePem(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writePem */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-pem.h b/Software/Visual_Studio/Embroidery/libembroidery/format-pem.h
new file mode 100644
index 000000000..685fea315
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-pem.h
@@ -0,0 +1,22 @@
+/*! @file format-pem.h */
+#ifndef FORMAT_PEM_H
+#define FORMAT_PEM_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readPem(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writePem(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_PEM_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-pes.c b/Software/Visual_Studio/Embroidery/libembroidery/format-pes.c
new file mode 100644
index 000000000..703b2460c
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-pes.c
@@ -0,0 +1,255 @@
+#include "format-pes.h"
+#include "format-pec.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+#include <stdlib.h>
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readPes(EmbPattern* pattern, const char* fileName)
+{
+ int pecstart, numColors, x;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-pes.c readPes(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-pes.c readPes(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-pes.c readPes(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embFile_seek(file, 8, SEEK_SET);
+ pecstart = binaryReadInt32(file);
+
+ embFile_seek(file, pecstart + 48, SEEK_SET);
+ numColors = embFile_getc(file) + 1;
+ for(x = 0; x < numColors; x++)
+ {
+ embPattern_addThread(pattern, pecThreads[(unsigned char) embFile_getc(file)]);
+ }
+
+ embFile_seek(file, pecstart + 532, SEEK_SET);
+ readPecStitches(pattern, file);
+
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ embPattern_flipVertical(pattern);
+
+ return 1;
+}
+
+static void pesWriteSewSegSection(EmbPattern* pattern, EmbFile* file)
+{
+ /* TODO: pointer safety */
+ EmbStitchList* pointer = 0;
+ EmbStitchList* mainPointer = 0;
+ short* colorInfo = 0;
+ int flag = 0;
+ int count = 0;
+ int colorCode = -1;
+ int stitchType = 0;
+ int blockCount = 0;
+ int colorCount = 0;
+ int newColorCode = 0;
+ int colorInfoIndex = 0;
+ int i;
+ EmbRect bounds = embPattern_calcBoundingBox(pattern);
+ EmbColor color;
+
+ mainPointer = pattern->stitchList;
+ while(mainPointer)
+ {
+ pointer = mainPointer;
+ flag = pointer->stitch.flags;
+ color = embThreadList_getAt(pattern->threadList, pointer->stitch.color).color;
+ newColorCode = embThread_findNearestColorInArray(color, (EmbThread*)pecThreads, pecThreadCount);
+ if(newColorCode != colorCode)
+ {
+ colorCount++;
+ colorCode = newColorCode;
+ }
+ while(pointer && (flag == pointer->stitch.flags))
+ {
+ count++;
+ pointer = pointer->next;
+ }
+ blockCount++;
+ mainPointer = pointer;
+ }
+
+ binaryWriteShort(file, (short)blockCount); /* block count */
+ binaryWriteUShort(file, 0xFFFF);
+ binaryWriteShort(file, 0x00);
+
+ binaryWriteShort(file, 0x07); /* string length */
+ binaryWriteBytes(file, "CSewSeg", 7);
+
+ colorInfo = (short *) calloc(colorCount * 2, sizeof(short));
+ mainPointer = pattern->stitchList;
+ colorCode = -1;
+ blockCount = 0;
+ while(mainPointer)
+ {
+ pointer = mainPointer;
+ flag = pointer->stitch.flags;
+ color = embThreadList_getAt(pattern->threadList, pointer->stitch.color).color;
+ newColorCode = embThread_findNearestColorInArray(color, (EmbThread*)pecThreads, pecThreadCount);
+ if(newColorCode != colorCode)
+ {
+ colorInfo[colorInfoIndex++] = (short)blockCount;
+ colorInfo[colorInfoIndex++] = (short)newColorCode;
+ colorCode = newColorCode;
+ }
+ count = 0;
+ while(pointer && (flag == pointer->stitch.flags))
+ {
+ count++;
+ pointer = pointer->next;
+ }
+ if(flag & JUMP)
+ {
+ stitchType = 1;
+ }
+ else
+ {
+ stitchType = 0;
+ }
+
+ binaryWriteShort(file, (short)stitchType); /* 1 for jump, 0 for normal */
+ binaryWriteShort(file, (short)colorCode); /* color code */
+ binaryWriteShort(file, (short)count); /* stitches in block */
+ pointer = mainPointer;
+ while(pointer && (flag == pointer->stitch.flags))
+ {
+ EmbStitch s = pointer->stitch;
+ binaryWriteShort(file, (short)(s.xx - bounds.left));
+ binaryWriteShort(file, (short)(s.yy + bounds.top));
+ pointer = pointer->next;
+ }
+ if(pointer)
+ {
+ binaryWriteShort(file, 0x8003);
+ }
+ blockCount++;
+ mainPointer = pointer;
+ }
+ binaryWriteShort(file, (short)colorCount);
+ for(i = 0; i < colorCount; i++)
+ {
+ binaryWriteShort(file, colorInfo[i * 2]);
+ binaryWriteShort(file, colorInfo[i * 2 + 1]);
+ }
+ binaryWriteInt(file, 0);
+ if(colorInfo)
+ {
+ free(colorInfo);
+ colorInfo = 0;
+ }
+}
+
+static void pesWriteEmbOneSection(EmbPattern* pattern, EmbFile* file)
+{
+ /* TODO: pointer safety */
+ int i;
+ int hoopHeight = 1800, hoopWidth = 1300;
+ EmbRect bounds;
+ binaryWriteShort(file, 0x07); /* string length */
+ binaryWriteBytes(file, "CEmbOne", 7);
+ bounds = embPattern_calcBoundingBox(pattern);
+
+ binaryWriteShort(file, 0);
+ binaryWriteShort(file, 0);
+ binaryWriteShort(file, 0);
+ binaryWriteShort(file, 0);
+
+ binaryWriteShort(file, 0);
+ binaryWriteShort(file, 0);
+ binaryWriteShort(file, 0);
+ binaryWriteShort(file, 0);
+
+ /* AffineTransform */
+ binaryWriteFloat(file, 1.0f);
+ binaryWriteFloat(file, 0.0f);
+ binaryWriteFloat(file, 0.0f);
+ binaryWriteFloat(file, 1.0f);
+ binaryWriteFloat(file, (float)((embRect_width(bounds) - hoopWidth) / 2));
+ binaryWriteFloat(file, (float)((embRect_height(bounds) + hoopHeight) / 2));
+
+ binaryWriteShort(file, 1);
+ binaryWriteShort(file, 0); /* Translate X */
+ binaryWriteShort(file, 0); /* Translate Y */
+ binaryWriteShort(file, (short)embRect_width(bounds));
+ binaryWriteShort(file, (short)embRect_height(bounds));
+
+ for(i = 0; i < 8; i++)
+ {
+ binaryWriteByte(file, 0);
+ }
+
+ /*WriteSubObjects(br, pes, SubBlocks); */
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writePes(EmbPattern* pattern, const char* fileName)
+{
+ int pecLocation;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-pes.c writePes(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-pes.c writePes(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "wb");
+ if(!file)
+ {
+ embLog_error("format-pes.c writePes(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+
+ if(!pattern->stitchList || embStitchList_count(pattern->stitchList) == 0) /* TODO: review this. seems like only embStitchList_count should be needed. */
+ {
+ embLog_error("format-pes.c writePes(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ embPattern_flipVertical(pattern);
+ embPattern_scale(pattern, 10.0);
+ binaryWriteBytes(file, "#PES0001", 8);
+ /* WRITE PECPointer 32 bit int */
+ binaryWriteInt(file, 0x00);
+
+ binaryWriteShort(file, 0x01);
+ binaryWriteShort(file, 0x01);
+
+ /* Write object count */
+ binaryWriteShort(file, 0x01);
+ binaryWriteShort(file, 0xFFFF); /* command */
+ binaryWriteShort(file, 0x00); /* unknown */
+
+ pesWriteEmbOneSection(pattern, file);
+ pesWriteSewSegSection(pattern, file);
+
+ pecLocation = embFile_tell(file);
+ embFile_seek(file, 0x08, SEEK_SET);
+ binaryWriteByte(file, (unsigned char)(pecLocation & 0xFF));
+ binaryWriteByte(file, (unsigned char)(pecLocation >> 8) & 0xFF);
+ binaryWriteByte(file, (unsigned char)(pecLocation >> 16) & 0xFF);
+ embFile_seek(file, 0x00, SEEK_END);
+ writePecStitches(pattern, file, fileName);
+ embFile_close(file);
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-pes.h b/Software/Visual_Studio/Embroidery/libembroidery/format-pes.h
new file mode 100644
index 000000000..e82404919
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-pes.h
@@ -0,0 +1,22 @@
+/*! @file format-pes.h */
+#ifndef FORMAT_PES_H
+#define FORMAT_PES_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readPes(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writePes(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_PES_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-phb.c b/Software/Visual_Studio/Embroidery/libembroidery/format-phb.c
new file mode 100644
index 000000000..66a3398bb
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-phb.c
@@ -0,0 +1,96 @@
+#include "format-phb.h"
+#include "format-pec.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readPhb(EmbPattern* pattern, const char* fileName)
+{
+ unsigned int fileOffset;
+ short colorCount;
+ EmbFile* file = 0;
+ int i;
+
+ if(!pattern) { embLog_error("format-phb.c readPhb(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-phb.c readPhb(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-phb.c readPhb(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embFile_seek(file, 0x71, SEEK_SET);
+ colorCount = binaryReadInt16(file);
+
+ for(i = 0; i < colorCount; i++)
+ {
+ EmbThread t = pecThreads[(int)binaryReadByte(file)];
+ embPattern_addThread(pattern, t);
+ }
+
+ /* TODO: check that file begins with #PHB */
+ embFile_seek(file, 0x54, SEEK_SET);
+ fileOffset = 0x52;
+ fileOffset += binaryReadUInt32(file);
+
+ embFile_seek(file, fileOffset, SEEK_SET);
+ fileOffset += binaryReadUInt32(file) + 2;
+
+ embFile_seek(file, fileOffset, SEEK_SET);
+ fileOffset += binaryReadUInt32(file);
+
+ embFile_seek(file, fileOffset + 14, SEEK_SET); /* 28 */
+
+ colorCount = (short)binaryReadByte(file);
+ for(i = 0; i< colorCount; i++)
+ {
+ binaryReadByte(file);
+ }
+ binaryReadInt32(file); /* bytes to end of file */
+ binaryReadInt32(file);
+ binaryReadByte(file);
+
+ binaryReadInt16(file);
+ binaryReadInt16(file);
+ binaryReadInt16(file);
+ binaryReadInt16(file);
+ binaryReadInt16(file);
+ binaryReadInt16(file);
+ readPecStitches(pattern, file);
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ embPattern_flipVertical(pattern);
+ return 1; /*TODO: finish ReadPhb */
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writePhb(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-phb.c writePhb(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-phb.c writePhb(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-phb.c writePhb(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writePhb */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-phb.h b/Software/Visual_Studio/Embroidery/libembroidery/format-phb.h
new file mode 100644
index 000000000..b05e938cd
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-phb.h
@@ -0,0 +1,22 @@
+/*! @file format-phb.h */
+#ifndef FORMAT_PHB_H
+#define FORMAT_PHB_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readPhb(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writePhb(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_PHB_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-phc.c b/Software/Visual_Studio/Embroidery/libembroidery/format-phc.c
new file mode 100644
index 000000000..59ad2c71a
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-phc.c
@@ -0,0 +1,82 @@
+#include "format-phc.h"
+#include "format-pec.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readPhc(EmbPattern* pattern, const char* fileName)
+{
+ int colorChanges, version, bytesInSection2;
+ unsigned short pecOffset, bytesInSection, bytesInSection3;
+ char pecAdd;
+ EmbFile* file = 0;
+ int i;
+
+ if(!pattern) { embLog_error("format-phc.c readPhc(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-phc.c readPhc(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-phc.c readPhc(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embFile_seek(file, 0x07, SEEK_SET);
+ version = binaryReadByte(file) - 0x30; /* converting from ansi number */
+ embFile_seek(file, 0x4D, SEEK_SET);
+ colorChanges = binaryReadUInt16(file);
+
+ for(i = 0; i < colorChanges; i++)
+ {
+ EmbThread t = pecThreads[(int)binaryReadByte(file)];
+ embPattern_addThread(pattern, t);
+ }
+ embFile_seek(file, 0x2B, SEEK_SET);
+ pecAdd = binaryReadByte(file);
+ binaryReadUInt32(file); /* file length */
+ pecOffset = binaryReadUInt16(file);
+ embFile_seek(file, pecOffset + pecAdd, SEEK_SET);
+ bytesInSection = binaryReadUInt16(file);
+ embFile_seek(file, bytesInSection, SEEK_CUR);
+ bytesInSection2 = binaryReadUInt32(file);
+ embFile_seek(file, bytesInSection2, SEEK_CUR);
+ bytesInSection3 = binaryReadUInt16(file);
+ embFile_seek(file, bytesInSection3 + 0x12, SEEK_CUR);
+
+ readPecStitches(pattern, file);
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ embPattern_flipVertical(pattern);
+ return 1; /*TODO: finish ReadPhc */
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writePhc(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-phc.c writePhc(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-phc.c writePhc(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-phc.c writePhc(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writePhc */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-phc.h b/Software/Visual_Studio/Embroidery/libembroidery/format-phc.h
new file mode 100644
index 000000000..f7dfcff90
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-phc.h
@@ -0,0 +1,22 @@
+/*! @file format-phc.h */
+#ifndef FORMAT_PHC_H
+#define FORMAT_PHC_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readPhc(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writePhc(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_PHC_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-plt.c b/Software/Visual_Studio/Embroidery/libembroidery/format-plt.c
new file mode 100644
index 000000000..0aa00272a
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-plt.c
@@ -0,0 +1,116 @@
+#include "format-plt.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+#include "helpers-misc.h"
+#include <stdio.h>
+#include <string.h>
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readPlt(EmbPattern* pattern, const char* fileName)
+{
+ double x, y;
+ double scalingFactor = 40;
+ char input[512];
+ FILE* file = 0;
+
+ if(!pattern) { embLog_error("format-plt.c readPlt(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-plt.c readPlt(), fileName argument is null\n"); return 0; }
+
+ file = fopen(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-plt.c readPlt(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embPattern_loadExternalColorFile(pattern, fileName);
+ /* TODO: replace all scanf code */
+ while(fscanf(file, "%s", input) >= 0)
+ {
+ if(startsWith("PD", input))
+ {
+ /* TODO: replace all scanf code */
+ if(sscanf(input, "PD%lf,%lf;", &x, &y) < 2)
+ {
+ break;
+ }
+ embPattern_addStitchAbs(pattern, x / scalingFactor, y / scalingFactor, NORMAL, 1);
+ }
+ else if(startsWith("PU", input))
+ {
+ /* TODO: replace all scanf code */
+ if(sscanf(input, "PU%lf,%lf;", &x, &y) < 2)
+ {
+ break;
+ }
+ embPattern_addStitchAbs(pattern, x / scalingFactor, y / scalingFactor, STOP, 1);
+ }
+ }
+ fclose(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writePlt(EmbPattern* pattern, const char* fileName)
+{
+ /* TODO: pointer safety */
+ double scalingFactor = 40;
+ EmbStitch stitch;
+ EmbStitchList* pointer = 0;
+ char firstStitchOfBlock = 1;
+ FILE* file = 0;
+
+ if(!pattern) { embLog_error("format-plt.c writePlt(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-plt.c writePlt(), fileName argument is null\n"); return 0; }
+
+ file = fopen(fileName, "wb");
+ if(!file)
+ {
+ embLog_error("format-plt.c writePlt(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+
+ fprintf(file, "IN;");
+ fprintf(file, "ND;");
+
+ pointer = pattern->stitchList;
+ while(pointer)
+ {
+ stitch = pointer->stitch;
+ if(stitch.flags & STOP)
+ {
+ firstStitchOfBlock = 1;
+ }
+ if(firstStitchOfBlock)
+ {
+ fprintf(file, "PU%f,%f;", stitch.xx * scalingFactor, stitch.yy * scalingFactor);
+ fprintf(file, "ST0.00,0.00;");
+ fprintf(file, "SP0;");
+ fprintf(file, "HT0;");
+ fprintf(file, "HS0;");
+ fprintf(file, "TT0;");
+ fprintf(file, "TS0;");
+ firstStitchOfBlock = 0;
+ }
+ else
+ {
+ fprintf(file, "PD%f,%f;", stitch.xx * scalingFactor, stitch.yy * scalingFactor);
+ }
+
+ pointer = pointer->next;
+ }
+ fprintf(file, "PU0.0,0.0;");
+ fprintf(file, "PU0.0,0.0;");
+ fclose(file);
+ return 1; /*TODO: finish WritePlt */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
+
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-plt.h b/Software/Visual_Studio/Embroidery/libembroidery/format-plt.h
new file mode 100644
index 000000000..453974eda
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-plt.h
@@ -0,0 +1,22 @@
+/*! @file format-plt.h */
+#ifndef FORMAT_PLT_H
+#define FORMAT_PLT_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readPlt(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writePlt(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_PLT_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-rgb.c b/Software/Visual_Studio/Embroidery/libembroidery/format-rgb.c
new file mode 100644
index 000000000..d7a57d69e
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-rgb.c
@@ -0,0 +1,76 @@
+#include "format-rgb.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+#include <stdlib.h>
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readRgb(EmbPattern* pattern, const char* fileName)
+{
+ int i, numberOfColors;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-rgb.c readRgb(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-rgb.c readRgb(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ /* NOTE: The .rgb format is an optional color file. Do not log an error if the file does not exist */
+ return 0;
+ }
+ embFile_seek(file, 0x00, SEEK_END);
+ numberOfColors = embFile_tell(file) / 4;
+
+ embThreadList_free(pattern->threadList);
+ pattern->threadList = 0;
+ pattern->lastThread = 0;
+
+ embFile_seek(file, 0x00, SEEK_SET);
+ for(i = 0; i < numberOfColors; i++)
+ {
+ EmbThread t;
+ t.color.r = binaryReadByte(file);
+ t.color.g = binaryReadByte(file);
+ t.color.b = binaryReadByte(file);
+ t.catalogNumber = "";
+ t.description = "";
+ binaryReadByte(file);
+ embPattern_addThread(pattern, t);
+ }
+ embFile_close(file);
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeRgb(EmbPattern* pattern, const char* fileName)
+{
+ EmbThreadList* colors = pattern->threadList;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-rgb.c writeRgb(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-rgb.c writeRgb(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "wb");
+ if(!file)
+ {
+ embLog_error("format-rgb.c writeRgb(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+
+ while(colors)
+ {
+ EmbColor c = colors->thread.color;
+ binaryWriteByte(file, c.r);
+ binaryWriteByte(file, c.g);
+ binaryWriteByte(file, c.b);
+ binaryWriteByte(file, 0);
+ colors = colors->next;
+ }
+ embFile_close(file);
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-rgb.h b/Software/Visual_Studio/Embroidery/libembroidery/format-rgb.h
new file mode 100644
index 000000000..b042e0ddb
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-rgb.h
@@ -0,0 +1,22 @@
+/*! @file format-rgb.h */
+#ifndef FORMAT_RGB_H
+#define FORMAT_RGB_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readRgb(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeRgb(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_RGB_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-sew.c b/Software/Visual_Studio/Embroidery/libembroidery/format-sew.c
new file mode 100644
index 000000000..212a9cd9c
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-sew.c
@@ -0,0 +1,210 @@
+#include "format-jef.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "emb-time.h"
+#include "helpers-binary.h"
+#include "helpers-misc.h"
+#include "emb-stitch.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+static char sewDecode(unsigned char inputByte)
+{
+ return (inputByte >= 0x80) ? (char) (-~(inputByte - 1)) : (char) inputByte; /* TODO: fix return statement */
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readSew(EmbPattern* pattern, const char* fileName)
+{
+ EmbFile* file = 0;
+ int i;
+ int fileLength;
+ char dx = 0, dy = 0;
+ int flags;
+ int numberOfColors;
+ char thisStitchIsJump = 0;
+
+ if(!pattern) { embLog_error("format-sew.c readSew(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-sew.c readSew(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-sew.c readSew(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embFile_seek(file, 0x00, SEEK_END);
+ fileLength = embFile_tell(file);
+ embFile_seek(file, 0x00, SEEK_SET);
+ numberOfColors = binaryReadByte(file);
+ numberOfColors += (binaryReadByte(file) << 8);
+
+ for(i = 0; i < numberOfColors; i++)
+ {
+ embPattern_addThread(pattern, jefThreads[binaryReadInt16(file)]);
+ }
+ embFile_seek(file, 0x1D78, SEEK_SET);
+
+ for(i = 0; embFile_tell(file) < fileLength; i++)
+ {
+ unsigned char b0 = binaryReadByte(file);
+ unsigned char b1 = binaryReadByte(file);
+
+ flags = NORMAL;
+ if(thisStitchIsJump)
+ {
+ flags = TRIM;
+ thisStitchIsJump = 0;
+ }
+ if(b0 == 0x80)
+ {
+ if(b1 == 1)
+ {
+ b0 = binaryReadByte(file);
+ b1 = binaryReadByte(file);
+ flags = STOP;
+ }
+ else if((b1 == 0x02) || (b1 == 0x04))
+ {
+ thisStitchIsJump = 1;
+ b0 = binaryReadByte(file);
+ b1 = binaryReadByte(file);
+ flags = TRIM;
+ }
+ else if(b1 == 0x10)
+ {
+ break;
+ }
+ }
+ dx = sewDecode(b0);
+ dy = sewDecode(b1);
+ if(abs(dx) == 127 || abs(dy) == 127)
+ {
+ thisStitchIsJump = 1;
+ flags = TRIM;
+ }
+
+ embPattern_addStitchRel(pattern, dx / 10.0, dy / 10.0, flags, 1);
+ }
+ printf("current position: %ld\n", embFile_tell(file));
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+static void sewEncode(unsigned char* b, char dx, char dy, int flags)
+{
+ if(!b)
+ {
+ embLog_error("format-exp.c expEncode(), b argument is null\n");
+ return;
+ }
+ if(flags == STOP)
+ {
+ b[0] = 0x80;
+ b[1] = 1;
+ b[2] = dx;
+ b[3] = dy;
+ }
+ else if (flags == END)
+ {
+ b[0] = 0x80;
+ b[1] = 0x10;
+ b[2] = 0;
+ b[3] = 0;
+ }
+ else if(flags == TRIM || flags == JUMP)
+ {
+ b[0] = 0x80;
+ b[1] = 2;
+ b[2] = dx;
+ b[3] = dy;
+ }
+ else
+ {
+ b[0] = dx;
+ b[1] = dy;
+ }
+}
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeSew(EmbPattern* pattern, const char* fileName)
+{
+ int colorlistSize, minColors, i;
+ EmbFile* file = 0;
+ EmbThreadList* threadPointer = 0;
+ EmbStitchList* stitches = 0;
+ double dx = 0.0, dy = 0.0;
+ double xx = 0.0, yy = 0.0;
+ int flags = 0;
+ unsigned char b[4];
+ if(!pattern) { embLog_error("format-sew.c writeSew(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-sew.c writeSew(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-sew.c writeSew(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if (pattern->lastStitch->stitch.flags != END)
+ {
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+ }
+ file = embFile_open(fileName, "wb");
+ if(!file)
+ {
+ embLog_error("format-sew.c writeJef(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+
+ colorlistSize = embThreadList_count(pattern->threadList);
+ minColors = max(colorlistSize, 6);
+ binaryWriteInt(file, 0x74 + (minColors * 4));
+ binaryWriteInt(file, 0x0A);
+
+ while(threadPointer)
+ {
+ binaryWriteInt(file, embThread_findNearestColorInArray(threadPointer->thread.color, (EmbThread*)jefThreads, 79));
+ threadPointer = threadPointer->next;
+ }
+ for(i = 0; i < (minColors - colorlistSize); i++)
+ {
+ binaryWriteInt(file, 0x0D);
+ }
+ for(i = 2; i < 7538; i++)
+ {
+ embFile_printf(file, " ");
+ }
+ stitches = pattern->stitchList;
+ while(stitches)
+ {
+ dx = stitches->stitch.xx * 10.0 - xx;
+ dy = stitches->stitch.yy * 10.0 - yy;
+ xx = stitches->stitch.xx * 10.0;
+ yy = stitches->stitch.yy * 10.0;
+ flags = stitches->stitch.flags;
+ sewEncode(b, (char)roundDouble(dx), (char)roundDouble(dy), flags);
+ if((b[0] == 0x80) && ((b[1] == 1) || (b[1] == 2) || (b[1] == 4) || (b[1] == 0x10)))
+ {
+ embFile_printf(file, "%c%c%c%c", b[0], b[1], b[2], b[3]);
+ }
+ else
+ {
+ binaryWriteByte(file, b[0]);
+ binaryWriteByte(file, b[1]);
+ }
+ stitches = stitches->next;
+ }
+ embFile_close(file);
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-sew.h b/Software/Visual_Studio/Embroidery/libembroidery/format-sew.h
new file mode 100644
index 000000000..fb4c3ab09
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-sew.h
@@ -0,0 +1,22 @@
+/*! @file format-sew.h */
+#ifndef FORMAT_SEW_H
+#define FORMAT_SEW_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readSew(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeSew(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_SEW_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-shv.c b/Software/Visual_Studio/Embroidery/libembroidery/format-shv.c
new file mode 100644
index 000000000..ae6c651a5
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-shv.c
@@ -0,0 +1,182 @@
+#include "format-shv.h"
+#include "format-jef.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+#include <string.h>
+
+static char shvDecode(unsigned char inputByte)
+{
+ if(inputByte >= 0x80)
+ {
+ return (char)-((unsigned char)((~inputByte) + 1));
+ }
+ return ((char)inputByte);
+}
+
+static short shvDecodeShort(unsigned short inputByte)
+{
+ if(inputByte > 0x8000)
+ {
+ return (short)-((unsigned short)((~inputByte) + 1));
+ }
+ return ((short)inputByte);
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readShv(EmbPattern* pattern, const char* fileName)
+{
+ EmbFile* file = 0;
+ int i;
+ char inJump = 0;
+ unsigned char fileNameLength, designWidth, designHeight;
+ char halfDesignWidth, halfDesignHeight, halfDesignWidth2, halfDesignHeight2;
+ char* headerText = "Embroidery disk created using software licensed from Viking Sewing Machines AB, Sweden";
+ char dx = 0, dy = 0;
+ char numberOfColors;
+ unsigned short magicCode;
+ int something;
+ short left,top,right,bottom;
+ char something2, numberOfSections, something3;
+ int stitchesPerColor[256];
+ int stitchesSinceChange = 0;
+ int currColorIndex = 0;
+ unsigned short sx, sy;
+
+ if(!pattern) { embLog_error("format-shv.c readShv(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-shv.c readShv(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-shv.c readShv(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embFile_seek(file, strlen(headerText), SEEK_SET);
+ fileNameLength = binaryReadUInt8(file);
+ embFile_seek(file, fileNameLength, SEEK_CUR);
+ designWidth = binaryReadUInt8(file);
+ designHeight = binaryReadUInt8(file);
+ halfDesignWidth = binaryReadUInt8(file);
+ halfDesignHeight = binaryReadUInt8(file);
+ halfDesignWidth2 = binaryReadUInt8(file);
+ halfDesignHeight2 = binaryReadUInt8(file);
+ if((designHeight % 2) == 1)
+ {
+ embFile_seek(file, ((designHeight + 1)*designWidth)/2, SEEK_CUR);
+ }
+ else
+ {
+ embFile_seek(file, (designHeight*designWidth)/2, SEEK_CUR);
+ }
+ numberOfColors = binaryReadUInt8(file);
+ magicCode = binaryReadUInt16(file);
+ binaryReadByte(file);
+ something = binaryReadInt32(file);
+ left = binaryReadInt16(file);
+ top = binaryReadInt16(file);
+ right = binaryReadInt16(file);
+ bottom = binaryReadInt16(file);
+
+ something2 = binaryReadByte(file);
+ numberOfSections = binaryReadUInt8(file);
+ something3 = binaryReadByte(file);
+
+ for(i = 0; i < numberOfColors; i++)
+ {
+ unsigned int stitchCount, colorNumber;
+ stitchCount = binaryReadUInt32BE(file);
+ colorNumber = binaryReadUInt8(file);
+ embPattern_addThread(pattern, shvThreads[colorNumber % 43]);
+ stitchesPerColor[i] = stitchCount;
+ embFile_seek(file, 9, SEEK_CUR);
+ }
+
+ embFile_seek(file, -2, SEEK_CUR);
+
+ for(i = 0; !embFile_eof(file); i++)
+ {
+ unsigned char b0, b1;
+ int flags;
+ if(inJump)
+ {
+ flags = JUMP;
+ }
+ else
+ {
+ flags = NORMAL;
+ }
+ b0 = binaryReadUInt8(file);
+ b1 = binaryReadUInt8(file);
+ if(stitchesSinceChange >= stitchesPerColor[currColorIndex])
+ {
+ embPattern_addStitchRel(pattern, 0, 0, STOP, 1);
+ currColorIndex++;
+ stitchesSinceChange = 0;
+ }
+ if(b0 == 0x80)
+ {
+ stitchesSinceChange++;
+ if(b1 == 3)
+ {
+ continue;
+ }
+ else if(b1 == 0x02)
+ {
+ inJump = 0;
+ continue;
+ }
+ else if(b1 == 0x01)
+ {
+ stitchesSinceChange += 2;
+ sx = binaryReadUInt8(file);
+ sx = (unsigned short)(sx << 8 | binaryReadUInt8(file));
+ sy = binaryReadUInt8(file);
+ sy = (unsigned short)(sy << 8 | binaryReadUInt8(file));
+ flags = TRIM;
+ inJump = 1;
+ embPattern_addStitchRel(pattern, shvDecodeShort(sx) / 10.0, shvDecodeShort(sy) / 10.0, flags, 1);
+ continue;
+ }
+ }
+ dx = shvDecode(b0);
+ dy = shvDecode(b1);
+ stitchesSinceChange++;
+ embPattern_addStitchRel(pattern, dx / 10.0, dy / 10.0, flags, 1);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ embPattern_flipVertical(pattern);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeShv(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-shv.c writeShv(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-shv.c writeShv(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-shv.c writeShv(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writeShv */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-shv.h b/Software/Visual_Studio/Embroidery/libembroidery/format-shv.h
new file mode 100644
index 000000000..a7e2a6e6e
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-shv.h
@@ -0,0 +1,71 @@
+/*! @file format-shv.h */
+#ifndef FORMAT_SHV_H
+#define FORMAT_SHV_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readShv(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeShv(EmbPattern* pattern, const char* fileName);
+/*****************************************
+ * SHV Colors
+ ****************************************/
+static const int shvThreadCount = 42;
+static const EmbThread shvThreads[] = {
+{{ 0, 0, 0 }, "Black", "TODO:CATALOG_NUMBER"},
+{{ 0, 0, 255 }, "Blue", "TODO:CATALOG_NUMBER"},
+{{ 51, 204, 102 }, "Green", "TODO:CATALOG_NUMBER"},
+{{ 255, 0, 0 }, "Red", "TODO:CATALOG_NUMBER"},
+{{ 255, 0, 255 }, "Purple", "TODO:CATALOG_NUMBER"},
+{{ 255, 255, 0 }, "Yellow", "TODO:CATALOG_NUMBER"},
+{{ 127, 127, 127 }, "Grey", "TODO:CATALOG_NUMBER"},
+{{ 51, 154, 255 }, "Light Blue", "TODO:CATALOG_NUMBER"},
+{{ 0, 255, 0 }, "Light Green", "TODO:CATALOG_NUMBER"},
+{{ 255, 127, 0 }, "Orange", "TODO:CATALOG_NUMBER"},
+{{ 255, 160, 180 }, "Pink", "TODO:CATALOG_NUMBER"},
+{{ 153, 75, 0 }, "Brown", "TODO:CATALOG_NUMBER"},
+{{ 255, 255, 255 }, "White", "TODO:CATALOG_NUMBER"},
+{{ 0, 0, 0 }, "Black", "TODO:CATALOG_NUMBER"},
+{{ 0, 0, 0 }, "Black", "TODO:CATALOG_NUMBER"},
+{{ 0, 0, 0 }, "Black", "TODO:CATALOG_NUMBER"},
+{{ 0, 0, 0 }, "Black", "TODO:CATALOG_NUMBER"},
+{{ 0, 0, 0 }, "Black", "TODO:CATALOG_NUMBER"},
+{{ 0, 0, 0 }, "Black", "TODO:CATALOG_NUMBER"},
+{{ 255, 127, 127 }, "Light Red", "TODO:CATALOG_NUMBER"},
+{{ 255, 127, 255 }, "Light Purple", "TODO:CATALOG_NUMBER"},
+{{ 255, 255, 153 }, "Light Yellow", "TODO:CATALOG_NUMBER"},
+{{ 192, 192, 192 }, "Light Grey", "TODO:CATALOG_NUMBER"},
+{{ 0, 0, 0 }, "Black", "TODO:CATALOG_NUMBER"},
+{{ 0, 0, 0 }, "Black", "TODO:CATALOG_NUMBER"},
+{{ 255, 165, 65 }, "Light Orange", "TODO:CATALOG_NUMBER"},
+{{ 255, 204, 204 }, "Light Pink", "TODO:CATALOG_NUMBER"},
+{{ 175, 90, 10 }, "Light Brown", "TODO:CATALOG_NUMBER"},
+{{ 0, 0, 0 }, "Black", "TODO:CATALOG_NUMBER"},
+{{ 0, 0, 0 }, "Black", "TODO:CATALOG_NUMBER"},
+{{ 0, 0, 0 }, "Black", "TODO:CATALOG_NUMBER"},
+{{ 0, 0, 0 }, "Black", "TODO:CATALOG_NUMBER"},
+{{ 0, 0, 0 }, "Black", "TODO:CATALOG_NUMBER"},
+{{ 0, 0, 127 }, "Dark Blue", "TODO:CATALOG_NUMBER"},
+{{ 0, 127, 0 }, "Dark Green", "TODO:CATALOG_NUMBER"},
+{{ 127, 0, 0 }, "Dark Red", "TODO:CATALOG_NUMBER"},
+{{ 127, 0, 127 }, "Dark Purple", "TODO:CATALOG_NUMBER"},
+{{ 200, 200, 0 }, "Dark Yellow", "TODO:CATALOG_NUMBER"},
+{{ 60, 60, 60 }, "Dark Gray", "TODO:CATALOG_NUMBER"},
+{{ 0, 0, 0 }, "Black", "TODO:CATALOG_NUMBER"},
+{{ 0, 0, 0 }, "Black", "TODO:CATALOG_NUMBER"},
+{{ 232, 63, 0 }, "Dark Orange", "TODO:CATALOG_NUMBER"},
+{{ 255, 102, 122 }, "Dark Pink", "TODO:CATALOG_NUMBER"}
+};
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_SHV_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-sst.c b/Software/Visual_Studio/Embroidery/libembroidery/format-sst.c
new file mode 100644
index 000000000..685c63e5b
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-sst.c
@@ -0,0 +1,83 @@
+#include "format-sst.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readSst(EmbPattern* pattern, const char* fileName)
+{
+ int fileLength;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-sst.c readSst(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-sst.c readSst(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-sst.c readSst(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embPattern_loadExternalColorFile(pattern, fileName);
+ embFile_seek(file, 0, SEEK_END);
+ fileLength = embFile_tell(file);
+ embFile_seek(file, 0xA0, SEEK_SET); /* skip the all zero header */
+ while(embFile_tell(file) < fileLength)
+ {
+ int stitchType = NORMAL;
+
+ int b1 = (int) binaryReadByte(file);
+ int b2 = (int) binaryReadByte(file);
+ unsigned char commandByte = binaryReadByte(file);
+
+ if(commandByte == 0x04)
+ {
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+ break;
+ }
+
+ if((commandByte & 0x01) == 0x01)
+ stitchType = STOP;
+ if((commandByte & 0x02) == 0x02)
+ stitchType = JUMP;
+ if((commandByte & 0x10) != 0x10)
+ b2 = -b2;
+ if((commandByte & 0x40) == 0x40)
+ b1 = -b1;
+ embPattern_addStitchRel(pattern, b1 / 10.0, b2 / 10.0, stitchType, 1);
+ }
+
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1; /*TODO: finish readSst */
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeSst(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-sst.c writeSst(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-sst.c writeSst(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-sst.c writeSst(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writeSst */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-sst.h b/Software/Visual_Studio/Embroidery/libembroidery/format-sst.h
new file mode 100644
index 000000000..59f2d5c69
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-sst.h
@@ -0,0 +1,22 @@
+/*! @file format-sst.h */
+#ifndef FORMAT_SST_H
+#define FORMAT_SST_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readSst(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeSst(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_SST_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-stx.c b/Software/Visual_Studio/Embroidery/libembroidery/format-stx.c
new file mode 100644
index 000000000..dcf766ae0
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-stx.c
@@ -0,0 +1,262 @@
+#include "format-stx.h"
+#include "helpers-binary.h"
+#include "helpers-misc.h"
+#include "helpers-unused.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include <stdlib.h>
+#include <string.h>
+
+typedef struct SubDescriptor_
+{
+ int someNum; /* TODO: better variable naming */
+ int someInt; /* TODO: better variable naming */
+ int someOtherInt; /* TODO: better variable naming */
+ char* colorCode;
+ char* colorName;
+} SubDescriptor;
+
+typedef struct StxThread_
+{
+ char* colorCode;
+ char* colorName;
+ char* sectionName;
+ SubDescriptor* subDescriptors;
+ EmbColor stxColor;
+} StxThread;
+
+static int stxReadThread(StxThread* thread, EmbFile* file)
+{
+ int j, colorNameLength, sectionNameLength;
+ int somethingSomething, somethingSomething2, somethingElse, numberOfOtherDescriptors; /* TODO: determine what these represent */
+ int codeLength = 0;
+ char* codeBuff = 0;
+ char* codeNameBuff = 0;
+ char* sectionNameBuff = 0;
+ EmbColor col;
+ unsigned char whatIsthis; /* TODO: determine what this represents */
+
+ if(!thread) { embLog_error("format-stx.c stxReadThread(), thread argument is null\n"); return 0; }
+ if(!file) { embLog_error("format-stx.c stxReadThread(), file argument is null\n"); return 0; }
+
+ codeLength = binaryReadUInt8(file);
+ codeBuff = (char*)malloc(codeLength);
+ if(!codeBuff) { embLog_error("format-stx.c stxReadThread(), unable to allocate memory for codeBuff\n"); return 0; }
+ binaryReadBytes(file, (unsigned char*)codeBuff, codeLength); /* TODO: check return value */
+ thread->colorCode = codeBuff;
+ colorNameLength = binaryReadUInt8(file);
+ codeNameBuff = (char*)malloc(colorNameLength);
+ if(!codeNameBuff) { embLog_error("format-stx.c stxReadThread(), unable to allocate memory for codeNameBuff\n"); return 0; }
+ binaryReadBytes(file, (unsigned char*)codeNameBuff, colorNameLength); /* TODO: check return value */
+ thread->colorName = codeNameBuff;
+
+ col.r = binaryReadUInt8(file);
+ col.b = binaryReadUInt8(file);
+ col.g = binaryReadUInt8(file);
+
+ whatIsthis = binaryReadUInt8(file);
+
+ sectionNameLength = binaryReadUInt8(file);
+ sectionNameBuff = (char*)malloc(sectionNameLength);
+ if(!sectionNameBuff) { embLog_error("format-stx.c stxReadThread(), unable to allocate memory for sectionNameBuff\n"); return 0; }
+ binaryReadBytes(file, (unsigned char*)sectionNameBuff, sectionNameLength); /* TODO: check return value */
+ thread->sectionName = sectionNameBuff;
+
+ somethingSomething = binaryReadInt32(file);
+ somethingSomething2 = binaryReadInt32(file);
+ somethingElse = binaryReadInt32(file);
+ numberOfOtherDescriptors = binaryReadInt16(file);
+
+ thread->subDescriptors = (SubDescriptor*)malloc(sizeof(SubDescriptor) * numberOfOtherDescriptors);
+ if(!thread->subDescriptors) { embLog_error("format-stx.c stxReadThread(), unable to allocate memory for thread->subDescriptors\n"); return 0; }
+ for(j = 0; j < numberOfOtherDescriptors; j++)
+ {
+ SubDescriptor sd;
+ char* subCodeBuff, *subColorNameBuff;
+ int subCodeLength, subColorNameLength;
+
+ sd.someNum = binaryReadInt16(file);
+ /* Debug.Assert(sd.someNum == 1); TODO: review */
+ sd.someInt = binaryReadInt32(file);
+ subCodeLength = binaryReadUInt8(file);
+ subCodeBuff = (char*)malloc(subCodeLength);
+ if(!subCodeBuff) { embLog_error("format-stx.c stxReadThread(), unable to allocate memory for subCodeBuff\n"); return 0; }
+ binaryReadBytes(file, (unsigned char*)subCodeBuff, subCodeLength); /* TODO: check return value */
+ sd.colorCode = subCodeBuff;
+ subColorNameLength = binaryReadUInt8(file);
+ subColorNameBuff = (char*)malloc(subColorNameLength);
+ if(!subColorNameBuff) { embLog_error("format-stx.c stxReadThread(), unable to allocate memory for subColorNameBuff\n"); return 0; }
+ binaryReadBytes(file, (unsigned char*)subColorNameBuff, subColorNameLength); /* TODO: check return value */
+ sd.colorName = subColorNameBuff;
+ sd.someOtherInt = binaryReadInt32(file);
+ thread->subDescriptors[j] = sd;
+ }
+ return 1;
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readStx(EmbPattern* pattern, const char* fileName)
+{
+ int i, threadCount;
+ unsigned char* gif = 0;
+ /* public Bitmap Image; */
+ StxThread* stxThreads = 0;
+ unsigned char headerBytes[7];
+ char* header = 0;
+ char filetype[4], version[5];
+ int paletteLength, imageLength, something1, stitchDataOffset, something3, threadDescriptionOffset, stitchCount, left, right, colors;
+ int val1, val2, val3, val4, val5, val6;
+
+ int vala1, vala2, vala3, vala4, vala5, vala6;
+ int bottom,top;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-stx.c readStx(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-stx.c readStx(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-stx.c readStx(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ binaryReadBytes(file, headerBytes, 7); /* TODO: check return value */
+ header = (char*)headerBytes;
+
+ memcpy(filetype, &header[0], 3);
+ memcpy(version, &header[3], 4);
+ filetype[3] = '\0';
+ version[4] = '\0';
+ binaryReadByte(file);
+ paletteLength = binaryReadInt32(file);
+ imageLength = binaryReadInt32(file);
+ something1 = binaryReadInt32(file);
+ stitchDataOffset = binaryReadInt32(file);
+ something3 = binaryReadInt32(file);
+ threadDescriptionOffset = binaryReadInt32(file);
+ stitchCount = binaryReadInt32(file);
+ colors = binaryReadInt32(file);
+ right = binaryReadInt16(file);
+ left = binaryReadInt16(file);
+ bottom = binaryReadInt16(file);
+ top = binaryReadInt16(file);
+
+ gif = (unsigned char*)malloc(imageLength);
+ if(!gif) { embLog_error("format-stx.c readStx(), unable to allocate memory for gif\n"); return 0; }
+ binaryReadBytes(file, gif, imageLength); /* TODO: check return value */
+ /*Stream s2 = new MemoryStream(gif); TODO: review */
+ /*Image = new Bitmap(s2); TODO: review */
+
+ threadCount = binaryReadInt16(file);
+ stxThreads = (StxThread*)malloc(sizeof(StxThread) * threadCount);
+ if(!stxThreads) { embLog_error("format-stx.c readStx(), unable to allocate memory for stxThreads\n"); return 0; }
+ for(i = 0; i < threadCount; i++)
+ {
+ EmbThread t;
+ StxThread st;
+ stxReadThread(&st, file);
+
+ t.color.r = st.stxColor.r;
+ t.color.g = st.stxColor.g;
+ t.color.b = st.stxColor.b;
+ t.description = st.colorName;
+ t.catalogNumber = st.colorCode;
+ embPattern_addThread(pattern, t);
+ stxThreads[i] = st;
+ }
+
+ binaryReadInt32(file);
+ binaryReadInt32(file);
+ binaryReadInt32(file);
+ binaryReadInt16(file);
+ binaryReadUInt8(file);
+
+ val1 = binaryReadInt16(file);
+ val2 = binaryReadInt16(file);
+ val3 = binaryReadInt16(file);
+ val4 = binaryReadInt16(file);
+
+ val5 = binaryReadInt16(file); /* 0 */
+ val6 = binaryReadInt16(file); /* 0 */
+
+ vala1 = binaryReadInt16(file);
+ vala2 = binaryReadInt16(file);
+ vala3 = binaryReadInt16(file);
+ vala4 = binaryReadInt16(file);
+ vala5 = binaryReadInt16(file); /* 0 */
+ vala6 = binaryReadInt16(file); /* 0 */
+
+ binaryReadInt32(file); /* 0 */
+ binaryReadInt32(file); /* 0 */
+
+ /* br.BaseStream.Position = stitchDataOffset; TODO: review */
+ for(i = 1; i < stitchCount; )
+ {
+ char b0 = binaryReadByte(file);
+ char b1 = binaryReadByte(file);
+ if(b0 == -128)
+ {
+ switch(b1)
+ {
+ case 1:
+ b0 = binaryReadByte(file);
+ b1 = binaryReadByte(file);
+ /*embPattern_addStitchRel(b0, b1, STOP); TODO: review */
+
+ i++;
+ break;
+ case 2:
+ b0 = binaryReadByte(file);
+ b1 = binaryReadByte(file);
+ embPattern_addStitchRel(pattern, b0 / 10.0, b1 / 10.0, JUMP, 1);
+ i++;
+ break;
+ case -94:
+ /* TODO: Is this a syncronize? If so document it in the comments. */
+ break;
+ default:
+ /*Debugger.Break(); TODO: review */
+ break;
+ }
+ }
+ else
+ {
+ embPattern_addStitchRel(pattern, b0 / 10.0, b1 / 10.0, NORMAL, 1);
+ i++;
+ }
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ embPattern_flipVertical(pattern);
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeStx(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-stx.c writeStx(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-stx.c writeStx(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-stx.c writeStx(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writeStx */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-stx.h b/Software/Visual_Studio/Embroidery/libembroidery/format-stx.h
new file mode 100644
index 000000000..bef405bdd
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-stx.h
@@ -0,0 +1,22 @@
+/*! @file format-stx.h */
+#ifndef FORMAT_STX_H
+#define FORMAT_STX_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readStx(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeStx(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_STX_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-svg.c b/Software/Visual_Studio/Embroidery/libembroidery/format-svg.c
new file mode 100644
index 000000000..817601f8b
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-svg.c
@@ -0,0 +1,3638 @@
+#include "format-svg.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-misc.h"
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+EmbColor svgColorToEmbColor(char* colorString)
+{
+ unsigned char r = 0;
+ unsigned char g = 0;
+ unsigned char b = 0;
+ int i = 0;
+ char* pEnd = 0;
+ char* colorStr = copy_trim(colorString); /* Trim out any junk spaces */
+ int length = strlen(colorStr);
+
+ /* SVGTiny1.2 Spec Section 11.13.1 syntax for color values */
+ if(length == 7 && colorStr[0] == '#') /* Six digit hex — #rrggbb */
+ {
+ EmbColor hexColor = embColor_fromHexStr(lTrim(colorStr, '#'));
+ r = hexColor.r;
+ g = hexColor.g;
+ b = hexColor.b;
+ }
+ else if(length == 4 && colorStr[0] == '#') /* Three digit hex — #rgb */
+ {
+ EmbColor hexColor;
+ /* Convert the 3 digit hex to a six digit hex */
+ char hex[7];
+ hex[0] = colorStr[1];
+ hex[1] = colorStr[1];
+ hex[2] = colorStr[2];
+ hex[3] = colorStr[2];
+ hex[4] = colorStr[3];
+ hex[5] = colorStr[3];
+ hex[6] = 0;
+
+ hexColor = embColor_fromHexStr(hex);
+ r = hexColor.r;
+ g = hexColor.g;
+ b = hexColor.b;
+ }
+ else if(strstr(colorStr, "%")) /* Float functional — rgb(R%, G%, B%) */
+ {
+ for(i = 0; i < length; i++)
+ {
+ if(colorStr[i] == 'r') colorStr[i] = ' ';
+ if(colorStr[i] == 'g') colorStr[i] = ' ';
+ if(colorStr[i] == 'b') colorStr[i] = ' ';
+ if(colorStr[i] == ',') colorStr[i] = ' ';
+ if(colorStr[i] == '(') colorStr[i] = ' ';
+ if(colorStr[i] == ')') colorStr[i] = ' ';
+ if(colorStr[i] == '%') colorStr[i] = ' ';
+ }
+ r = (unsigned char)roundDouble(255.0/100.0 * strtod(colorStr, &pEnd));
+ g = (unsigned char)roundDouble(255.0/100.0 * strtod(pEnd, &pEnd));
+ b = (unsigned char)roundDouble(255.0/100.0 * strtod(pEnd, &pEnd));
+ }
+ else if(length > 3 && startsWith("rgb", colorStr)) /* Integer functional — rgb(rrr, ggg, bbb) */
+ {
+ for(i = 0; i < length; i++)
+ {
+ if(colorStr[i] == 'r') colorStr[i] = ' ';
+ if(colorStr[i] == 'g') colorStr[i] = ' ';
+ if(colorStr[i] == 'b') colorStr[i] = ' ';
+ if(colorStr[i] == ',') colorStr[i] = ' ';
+ if(colorStr[i] == '(') colorStr[i] = ' ';
+ if(colorStr[i] == ')') colorStr[i] = ' ';
+ }
+ r = (unsigned char)strtol(colorStr, &pEnd, 10);
+ g = (unsigned char)strtol(pEnd, &pEnd, 10);
+ b = (unsigned char)strtol(pEnd, &pEnd, 10);
+ }
+ else /* Color keyword */
+ {
+ if (!strcmp(colorStr, "black")) { r = 0; g = 0; b = 0; }
+ else if(!strcmp(colorStr, "silver")) { r = 192; g = 192; b = 192; }
+ else if(!strcmp(colorStr, "gray")) { r = 128; g = 128; b = 128; }
+ else if(!strcmp(colorStr, "white")) { r = 255; g = 255; b = 255; }
+ else if(!strcmp(colorStr, "maroon")) { r = 128; g = 0; b = 0; }
+ else if(!strcmp(colorStr, "red")) { r = 255; g = 0; b = 0; }
+ else if(!strcmp(colorStr, "purple")) { r = 128; g = 0; b = 128; }
+ else if(!strcmp(colorStr, "fuchsia")) { r = 255; g = 0; b = 255; }
+ else if(!strcmp(colorStr, "green")) { r = 0; g = 128; b = 0; }
+ else if(!strcmp(colorStr, "lime")) { r = 0; g = 255; b = 0; }
+ else if(!strcmp(colorStr, "olive")) { r = 128; g = 128; b = 0; }
+ else if(!strcmp(colorStr, "yellow")) { r = 255; g = 255; b = 0; }
+ else if(!strcmp(colorStr, "navy")) { r = 0; g = 0; b = 128; }
+ else if(!strcmp(colorStr, "blue")) { r = 0; g = 0; b = 255; }
+ else if(!strcmp(colorStr, "teal")) { r = 0; g = 128; b = 128; }
+ else if(!strcmp(colorStr, "aqua")) { r = 0; g = 255; b = 255; }
+ }
+
+ free(colorStr);
+ /* Returns black if all else fails */
+ return embColor_make(r, g, b);
+}
+
+EmbFlag svgPathCmdToEmbPathFlag(char cmd)
+{
+ /* TODO: This function needs some work */
+ /*
+ if (toUpper(cmd) == 'M') return MOVETO;
+ else if(toUpper(cmd) == 'L') return LINETO;
+ else if(toUpper(cmd) == 'C') return CUBICTOCONTROL1;
+ else if(toUpper(cmd) == 'CC') return CUBICTOCONTROL2;
+ else if(toUpper(cmd) == 'CCC') return CUBICTOEND;
+ else if(toUpper(cmd) == 'A') return ELLIPSETORAD;
+ else if(toUpper(cmd) == 'AA') return ELLIPSETOEND;
+ else if(toUpper(cmd) == 'Q') return QUADTOCONTROL;
+ else if(toUpper(cmd) == 'QQ') return QUADTOEND;
+ else if(toUpper(cmd) == 'Z') return LINETO;
+ */
+
+ /*else if(toUpper(cmd) == 'B') return BULGETOCONTROL; /* NOTE: This is not part of the SVG spec, but hopefully Bulges will be added to the SVG spec someday */
+ /*else if(toUpper(cmd) == 'BB') return BULGETOEND; /* NOTE: This is not part of the SVG spec, but hopefully Bulges will be added to the SVG spec someday */
+ /*else { embLog_error("format-svg.c svgPathCmdToEmbPathFlag(), unknown command '%c'\n", cmd); return MOVETO; } */
+
+ return LINETO;
+}
+
+SvgAttribute svgAttribute_create(const char* name, const char* value)
+{
+ SvgAttribute attribute;
+ char* modValue = 0;
+ int last = 0;
+ int i = 0;
+
+ modValue = emb_strdup(value);
+ last = strlen(modValue);
+ for(i = 0; i < last; i++)
+ {
+ if(modValue[i] == '"') modValue[i] = ' ';
+ if(modValue[i] == '\'') modValue[i] = ' ';
+ if(modValue[i] == '/') modValue[i] = ' ';
+ if(modValue[i] == ',') modValue[i] = ' ';
+ }
+ attribute.name = emb_strdup(name);
+ attribute.value = modValue;
+ return attribute;
+}
+
+void svgElement_addAttribute(SvgElement* element, SvgAttribute data)
+{
+ if(!element) { embLog_error("format-svg.c svgElement_addAttribute(), element argument is null\n"); return; }
+
+ if(!(element->attributeList))
+ {
+ element->attributeList = (SvgAttributeList*)malloc(sizeof(SvgAttributeList));
+ if(!(element->attributeList)) { embLog_error("format-svg.c svgElement_addAttribute(), cannot allocate memory for element->attributeList\n"); return; }
+ element->attributeList->attribute = data;
+ element->attributeList->next = 0;
+ element->lastAttribute = element->attributeList;
+ element->lastAttribute->next = 0;
+ }
+ else
+ {
+ SvgAttributeList* pointerLast = element->lastAttribute;
+ SvgAttributeList* list = (SvgAttributeList*)malloc(sizeof(SvgAttributeList));
+ if(!list) { embLog_error("format-svg.c svgElement_addAttribute(), cannot allocate memory for list\n"); return; }
+ list->attribute = data;
+ list->next = 0;
+ pointerLast->next = list;
+ element->lastAttribute = list;
+ }
+}
+
+void svgElement_free(SvgElement* element)
+{
+ SvgAttributeList* list = 0;
+ SvgAttributeList* nextList = 0;
+ if(!element) return;
+
+ list = element->attributeList;
+
+ while(list)
+ {
+ free(list->attribute.name);
+ list->attribute.name = 0;
+ free(list->attribute.value);
+ list->attribute.value = 0;
+ nextList = list->next;
+ free(list);
+ list = 0;
+ list = nextList;
+ }
+
+ element->lastAttribute = 0;
+ free(element->name);
+ element->name = 0;
+ free(element);
+ element = 0;
+}
+
+SvgElement* svgElement_create(const char* name)
+{
+ SvgElement* element = 0;
+
+ element = (SvgElement*)malloc(sizeof(SvgElement));
+ if(!element) { embLog_error("format-svg.c svgElement_create(), cannot allocate memory for element\n"); return 0; }
+ element->name = emb_strdup(name);
+ if(!element->name) { embLog_error("format-svg.c svgElement_create(), element->name is null\n"); return 0; }
+ element->attributeList = 0;
+ element->lastAttribute = 0;
+ return element;
+}
+
+char* svgAttribute_getValue(SvgElement* element, const char* name)
+{
+ SvgAttributeList* pointer = 0;
+
+ if(!element) { embLog_error("format-svg.c svgAttribute_getValue(), element argument is null\n"); return "none"; }
+ if(!name) { embLog_error("format-svg.c svgAttribute_getValue(), name argument is null\n"); return "none"; }
+ if(!element->attributeList) { /* TODO: error */ return "none"; }
+
+ pointer = element->attributeList;
+ while(pointer)
+ {
+ if(!strcmp(pointer->attribute.name, name)) { return pointer->attribute.value; }
+ pointer = pointer->next;
+ }
+
+ return "none";
+}
+
+void svgAddToPattern(EmbPattern* p)
+{
+ const char* buff = 0;
+
+ if(!p) { embLog_error("format-svg.c svgAddToPattern(), p argument is null\n"); return; }
+ if(!currentElement) { return; }
+
+ buff = currentElement->name;
+ if(!buff) { return; }
+
+ if (!strcmp(buff, "?xml")) { }
+ else if(!strcmp(buff, "a")) { }
+ else if(!strcmp(buff, "animate")) { }
+ else if(!strcmp(buff, "animateColor")) { }
+ else if(!strcmp(buff, "animateMotion")) { }
+ else if(!strcmp(buff, "animateTransform")) { }
+ else if(!strcmp(buff, "animation")) { }
+ else if(!strcmp(buff, "audio")) { }
+ else if(!strcmp(buff, "circle"))
+ {
+ embPattern_addCircleObjectAbs(p, atof(svgAttribute_getValue(currentElement, "cx")),
+ atof(svgAttribute_getValue(currentElement, "cy")),
+ atof(svgAttribute_getValue(currentElement, "r")));
+ }
+ else if(!strcmp(buff, "defs")) { }
+ else if(!strcmp(buff, "desc")) { }
+ else if(!strcmp(buff, "discard")) { }
+ else if(!strcmp(buff, "ellipse"))
+ {
+ embPattern_addEllipseObjectAbs(p, atof(svgAttribute_getValue(currentElement, "cx")),
+ atof(svgAttribute_getValue(currentElement, "cy")),
+ atof(svgAttribute_getValue(currentElement, "rx")),
+ atof(svgAttribute_getValue(currentElement, "ry")));
+ }
+ else if(!strcmp(buff, "font")) { }
+ else if(!strcmp(buff, "font-face")) { }
+ else if(!strcmp(buff, "font-face-src")) { }
+ else if(!strcmp(buff, "font-face-uri")) { }
+ else if(!strcmp(buff, "foreignObject")) { }
+ else if(!strcmp(buff, "g")) { }
+ else if(!strcmp(buff, "glyph")) { }
+ else if(!strcmp(buff, "handler")) { }
+ else if(!strcmp(buff, "hkern")) { }
+ else if(!strcmp(buff, "image")) { }
+ else if(!strcmp(buff, "line"))
+ {
+ char* x1 = svgAttribute_getValue(currentElement, "x1");
+ char* y1 = svgAttribute_getValue(currentElement, "y1");
+ char* x2 = svgAttribute_getValue(currentElement, "x2");
+ char* y2 = svgAttribute_getValue(currentElement, "y2");
+
+ /* If the starting and ending points are the same, it is a point */
+ if(!strcmp(x1, x2) && !strcmp(y1, y2))
+ embPattern_addPointObjectAbs(p, atof(x1), atof(y1));
+ else
+ embPattern_addLineObjectAbs(p, atof(x1), atof(y1), atof(x2), atof(y2));
+ }
+ else if(!strcmp(buff, "linearGradient")) { }
+ else if(!strcmp(buff, "listener")) { }
+ else if(!strcmp(buff, "metadata")) { }
+ else if(!strcmp(buff, "missing-glyph")) { }
+ else if(!strcmp(buff, "mpath")) { }
+ else if(!strcmp(buff, "path"))
+ {
+ /* TODO: finish */
+
+ char* pointStr = svgAttribute_getValue(currentElement, "d");
+ char* mystrok = svgAttribute_getValue(currentElement, "stroke");
+
+ int last = strlen(pointStr);
+ int size = 32;
+ int i = 0;
+ int j = 0;
+ int pos = 0;
+ /* An odometer aka 'tripometer' used for stepping thru the pathData */
+ int trip = -1; /* count of float[] that has been filled. 0=first item of array, -1=not filled = empty array */
+ int reset = -1;
+ double xx = 0.0;
+ double yy = 0.0;
+ double fx = 0.0;
+ double fy = 0.0;
+ double lx = 0.0;
+ double ly = 0.0;
+ double cx1 = 0.0, cx2 = 0.0;
+ double cy1 = 0.0, cy2 = 0.0;
+ int cmd = 0;
+ double pathData[7];
+ unsigned int numMoves = 0;
+ int pendingTask = 0;
+ int relative = 0;
+
+ EmbPointList* startOfPointList = 0;
+ EmbPointList* pathObjPointList = 0;
+ EmbFlagList* startOfFlagList = 0;
+ EmbFlagList* pathObjFlagList = 0;
+
+ char* pathbuff = 0;
+ pathbuff = (char*)malloc(size);
+ if(!pathbuff) { embLog_error("format-svg.c svgAddToPattern(), cannot allocate memory for pathbuff\n"); return; }
+
+ printf("stroke:%s\n", mystrok);
+
+ /* M44.219,26.365c0,10.306-8.354,18.659-18.652,18.659c-10.299,0-18.663-8.354-18.663-18.659c0-10.305,8.354-18.659,18.659-18.659C35.867,7.707,44.219,16.06,44.219,26.365z */
+ for(i = 0; i < last; i++)
+ {
+ char c = pointStr[i];
+ switch(c)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '.':
+ pathbuff[pos++] = (char)c; /* add a more char */
+ break;
+
+ case ' ':
+ case ',':
+
+ /*printf(" ,'%s' ~POS=%d ~TRIP=%d ~[pos]=%d\n", pathbuff,pos,trip, pathbuff[pos]);*/
+ if(pos > 0) { /* append float to array, if it not yet stored */
+ pathbuff[pos] = 0;
+ pos = 0;
+ printf(" ,val:%s\n", pathbuff);
+ pathData[++trip] = atof(pathbuff);
+ }
+ break;
+
+ case '-':
+
+ if(pos > 0) { /* append float to array, if it not yet stored */
+ pathbuff[pos] = 0;
+ pos = 0;
+ printf(" -val:%s\n", pathbuff);
+ pathData[++trip] = atof(pathbuff);
+ }
+ pathbuff[pos++] = (char)c; /* add a more char */
+ break;
+
+ default:
+ /*** ASSUMED ANY COMMAND FOUND ***/
+
+
+ if(pos > 0) { /* just make sure: append float to array, if it not yet stored */
+ pathbuff[pos] = 0;
+ pos = 0;
+ printf(" >val:%s\n", pathbuff);
+ pathData[++trip] = atof(pathbuff);
+ }
+
+ /**** Compose Point List ****/
+
+ /* below "while" is for avoid loosing last 'z' command that maybe never accomodated. */
+ pendingTask = 1; if (i==last-1) {pendingTask = 2;}
+
+ while (pendingTask > 0)
+ {
+ pendingTask -= 1;
+
+ /* Check wether prior command need to be saved */
+ if(trip>=0)
+ {
+ trip = -1;
+ reset = -1;
+
+ relative = 0; /* relative to prior coordinate point or absolute coordinate? */
+
+ if (cmd == 'M') { xx = pathData[0]; yy = pathData[1]; fx = xx; fy = yy; }
+ else if(cmd == 'm') { xx = pathData[0]; yy = pathData[1]; fx = xx; fy = yy; relative=1; }
+ else if(cmd == 'L') { xx = pathData[0]; yy = pathData[1]; }
+ else if(cmd == 'l') { xx = pathData[0]; yy = pathData[1]; relative=1;}
+ else if(cmd == 'H') { xx = pathData[0]; yy = ly; }
+ else if(cmd == 'h') { xx = pathData[0]; yy = ly; relative=1;}
+ else if(cmd == 'V') { xx = lx; yy = pathData[1]; }
+ else if(cmd == 'v') { xx = lx; yy = pathData[1]; relative=1;}
+ else if(cmd == 'C') { xx = pathData[4]; yy = pathData[5]; cx1 = pathData[0]; cy1 = pathData[1]; cx2 = pathData[2]; cy2 = pathData[3]; }
+ else if(cmd == 'c') { xx = pathData[4]; yy = pathData[5]; cx1 = pathData[0]; cy1 = pathData[1]; cx2 = pathData[2]; cy2 = pathData[3]; relative=1;}
+ /*
+ else if(cmd == 'S') { xx = pathData[0]; yy = pathData[1]; }
+ else if(cmd == 's') { xx = pathData[0]; yy = pathData[1]; }
+ else if(cmd == 'Q') { xx = pathData[0]; yy = pathData[1]; }
+ else if(cmd == 'q') { xx = pathData[0]; yy = pathData[1]; }
+ else if(cmd == 'T') { xx = pathData[0]; yy = pathData[1]; }
+ else if(cmd == 't') { xx = pathData[0]; yy = pathData[1]; }
+ else if(cmd == 'A') { xx = pathData[0]; yy = pathData[1]; }
+ else if(cmd == 'a') { xx = pathData[0]; yy = pathData[1]; }
+ */
+ else if(cmd == 'Z') { xx = fx; yy = fy; }
+ else if(cmd == 'z') { xx = fx; yy = fy; }
+
+ if(!pathObjPointList && !pathObjFlagList)
+ {
+ pathObjPointList = embPointList_create(xx, yy);
+ startOfPointList = pathObjPointList;
+ pathObjFlagList = embFlagList_create(svgPathCmdToEmbPathFlag(cmd));
+ startOfFlagList = pathObjFlagList;
+ }
+ else
+ {
+ pathObjPointList = embPointList_add(pathObjPointList, embPoint_make(xx, yy));
+ pathObjFlagList = embFlagList_add(pathObjFlagList, svgPathCmdToEmbPathFlag(cmd));
+ }
+ lx = xx; ly = yy;
+
+ pathbuff[0] = (char)cmd; /* set the command for compare */
+ pathbuff[1] = 0;
+ pos = 0;
+
+ printf("*prior:%s (%f, %f, %f, %f, %f,%f, %f) \n", pathbuff,
+ pathData[0],
+ pathData[1],
+ pathData[2],
+ pathData[3],
+ pathData[4],
+ pathData[5],
+ pathData[6]
+ );
+
+ }
+
+ /* assign new command */
+ if(trip == -1 && reset == -1)
+ {
+ pathbuff[0] = (char)c; /* set the command for compare */
+ pathbuff[1] = 0;
+
+ printf("cmd:%s\n", pathbuff);
+ if (!strcmp(pathbuff, "M")) { cmd = 'M'; reset = 2; numMoves++; }
+ else if(!strcmp(pathbuff, "m")) { cmd = 'm'; reset = 2; numMoves++; }
+ else if(!strcmp(pathbuff, "L")) { cmd = 'L'; reset = 2; }
+ else if(!strcmp(pathbuff, "l")) { cmd = 'l'; reset = 2; }
+ else if(!strcmp(pathbuff, "C")) { cmd = 'C'; reset = 6; }
+ else if(!strcmp(pathbuff, "c")) { cmd = 'c'; reset = 6; }
+ else if(!strcmp(pathbuff, "H")) { cmd = 'H'; reset = 1; }
+ else if(!strcmp(pathbuff, "h")) { cmd = 'h'; reset = 1; }
+ else if(!strcmp(pathbuff, "V")) { cmd = 'V'; reset = 1; }
+ else if(!strcmp(pathbuff, "v")) { cmd = 'v'; reset = 1; }
+ else if(!strcmp(pathbuff, "S")) { cmd = 'S'; reset = 4; }
+ else if(!strcmp(pathbuff, "s")) { cmd = 's'; reset = 4; }
+ else if(!strcmp(pathbuff, "Q")) { cmd = 'Q'; reset = 4; }
+ else if(!strcmp(pathbuff, "q")) { cmd = 'q'; reset = 4; }
+ else if(!strcmp(pathbuff, "T")) { cmd = 'T'; reset = 2; }
+ else if(!strcmp(pathbuff, "t")) { cmd = 't'; reset = 2; }
+ else if(!strcmp(pathbuff, "A")) { cmd = 'A'; reset = 7; }
+ else if(!strcmp(pathbuff, "a")) { cmd = 'a'; reset = 7; }
+ else if(!strcmp(pathbuff, "Z")) { cmd = 'Z'; reset = 0; }
+ else if(!strcmp(pathbuff, "z")) { cmd = 'z'; reset = 0; }
+ else {
+ embLog_error("format-svg.c svgAddToPattern(), %s is not a valid svg path command, skipping...\n", pathbuff);
+ trip = -1;
+ reset = -1;
+ }
+ }
+ /* avoid loosing 'z' command that maybe never accomodated. */
+ if (i==last-1) {
+ trip = 2;
+ }
+ } /* while pendingTask */
+
+
+ break;
+ }
+ if(pos >= size - 1)
+ {
+ /* increase pathbuff length - leave room for 0 */
+ size *= 2;
+ pathbuff = (char*)realloc(pathbuff, size);
+ if(!pathbuff) { embLog_error("format-svg.c svgAddToPattern(), cannot re-allocate memory for pathbuff\n"); return; }
+ }
+ }
+ free(pathbuff);
+ pathbuff = 0;
+
+ /* TODO: subdivide numMoves > 1 */
+
+ embPattern_addPathObjectAbs(p, embPathObject_create(startOfPointList, startOfFlagList, svgColorToEmbColor(svgAttribute_getValue(currentElement, "stroke")), 1));
+ }
+ else if(!strcmp(buff, "polygon") ||
+ !strcmp(buff, "polyline"))
+ {
+ char* pointStr = svgAttribute_getValue(currentElement, "points");
+ int last = strlen(pointStr);
+ int size = 32;
+ int i = 0;
+ int c = 0;
+ int pos = 0;
+ unsigned char odd = 1;
+ double xx = 0.0;
+ double yy = 0.0;
+
+ EmbPointList* startOfPointList = 0;
+ EmbPointList* polyObjPointList = 0;
+
+ char* polybuff = 0;
+ polybuff = (char*)malloc(size);
+ if(!polybuff) { embLog_error("format-svg.c svgAddToPattern(), cannot allocate memory for polybuff\n"); return; }
+
+ for(i = 0; i < last; i++)
+ {
+ char c = pointStr[i];
+ switch(c)
+ {
+ case ' ':
+ if(pos == 0)
+ break;
+ polybuff[pos] = 0;
+ pos = 0;
+ /*Compose Point List */
+ if(odd)
+ {
+ odd = 0;
+ xx = atof(polybuff);
+ }
+ else
+ {
+ odd = 1;
+ yy = atof(polybuff);
+
+ if(!polyObjPointList)
+ {
+ polyObjPointList = embPointList_create(xx, yy);
+ startOfPointList = polyObjPointList;
+ }
+ else
+ {
+ polyObjPointList = embPointList_add(polyObjPointList, embPoint_make(xx, yy));
+ }
+ }
+
+ break;
+ default:
+ polybuff[pos++] = (char)c;
+ break;
+ }
+ if(pos >= size - 1)
+ {
+ /* increase polybuff length - leave room for 0 */
+ size *= 2;
+ polybuff = (char*)realloc(polybuff, size);
+ if(!polybuff) { embLog_error("format-svg.c svgAddToPattern(), cannot re-allocate memory for polybuff\n"); return; }
+ }
+ }
+ free(polybuff);
+ polybuff = 0;
+
+ if(!strcmp(buff, "polygon"))
+ {
+ EmbPolygonObject* polygonObj = embPolygonObject_create(startOfPointList, svgColorToEmbColor(svgAttribute_getValue(currentElement, "stroke")), 1); /* TODO: use lineType enum */
+ embPattern_addPolygonObjectAbs(p, polygonObj);
+ }
+ else /* polyline */
+ {
+ EmbPolylineObject* polylineObj = embPolylineObject_create(startOfPointList, svgColorToEmbColor(svgAttribute_getValue(currentElement, "stroke")), 1); /* TODO: use lineType enum */
+ embPattern_addPolylineObjectAbs(p, polylineObj);
+ }
+ }
+ else if(!strcmp(buff, "prefetch")) { }
+ else if(!strcmp(buff, "radialGradient")) { }
+ else if(!strcmp(buff, "rect"))
+ {
+ embPattern_addRectObjectAbs(p, atof(svgAttribute_getValue(currentElement, "x")),
+ atof(svgAttribute_getValue(currentElement, "y")),
+ atof(svgAttribute_getValue(currentElement, "width")),
+ atof(svgAttribute_getValue(currentElement, "height")));
+ }
+ else if(!strcmp(buff, "script")) { }
+ else if(!strcmp(buff, "set")) { }
+ else if(!strcmp(buff, "solidColor")) { }
+ else if(!strcmp(buff, "stop")) { }
+ else if(!strcmp(buff, "svg")) { }
+ else if(!strcmp(buff, "switch")) { }
+ else if(!strcmp(buff, "tbreak")) { }
+ else if(!strcmp(buff, "text")) { }
+ else if(!strcmp(buff, "textArea")) { }
+ else if(!strcmp(buff, "title")) { }
+ else if(!strcmp(buff, "tspan")) { }
+ else if(!strcmp(buff, "use")) { }
+ else if(!strcmp(buff, "video")) { }
+
+ svgElement_free(currentElement);
+ currentElement = 0;
+}
+
+
+int svgIsElement(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "?xml")) { type = SVG_NULL; } /* TODO: Fix the xml version ? messing with svg version */
+ else if(!strcmp(buff, "a")) { type = SVG_ELEMENT; }
+ /* else if(!strcmp(buff, "altGlyph")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "altGlyphDef")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "altGlyphItem")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ else if(!strcmp(buff, "animate")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "animateColor")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "animateMotion")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "animateTransform")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "animation")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "audio")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "circle")) { type = SVG_ELEMENT; }
+ /* else if(!strcmp(buff, "clipPath")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "color-profile")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "cursor")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ else if(!strcmp(buff, "defs")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "desc")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "discard")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "ellipse")) { type = SVG_ELEMENT; }
+ /* else if(!strcmp(buff, "feBlend")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "feColorMatrix")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "feComponentTransfer")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "feComposite")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "feConvolveMatrix")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "feDiffuseLighting")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "feDisplacementMap")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "feDistantLight")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "feFlood")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "feFuncA")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "feFuncB")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "feFuncG")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "feFuncR")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "feGaussianBlur")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "feImage")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "feMerge")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "feMergeNode")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "feMorphology")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "feOffset")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "fePointLight")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "feSpecularLighting")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "feSpotLight")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "feTile")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "feTurbulence")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "filter")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ else if(!strcmp(buff, "font")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "font-face")) { type = SVG_ELEMENT; }
+ /* else if(!strcmp(buff, "font-face-format")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "font-face-name")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ else if(!strcmp(buff, "font-face-src")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "font-face-uri")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "foreignObject")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "g")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "glyph")) { type = SVG_ELEMENT; }
+ /* else if(!strcmp(buff, "glyphRef")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ else if(!strcmp(buff, "handler")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "hkern")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "image")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "line")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "linearGradient")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "listener")) { type = SVG_ELEMENT; }
+ /* else if(!strcmp(buff, "marker")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "mask")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ else if(!strcmp(buff, "metadata")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "missing-glyph")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "mpath")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "path")) { type = SVG_ELEMENT; }
+ /* else if(!strcmp(buff, "pattern")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ else if(!strcmp(buff, "polygon")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "polyline")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "prefetch")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "radialGradient")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "rect")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "script")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "set")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "solidColor")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "stop")) { type = SVG_ELEMENT; }
+ /* else if(!strcmp(buff, "style")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ else if(!strcmp(buff, "svg")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "switch")) { type = SVG_ELEMENT; }
+ /* else if(!strcmp(buff, "symbol")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ else if(!strcmp(buff, "tbreak")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "text")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "textArea")) { type = SVG_ELEMENT; }
+ /* else if(!strcmp(buff, "textPath")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ else if(!strcmp(buff, "title")) { type = SVG_ELEMENT; }
+ /* else if(!strcmp(buff, "tref")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ else if(!strcmp(buff, "tspan")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "use")) { type = SVG_ELEMENT; }
+ else if(!strcmp(buff, "video")) { type = SVG_ELEMENT; }
+ /* else if(!strcmp(buff, "view")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+ /* else if(!strcmp(buff, "vkern")) { type = SVG_ELEMENT; } TODO: SVG Full 1.1 Spec Element */
+
+ /* Attempt to identify the program that created the SVG file. This should be in a comment at that occurs before the svg element. */
+ else if(!strcmp(buff, "Embroidermodder")) { type = SVG_NULL; svgCreator = SVG_CREATOR_EMBROIDERMODDER; }
+ else if(!strcmp(buff, "Illustrator")) { type = SVG_NULL; svgCreator = SVG_CREATOR_ILLUSTRATOR; }
+ else if(!strcmp(buff, "Inkscape")) { type = SVG_NULL; svgCreator = SVG_CREATOR_INKSCAPE; }
+
+ else { type = SVG_NULL; }
+ return type;
+}
+
+int svgIsMediaProperty(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "audio-level")) { type = SVG_MEDIA_PROPERTY; }
+ else if(!strcmp(buff, "buffered-rendering")) { type = SVG_MEDIA_PROPERTY; }
+ else if(!strcmp(buff, "display")) { type = SVG_MEDIA_PROPERTY; }
+ else if(!strcmp(buff, "image-rendering")) { type = SVG_MEDIA_PROPERTY; }
+ else if(!strcmp(buff, "pointer-events")) { type = SVG_MEDIA_PROPERTY; }
+ else if(!strcmp(buff, "shape-rendering")) { type = SVG_MEDIA_PROPERTY; }
+ else if(!strcmp(buff, "text-rendering")) { type = SVG_MEDIA_PROPERTY; }
+ else if(!strcmp(buff, "viewport-fill")) { type = SVG_MEDIA_PROPERTY; }
+ else if(!strcmp(buff, "viewport-fill-opacity")) { type = SVG_MEDIA_PROPERTY; }
+ else if(!strcmp(buff, "visibility")) { type = SVG_MEDIA_PROPERTY; }
+ return type;
+}
+
+int svgIsProperty(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "audio-level")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "buffered-rendering")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "color")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "color-rendering")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "direction")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "display")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "display-align")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "fill")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "fill-opacity")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "fill-rule")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "font-family")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "font-size")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "font-style")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "font-variant")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "font-weight")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "image-rendering")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "line-increment")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "opacity")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "pointer-events")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "shape-rendering")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "solid-color")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "solid-opacity")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "stop-color")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "stop-opacity")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "stroke")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "stroke-dasharray")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "stroke-linecap")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "stroke-linejoin")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "stroke-miterlimit")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "stroke-opacity")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "stroke-width")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "text-align")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "text-anchor")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "text-rendering")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "unicode-bidi")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "vector-effect")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "viewport-fill")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "viewport-fill-opacity")) { type = SVG_PROPERTY; }
+ else if(!strcmp(buff, "visibility")) { type = SVG_PROPERTY; }
+ return type;
+}
+
+int svgIsXmlAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "encoding")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "standalone")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "version")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsXmlAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsLinkAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "externalResourcesRequired")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusHighlight")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusable")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-next")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-prev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "target")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "transform")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:actuate")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:arcrole")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:href")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:show")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:title")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:type")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsLinkAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsAnimateAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "accumulate")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "additive")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "attributeName")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "attributeType")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "begin")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "by")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "calcMode")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "dur")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "end")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "fill")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "from")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "keySplines")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "keyTimes")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "max")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "min")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "repeatCount")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "repeatDur")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "restart")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "to")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "values")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:actuate")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:arcrole")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:href")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:show")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:title")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:type")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsAnimateAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsAnimateColorAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "accumulate")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "additive")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "attributeName")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "attributeType")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "begin")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "by")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "calcMode")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "dur")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "end")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "fill")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "from")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "keySplines")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "keyTimes")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "max")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "min")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "repeatCount")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "repeatDur")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "restart")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "to")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "values")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:actuate")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:arcrole")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:href")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:show")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:title")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:type")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsAnimateColorAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsAnimateMotionAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "accumulate")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "additive")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "begin")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "by")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "calcMode")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "dur")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "end")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "fill")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "from")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "keyPoints")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "keySplines")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "keyTimes")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "max")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "min")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "origin")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "path")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "repeatCount")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "repeatDur")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "restart")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rotate")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "to")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "values")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:actuate")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:arcrole")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:href")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:show")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:title")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:type")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsAnimateMotionAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsAnimateTransformAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "accumulate")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "additive")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "attributeName")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "attributeType")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "begin")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "by")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "calcMode")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "dur")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "end")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "fill")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "from")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "keySplines")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "keyTimes")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "max")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "min")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "repeatCount")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "repeatDur")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "restart")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "to")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "type")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "values")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:actuate")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:arcrole")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:href")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:show")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:title")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:type")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsAnimateTransformAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsAnimationAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "begin")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "dur")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "end")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "externalResourcesRequired")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "fill")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusHighlight")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusable")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "height")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "initialVisibility")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "max")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "min")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-next")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-prev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "preserveAspectRatio")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "repeatCount")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "repeatDur")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "restart")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "syncBehavior")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "syncMaster")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "syncTolerance")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "transform")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "width")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "x")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:actuate")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:arcrole")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:href")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:show")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:title")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:type")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "y")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsAnimationAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsAudioAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "begin")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "dur")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "end")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "externalResourcesRequired")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "fill")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "max")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "min")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "repeatCount")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "repeatDur")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "restart")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "syncBehavior")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "syncMaster")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "syncTolerance")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "type")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:actuate")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:arcrole")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:href")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:show")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:title")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:type")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsAudioAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsCircleAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "cx")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "cy")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusHighlight")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusable")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-next")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-prev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "r")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "transform")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsCircleAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsDefsAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsDefsAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsDescAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsDescAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsDiscardAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "begin")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:actuate")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:arcrole")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:href")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:show")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:title")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:type")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsDiscardAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsEllipseAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "cx")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "cy")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusHighlight")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusable")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-next")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-prev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rx")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "ry")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "transform")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsEllipseAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsFontAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "externalResourcesRequired")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "horiz-adv-x")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "horiz-origin-x")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsFontAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsFontFaceAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "accent-height")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "alphabetic")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "ascent")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "bbox")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "cap-height")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "descent")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "externalResourcesRequired")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "font-family")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "font-stretch")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "font-style")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "font-variant")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "font-weight")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "hanging")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "ideographic")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "mathematical")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "overline-position")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "overline-thickness")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "panose-1")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "slope")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "stemh")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "stemv")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "strikethrough-position")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "strikethrough-thickness")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "underline-position")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "underline-thickness")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "unicode-range")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "units-per-em")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "widths")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "x-height")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsFontFaceAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsFontFaceSrcAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsFontFaceSrcAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsFontFaceUriAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "externalResourcesRequired")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:actuate")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:arcrole")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:href")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:show")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:title")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:type")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsFontFaceUriAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsForeignObjectAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "externalResourcesRequired")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusHighlight")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusable")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "height")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-next")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-prev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "transform")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "width")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "x")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:actuate")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:arcrole")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:href")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:show")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:title")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:type")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "y")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsForeignObjectAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsGroupAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "externalResourcesRequired")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusHighlight")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusable")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-next")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-prev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "transform")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsGroupAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsGlyphAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "arabic-form")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "d")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "glyph-name")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "horiz-adv-x")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "unicode")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsGlyphAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsHandlerAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "ev:event")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "externalResourcesRequired")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "type")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:actuate")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:arcrole")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:href")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:show")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:title")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:type")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsHandlerAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsHKernAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "g1")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "g2")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "k")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "u1")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "u2")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsHKernAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsImageAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "externalResourcesRequired")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusHighlight")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusable")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "height")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-next")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-prev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "opacity")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "preserveAspectRatio")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "transform")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "type")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "width")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "x")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:actuate")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:arcrole")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:href")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:show")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:title")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:type")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "y")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsImageAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsLineAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusHighlight")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusable")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-next")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-prev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "transform")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "x1")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "x2")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "y1")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "y2")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsLineAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsLinearGradientAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "gradientUnits")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "x1")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "x2")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "y1")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "y2")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsLinearGradientAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsListenerAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "defaultAction")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "event")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "handler")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "observer")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "phase")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "propagate")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "target")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsListenerAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsMetadataAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsMetadataAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsMissingGlyphAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "d")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "horiz-adv-x")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsMissingGlyphAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsMPathAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:actuate")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:arcrole")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:href")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:show")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:title")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:type")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsMPathAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsPathAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "d")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusHighlight")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusable")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-next")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-prev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "pathLength")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "transform")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsPathAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsPolygonAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusHighlight")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusable")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-next")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-prev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "points")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "transform")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsPolygonAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsPolylineAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusHighlight")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusable")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-next")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-prev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "points")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "transform")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsPolylineAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsPrefetchAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "bandwidth")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "mediaCharacterEncoding")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "mediaContentEncodings")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "mediaSize")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "mediaTime")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:actuate")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:arcrole")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:href")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:show")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:title")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:type")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsPrefetchAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsRadialGradientAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "cx")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "cy")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "gradientUnits")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "r")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsRadialGradientAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsRectAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusHighlight")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusable")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "height")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-next")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-prev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rx")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "ry")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "transform")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "width")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "x")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "y")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsRectAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsScriptAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "externalResourcesRequired")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "type")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:actuate")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:arcrole")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:href")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:show")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:title")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:type")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsScriptAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsSetAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "attributeName")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "attributeType")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "begin")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "dur")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "end")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "fill")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "max")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "min")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "repeatCount")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "repeatDur")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "to")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:actuate")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:arcrole")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:href")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:show")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:title")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:type")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsSetAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsSolidColorAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsSolidColorAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsStopAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "offset")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsStopAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsSvgAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "baseProfile")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "contentScriptType")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "externalResourcesRequired")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusHighlight")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusable")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "height")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-next")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-prev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "playbackOrder")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "preserveAspectRatio")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "snapshotTime")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "syncBehaviorDefault")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "syncToleranceDefault")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "timelineBegin")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "version")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "viewBox")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "width")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "zoomAndPan")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+ else if(svgCreator == SVG_CREATOR_INKSCAPE)
+ {
+ if (!strcmp(buff, "xmlns:dc")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xmlns:cc")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xmlns:rdf")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xmlns:svg")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xmlns")) { type = SVG_ATTRIBUTE; }
+ }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsSvgAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsSwitchAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "externalResourcesRequired")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusHighlight")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusable")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-next")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-prev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "transform")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsSwitchAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsTBreakAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsTBreakAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsTextAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "editable")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusHighlight")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusable")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-next")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-prev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rotate")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "transform")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "x")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "y")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsTextAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsTextAreaAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "editable")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusHighlight")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusable")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "height")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-next")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-prev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "transform")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "width")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "x")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "y")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsTextAreaAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsTitleAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsTitleAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsTSpanAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusHighlight")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusable")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-next")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-prev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsTSpanAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsUseAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "externalResourcesRequired")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusHighlight")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusable")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-next")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-prev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "transform")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "x")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:actuate")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:arcrole")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:href")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:show")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:title")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:type")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "y")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsUseAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+int svgIsVideoAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ if (!strcmp(buff, "about")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "begin")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "class")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "content")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "dur")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "end")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "externalResourcesRequired")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "fill")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusHighlight")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "focusable")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "height")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "initialVisibility")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "max")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "min")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-down-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-next")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-prev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-left")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "nav-up-right")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "overlay")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "preserveAspectRatio")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "property")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rel")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "repeatCount")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "repeatDur")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "resource")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "restart")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "rev")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "syncBehavior")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "syncMaster")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "syncTolerance")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "transform")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "transformBehavior")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "type")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "width")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "x")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:actuate")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:arcrole")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:href")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:role")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:show")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:title")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xlink:type")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "y")) { type = SVG_ATTRIBUTE; }
+ else if(!strcmp(buff, "/")) { type = SVG_ATTRIBUTE; }
+
+ if(type == SVG_NULL) { embLog_print("format-svg.c svgIsVideoAttribute(), unknown: %s\n", buff); }
+ return type;
+}
+
+
+int svgIsCatchAllAttribute(const char* buff)
+{
+ int type = SVG_NULL;
+ /* Catch All Properties */
+ if (!strcmp(buff, "audio-level")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "buffered-rendering")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "color")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "color-rendering")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "direction")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "display")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "display-align")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "fill")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "fill-opacity")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "fill-rule")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "font-family")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "font-size")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "font-style")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "font-variant")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "font-weight")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "image-rendering")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "line-increment")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "opacity")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "pointer-events")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "shape-rendering")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "solid-color")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "solid-opacity")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "stop-color")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "stop-opacity")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "stroke")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "stroke-dasharray")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "stroke-linecap")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "stroke-linejoin")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "stroke-miterlimit")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "stroke-opacity")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "stroke-width")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "text-align")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "text-anchor")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "text-rendering")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "unicode-bidi")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "vector-effect")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "viewport-fill")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "viewport-fill-opacity")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "visibility")) { type = SVG_CATCH_ALL; }
+ /* Catch All Attributes */
+ else if(!strcmp(buff, "about")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "accent-height")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "accumulate")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "additive")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "alphabetic")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "arabic-form")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "ascent")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "attributeName")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "attributeType")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "bandwidth")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "baseProfile")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "bbox")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "begin")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "by")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "calcMode")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "cap-height")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "class")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "content")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "contentScriptType")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "cx")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "cy")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "d")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "datatype")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "defaultAction")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "descent")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "dur")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "editable")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "end")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "ev:event")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "event")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "externalResourcesRequired")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "focusHighlight")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "focusable")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "font-family")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "font-stretch")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "font-style")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "font-variant")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "font-weight")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "from")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "g1")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "g2")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "glyph-name")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "gradientUnits")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "handler")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "hanging")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "height")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "horiz-adv-x")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "horiz-origin-x")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "id")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "ideographic")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "initialVisibility")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "k")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "keyPoints")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "keySplines")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "keyTimes")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "lang")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "mathematical")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "max")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "mediaCharacterEncoding")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "mediaContentEncodings")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "mediaSize")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "mediaTime")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "min")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "nav-down")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "nav-down-left")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "nav-down-right")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "nav-left")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "nav-next")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "nav-prev")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "nav-right")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "nav-up")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "nav-up-left")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "nav-up-right")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "observer")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "offset")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "origin")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "overlay")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "overline-position")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "overline-thickness")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "panose-1")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "path")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "pathLength")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "phase")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "playbackOrder")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "points")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "preserveAspectRatio")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "propagate")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "property")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "r")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "rel")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "repeatCount")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "repeatDur")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "requiredExtensions")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "requiredFeatures")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "requiredFonts")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "requiredFormats")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "resource")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "restart")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "rev")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "role")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "rotate")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "rx")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "ry")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "slope")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "snapshotTime")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "stemh")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "stemv")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "strikethrough-position")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "strikethrough-thickness")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "syncBehavior")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "syncBehaviorDefault")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "syncMaster")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "syncTolerance")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "syncToleranceDefault")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "systemLanguage")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "target")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "timelineBegin")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "to")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "transform")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "transformBehavior")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "type")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "typeof")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "u1")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "u2")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "underline-position")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "underline-thickness")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "unicode")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "unicode-range")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "units-per-em")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "values")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "version")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "viewBox")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "width")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "widths")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "x")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "x-height")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "x1")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "x2")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "xlink:actuate")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "xlink:arcrole")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "xlink:href")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "xlink:role")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "xlink:show")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "xlink:title")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "xlink:type")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "xml:base")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "xml:id")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "xml:lang")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "xml:space")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "y")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "y1")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "y2")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "zoomAndPan")) { type = SVG_CATCH_ALL; }
+ else if(!strcmp(buff, "/")) { type = SVG_CATCH_ALL; }
+ return type;
+}
+
+void svgProcess(int c, const char* buff)
+{
+ if(svgExpect == SVG_EXPECT_ELEMENT)
+ {
+ char advance = 0;
+ if(buff[0] == '/') { return; }
+
+ advance = (char)svgIsElement(buff);
+
+ if(advance) { printf("ELEMENT:\n"); svgExpect = SVG_EXPECT_ATTRIBUTE; currentElement = svgElement_create(buff); }
+ else { return; }
+ }
+ else if(svgExpect == SVG_EXPECT_ATTRIBUTE)
+ {
+ char advance = 0;
+ const char* name = 0;
+ if(!currentElement) { /* TODO: error */ return; }
+ name = currentElement->name;
+
+ if(!strcmp(name, "?xml"))
+ {
+ if(!advance) { advance = (char)svgIsXmlAttribute(buff); }
+ }
+ else if(!strcmp(name, "a"))
+ {
+ if(!advance) { advance = (char)svgIsProperty(buff); }
+ if(!advance) { advance = (char)svgIsLinkAttribute(buff); }
+ }
+ else if(!strcmp(name, "animate"))
+ {
+ if(!advance) { advance = (char)svgIsAnimateAttribute(buff); }
+ }
+ else if(!strcmp(name, "animateColor"))
+ {
+ if(!advance) { advance = (char)svgIsAnimateColorAttribute(buff); }
+ }
+ else if(!strcmp(name, "animateMotion"))
+ {
+ if(!advance) { advance = (char)svgIsAnimateMotionAttribute(buff); }
+ }
+ else if(!strcmp(name, "animateTransform"))
+ {
+ if(!advance) { advance = (char)svgIsAnimateTransformAttribute(buff); }
+ }
+ else if(!strcmp(name, "animation"))
+ {
+ if(!advance) { advance = (char)svgIsMediaProperty(buff); }
+ if(!advance) { advance = (char)svgIsAnimationAttribute(buff); }
+ }
+ else if(!strcmp(name, "audio"))
+ {
+ if(!advance) { advance = (char)svgIsMediaProperty(buff); }
+ if(!advance) { advance = (char)svgIsAudioAttribute(buff); }
+ }
+ else if(!strcmp(name, "circle"))
+ {
+ if(!advance) { advance = (char)svgIsProperty(buff); }
+ if(!advance) { advance = (char)svgIsCircleAttribute(buff); }
+ }
+ else if(!strcmp(name, "defs"))
+ {
+ if(!advance) { advance = (char)svgIsProperty(buff); }
+ if(!advance) { advance = (char)svgIsDefsAttribute(buff); }
+ }
+ else if(!strcmp(name, "desc"))
+ {
+ if(!advance) { advance = (char)svgIsMediaProperty(buff); }
+ if(!advance) { advance = (char)svgIsDescAttribute(buff); }
+ }
+ else if(!strcmp(name, "discard"))
+ {
+ if(!advance) { advance = (char)svgIsDiscardAttribute(buff); }
+ }
+ else if(!strcmp(name, "ellipse"))
+ {
+ if(!advance) { advance = (char)svgIsProperty(buff); }
+ if(!advance) { advance = (char)svgIsEllipseAttribute(buff); }
+ }
+ else if(!strcmp(name, "font"))
+ {
+ if(!advance) { advance = (char)svgIsFontAttribute(buff); }
+ }
+ else if(!strcmp(name, "font-face"))
+ {
+ if(!advance) { advance = (char)svgIsFontFaceAttribute(buff); }
+ }
+ else if(!strcmp(name, "font-face-src"))
+ {
+ if(!advance) { advance = (char)svgIsFontFaceSrcAttribute(buff); }
+ }
+ else if(!strcmp(name, "font-face-uri"))
+ {
+ if(!advance) { advance = (char)svgIsFontFaceUriAttribute(buff); }
+ }
+ else if(!strcmp(name, "foreignObject"))
+ {
+ if(!advance) { advance = (char)svgIsProperty(buff); }
+ if(!advance) { advance = (char)svgIsForeignObjectAttribute(buff); }
+ }
+ else if(!strcmp(name, "g"))
+ {
+ if(!advance) { advance = (char)svgIsProperty(buff); }
+ if(!advance) { advance = (char)svgIsGroupAttribute(buff); }
+ }
+ else if(!strcmp(name, "glyph"))
+ {
+ if(!advance) { advance = (char)svgIsGlyphAttribute(buff); }
+ }
+ else if(!strcmp(name, "handler"))
+ {
+ if(!advance) { advance = (char)svgIsHandlerAttribute(buff); }
+ }
+ else if(!strcmp(name, "hkern"))
+ {
+ if(!advance) { advance = (char)svgIsHKernAttribute(buff); }
+ }
+ else if(!strcmp(name, "image"))
+ {
+ if(!advance) { advance = (char)svgIsMediaProperty(buff); }
+ if(!advance) { advance = (char)svgIsImageAttribute(buff); }
+ }
+ else if(!strcmp(name, "line"))
+ {
+ if(!advance) { advance = (char)svgIsProperty(buff); }
+ if(!advance) { advance = (char)svgIsLineAttribute(buff); }
+ }
+ else if(!strcmp(name, "linearGradient"))
+ {
+ if(!advance) { advance = (char)svgIsProperty(buff); }
+ if(!advance) { advance = (char)svgIsLinearGradientAttribute(buff); }
+ }
+ else if(!strcmp(name, "listener"))
+ {
+ if(!advance) { advance = (char)svgIsListenerAttribute(buff); }
+ }
+ else if(!strcmp(name, "metadata"))
+ {
+ if(!advance) { advance = (char)svgIsMediaProperty(buff); }
+ if(!advance) { advance = (char)svgIsMetadataAttribute(buff); }
+ }
+ else if(!strcmp(name, "missing-glyph"))
+ {
+ if(!advance) { advance = (char)svgIsMissingGlyphAttribute(buff); }
+ }
+ else if(!strcmp(name, "mpath"))
+ {
+ if(!advance) { advance = (char)svgIsMPathAttribute(buff); }
+ }
+ else if(!strcmp(name, "path"))
+ {
+ if(!advance) { advance = (char)svgIsProperty(buff); }
+ if(!advance) { advance = (char)svgIsPathAttribute(buff); }
+ }
+ else if(!strcmp(name, "polygon"))
+ {
+ if(!advance) { advance = (char)svgIsProperty(buff); }
+ if(!advance) { advance = (char)svgIsPolygonAttribute(buff); }
+ }
+ else if(!strcmp(name, "polyline"))
+ {
+ if(!advance) { advance = (char)svgIsProperty(buff); }
+ if(!advance) { advance = (char)svgIsPolylineAttribute(buff); }
+ }
+ else if(!strcmp(name, "prefetch"))
+ {
+ if(!advance) { advance = (char)svgIsPrefetchAttribute(buff); }
+ }
+ else if(!strcmp(name, "radialGradient"))
+ {
+ if(!advance) { advance = (char)svgIsProperty(buff); }
+ if(!advance) { advance = (char)svgIsRadialGradientAttribute(buff); }
+ }
+ else if(!strcmp(name, "rect"))
+ {
+ if(!advance) { advance = (char)svgIsProperty(buff); }
+ if(!advance) { advance = (char)svgIsRectAttribute(buff); }
+ }
+ else if(!strcmp(name, "script"))
+ {
+ if(!advance) { advance = (char)svgIsScriptAttribute(buff); }
+ }
+ else if(!strcmp(name, "set"))
+ {
+ if(!advance) { advance = (char)svgIsSetAttribute(buff); }
+ }
+ else if(!strcmp(name, "solidColor"))
+ {
+ if(!advance) { advance = (char)svgIsProperty(buff); }
+ if(!advance) { advance = (char)svgIsSolidColorAttribute(buff); }
+ }
+ else if(!strcmp(name, "stop"))
+ {
+ if(!advance) { advance = (char)svgIsProperty(buff); }
+ if(!advance) { advance = (char)svgIsStopAttribute(buff); }
+ }
+ else if(!strcmp(name, "svg"))
+ {
+ if(!advance) { advance = (char)svgIsProperty(buff); }
+ if(!advance) { advance = (char)svgIsSvgAttribute(buff); }
+ }
+ else if(!strcmp(name, "switch"))
+ {
+ if(!advance) { advance = (char)svgIsProperty(buff); }
+ if(!advance) { advance = (char)svgIsSwitchAttribute(buff); }
+ }
+ else if(!strcmp(name, "tbreak"))
+ {
+ if(!advance) { advance = (char)svgIsTBreakAttribute(buff); }
+ }
+ else if(!strcmp(name, "text"))
+ {
+ if(!advance) { advance = (char)svgIsProperty(buff); }
+ if(!advance) { advance = (char)svgIsTextAttribute(buff); }
+ }
+ else if(!strcmp(name, "textArea"))
+ {
+ if(!advance) { advance = (char)svgIsProperty(buff); }
+ if(!advance) { advance = (char)svgIsTextAreaAttribute(buff); }
+ }
+ else if(!strcmp(name, "title"))
+ {
+ if(!advance) { advance = (char)svgIsMediaProperty(buff); }
+ if(!advance) { advance = (char)svgIsTitleAttribute(buff); }
+ }
+ else if(!strcmp(name, "tspan"))
+ {
+ if(!advance) { advance = (char)svgIsProperty(buff); }
+ if(!advance) { advance = (char)svgIsTSpanAttribute(buff); }
+ }
+ else if(!strcmp(name, "use"))
+ {
+ if(!advance) { advance = (char)svgIsProperty(buff); }
+ if(!advance) { advance = (char)svgIsUseAttribute(buff); }
+ }
+ else if(!strcmp(name, "video"))
+ {
+ if(!advance) { advance = (char)svgIsMediaProperty(buff); }
+ if(!advance) { advance = (char)svgIsVideoAttribute(buff); }
+ }
+
+ if(advance)
+ {
+ printf("ATTRIBUTE:\n");
+ svgExpect = SVG_EXPECT_VALUE;
+ free(currentAttribute);
+ currentAttribute = 0;
+ currentAttribute = emb_strdup(buff);
+ }
+ }
+ else if(svgExpect == SVG_EXPECT_VALUE)
+ {
+ int last = strlen(buff) - 1;
+ printf("VALUE:\n");
+
+ /* single-value */
+ if((buff[0] == '"' || buff[0] == '\'') && (buff[last] == '/' || buff[last] == '"' || buff[last] == '\'') && !svgMultiValue)
+ {
+ svgExpect = SVG_EXPECT_ATTRIBUTE;
+ svgElement_addAttribute(currentElement, svgAttribute_create(currentAttribute, buff));
+ }
+ else /* multi-value */
+ {
+ svgMultiValue = 1;
+ if(!currentValue)
+ {
+ currentValue = emb_strdup(buff);
+ if(!currentValue) { /*TODO: error */ return; }
+ }
+ else
+ {
+ char* tmp = 0;
+ tmp = emb_strdup(currentValue);
+ free(currentValue);
+ currentValue = 0;
+ currentValue = (char*)malloc(strlen(buff) + strlen(tmp) + 2);
+ if(!currentValue) { embLog_error("format-svg.c svgProcess(), cannot allocate memory for currentValue\n"); return; }
+ if(currentValue) memset(currentValue, 0, strlen(buff) + strlen(tmp) + 2);
+ strcat(currentValue, tmp);
+ strcat(currentValue, " ");
+ strcat(currentValue, buff);
+ free(tmp);
+ tmp = 0;
+ }
+
+ if(buff[last] == '/' || buff[last] == '"' || buff[last] == '\'')
+ {
+ svgMultiValue = 0;
+ svgExpect = SVG_EXPECT_ATTRIBUTE;
+ svgElement_addAttribute(currentElement, svgAttribute_create(currentAttribute, currentValue));
+ free(currentValue);
+ currentValue = 0;
+ }
+ }
+ }
+
+ if(svgExpect != SVG_EXPECT_NULL)
+ printf("%s\n", buff);
+
+ if(c == '>')
+ svgExpect = SVG_EXPECT_NULL;
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readSvg(EmbPattern* pattern, const char* fileName)
+{
+ EmbFile* file = 0;
+ int size = 1024;
+ int pos;
+ int c = 0;
+ EmbRectObjectList* rList = 0;
+ EmbCircleObjectList* cList = 0;
+ EmbEllipseObjectList* eList = 0;
+ EmbLineObjectList* liList = 0;
+ EmbPointObjectList* poList = 0;
+ EmbPolygonObjectList* pogList = 0;
+ EmbPolylineObjectList* polList = 0;
+ char* buff = 0;
+
+ if(!pattern) { embLog_error("format-svg.c readSvg(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-svg.c readSvg(), fileName argument is null\n"); return 0; }
+
+ buff = (char*)malloc(size);
+ if(!buff) { embLog_error("format-svg.c readSvg(), cannot allocate memory for buff\n"); return 0; }
+
+ svgCreator = SVG_CREATOR_NULL;
+
+ svgExpect = SVG_EXPECT_NULL;
+ svgMultiValue = 0;
+
+ currentElement = 0;
+ currentAttribute = 0;
+ currentValue = 0;
+
+ /* Pre-flip incase of multiple reads on the same pattern */
+ embPattern_flipVertical(pattern);
+
+ file = embFile_open(fileName, "r");
+ if(file)
+ {
+ pos = 0;
+ do
+ {
+ c = embFile_getc(file);
+ switch(c)
+ {
+ case '<':
+ if(svgExpect == SVG_EXPECT_NULL)
+ {
+ svgAddToPattern(pattern);
+ svgExpect = SVG_EXPECT_ELEMENT;
+ }
+ case '>':
+ if(pos == 0) /* abnormal case that may occur in svg element where '>' is all by itself */
+ {
+ /*TODO: log a warning about this absurdity! */
+ svgExpect = SVG_EXPECT_ELEMENT;
+ break;
+ }
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\n':
+ case '=':
+ if(pos == 0)
+ break;
+ buff[pos] = 0;
+ pos = 0;
+ svgProcess(c, buff);
+ break;
+ default:
+ buff[pos++] = (char)c;
+ break;
+ }
+ if(pos >= size - 1)
+ {
+ /* increase buff length - leave room for 0 */
+ size *= 2;
+ buff = (char*)realloc(buff, size);
+ if(!buff) { embLog_error("format-svg.c readSvg(), cannot re-allocate memory for buff\n"); return 0; }
+ }
+ }
+ while(c != EOF);
+ embFile_close(file);
+ }
+ free(buff);
+ buff = 0;
+ free(currentAttribute);
+ currentAttribute = 0;
+ free(currentValue);
+ currentValue = 0;
+
+ /*TODO: remove this summary after testing is complete */
+ printf("OBJECT SUMMARY:\n");
+ cList = pattern->circleObjList;
+ while(cList)
+ {
+ EmbCircle c = cList->circleObj.circle;
+ printf("circle %f %f %f\n", c.centerX, c.centerY, c.radius);
+ cList = cList->next;
+ }
+ eList = pattern->ellipseObjList;
+ while(eList)
+ {
+ EmbEllipse e = eList->ellipseObj.ellipse;
+ printf("ellipse %f %f %f %f\n", embEllipse_centerX(e), embEllipse_centerY(e), embEllipse_radiusX(e), embEllipse_radiusY(e));
+ eList = eList->next;
+ }
+ liList = pattern->lineObjList;
+ while(liList)
+ {
+ EmbLine li = liList->lineObj.line;
+ printf("line %f %f %f %f\n", embLine_x1(li), embLine_y1(li), embLine_x2(li), embLine_y2(li));
+ liList = liList->next;
+ }
+ poList = pattern->pointObjList;
+ while(poList)
+ {
+ EmbPoint po = poList->pointObj.point;
+ printf("point %f %f\n", embPoint_x(po), embPoint_y(po));
+ poList = poList->next;
+ }
+ pogList = pattern->polygonObjList;
+ while(pogList)
+ {
+ int vertices = embPointList_count(pogList->polygonObj->pointList);
+ printf("polygon %d\n", vertices);
+ pogList = pogList->next;
+ }
+ polList = pattern->polylineObjList;
+ while(polList)
+ {
+ int vertices = embPointList_count(polList->polylineObj->pointList);
+ printf("polyline %d\n", vertices);
+ polList = polList->next;
+ }
+ rList = pattern->rectObjList;
+ while(rList)
+ {
+ EmbRect r = rList->rectObj.rect;
+ printf("rect %f %f %f %f\n", embRect_x(r), embRect_y(r), embRect_width(r), embRect_height(r));
+ rList = rList->next;
+ }
+
+ /* Flip the pattern since SVG Y+ is down and libembroidery Y+ is up. */
+ embPattern_flipVertical(pattern);
+
+ return 1; /*TODO: finish readSvg */
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeSvg(EmbPattern* pattern, const char* fileName)
+{
+ EmbFile* file = 0;
+ EmbRect boundingRect;
+ EmbStitchList* stList;
+ EmbCircleObjectList* cObjList = 0;
+ EmbCircle circle;
+ EmbEllipseObjectList* eObjList = 0;
+ EmbEllipse ellipse;
+ EmbLineObjectList* liObjList = 0;
+ EmbLine line;
+ EmbPointObjectList* poObjList = 0;
+ EmbPoint point;
+ EmbPolygonObjectList* pogObjList = 0;
+ EmbPointList* pogPointList = 0;
+ EmbPolylineObjectList* polObjList = 0;
+ EmbPointList* polPointList = 0;
+ EmbRectObjectList* rObjList = 0;
+ EmbRect rect;
+ EmbColor color;
+
+ char tmpX[32];
+ char tmpY[32];
+
+ if(!pattern) { embLog_error("format-svg.c writeSvg(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-svg.c writeSvg(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "w");
+ if(!file)
+ {
+ embLog_error("format-svg.c writeSvg(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+
+ /* Pre-flip the pattern since SVG Y+ is down and libembroidery Y+ is up. */
+ embPattern_flipVertical(pattern);
+
+ boundingRect = embPattern_calcBoundingBox(pattern);
+ embFile_printf(file, "<?xml version=\"1.0\"?>\n");
+ embFile_printf(file, "<!-- Embroidermodder 2 SVG Embroidery File -->\n");
+ embFile_printf(file, "<!-- http://embroidermodder.github.io -->\n");
+ embFile_printf(file, "<svg ");
+
+ /* TODO: See the SVG Tiny Version 1.2 Specification Section 7.14.
+ * Until all of the formats and API is stable, the width, height and viewBox attributes need to be left unspecified.
+ * If the attribute values are incorrect, some applications wont open it at all.
+ embFile_printf(file, "viewBox=\"%f %f %f %f\" ",
+ boundingRect.left,
+ boundingRect.top,
+ embRect_width(boundingRect),
+ embRect_height(boundingRect)); */
+
+ embFile_printf(file, "xmlns=\"http://www.w3.org/2000/svg\" version=\"1.2\" baseProfile=\"tiny\">");
+
+ /*TODO: Low Priority Optimization:
+ * Using %g in embFile_printf just doesn't work good enough at trimming trailing zeroes.
+ * It's precision refers to significant digits, not decimal places (which is what we want).
+ * We need to roll our own function for trimming trailing zeroes to keep
+ * the precision as high as possible if needed, but help reduce file size also. */
+
+ /*TODO: Low Priority Optimization:
+ * Make sure that the line length that is output doesn't exceed 1000 characters. */
+
+ /*TODO: Low Priority: Indent output properly. */
+
+ /* write circles */
+ cObjList = pattern->circleObjList;
+ while(cObjList)
+ {
+ circle = cObjList->circleObj.circle;
+ color = cObjList->circleObj.color;
+ /* TODO: use proper thread width for stoke-width rather than just 0.2 */
+ embFile_printf(file, "\n<circle stroke-width=\"0.2\" stroke=\"#%02x%02x%02x\" fill=\"none\" cx=\"%f\" cy=\"%f\" r=\"%f\" />",
+ color.r,
+ color.g,
+ color.b,
+ circle.centerX,
+ circle.centerY,
+ circle.radius);
+ cObjList = cObjList->next;
+ }
+
+ /* write ellipses */
+ eObjList = pattern->ellipseObjList;
+ while(eObjList)
+ {
+ ellipse = eObjList->ellipseObj.ellipse;
+ color = eObjList->ellipseObj.color;
+ /* TODO: use proper thread width for stoke-width rather than just 0.2 */
+ embFile_printf(file, "\n<ellipse stroke-width=\"0.2\" stroke=\"#%02x%02x%02x\" fill=\"none\" cx=\"%f\" cy=\"%f\" rx=\"%f\" ry=\"%f\" />",
+ color.r,
+ color.g,
+ color.b,
+ ellipse.centerX,
+ ellipse.centerY,
+ ellipse.radiusX,
+ ellipse.radiusY);
+ eObjList = eObjList->next;
+ }
+
+ /* write lines */
+ liObjList = pattern->lineObjList;
+ while(liObjList)
+ {
+ line = liObjList->lineObj.line;
+ color = liObjList->lineObj.color;
+ /* TODO: use proper thread width for stoke-width rather than just 0.2 */
+ embFile_printf(file, "\n<line stroke-width=\"0.2\" stroke=\"#%02x%02x%02x\" fill=\"none\" x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" />",
+ color.r,
+ color.g,
+ color.b,
+ line.x1,
+ line.y1,
+ line.x2,
+ line.y2);
+ liObjList = liObjList->next;
+ }
+
+ /* write points */
+ poObjList = pattern->pointObjList;
+ while(poObjList)
+ {
+ point = poObjList->pointObj.point;
+ color = poObjList->pointObj.color;
+ /* See SVG Tiny 1.2 Spec:
+ * Section 9.5 The 'line' element
+ * Section C.6 'path' element implementation notes */
+ /* TODO: use proper thread width for stoke-width rather than just 0.2 */
+ embFile_printf(file, "\n<line stroke-linecap=\"round\" stroke-width=\"0.2\" stroke=\"#%02x%02x%02x\" fill=\"none\" x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" />",
+ color.r,
+ color.g,
+ color.b,
+ point.xx,
+ point.yy,
+ point.xx,
+ point.yy);
+ poObjList = poObjList->next;
+ }
+
+ /* write polygons */
+ pogObjList = pattern->polygonObjList;
+ while(pogObjList)
+ {
+ pogPointList = pogObjList->polygonObj->pointList;
+ if(pogPointList)
+ {
+ color = pogObjList->polygonObj->color;
+ /* TODO: use proper thread width for stoke-width rather than just 0.2 */
+ embFile_printf(file, "\n<polygon stroke-linejoin=\"round\" stroke-linecap=\"round\" stroke-width=\"0.2\" stroke=\"#%02x%02x%02x\" fill=\"none\" points=\"%s,%s",
+ color.r,
+ color.g,
+ color.b,
+ emb_optOut(pogPointList->point.xx, tmpX),
+ emb_optOut(pogPointList->point.yy, tmpY));
+ pogPointList = pogPointList->next;
+ while(pogPointList)
+ {
+ embFile_printf(file, " %s,%s", emb_optOut(pogPointList->point.xx, tmpX), emb_optOut(pogPointList->point.yy, tmpY));
+ pogPointList = pogPointList->next;
+ }
+ embFile_printf(file, "\"/>");
+ }
+ pogObjList = pogObjList->next;
+ }
+
+ /* write polylines */
+ polObjList = pattern->polylineObjList;
+ while(polObjList)
+ {
+ polPointList = polObjList->polylineObj->pointList;
+ if(polPointList)
+ {
+ color = polObjList->polylineObj->color;
+ /* TODO: use proper thread width for stoke-width rather than just 0.2 */
+ embFile_printf(file, "\n<polyline stroke-linejoin=\"round\" stroke-linecap=\"round\" stroke-width=\"0.2\" stroke=\"#%02x%02x%02x\" fill=\"none\" points=\"%s,%s",
+ color.r,
+ color.g,
+ color.b,
+ emb_optOut(polPointList->point.xx, tmpX),
+ emb_optOut(polPointList->point.yy, tmpY));
+ polPointList = polPointList->next;
+ while(polPointList)
+ {
+ embFile_printf(file, " %s,%s", emb_optOut(polPointList->point.xx, tmpX), emb_optOut(polPointList->point.yy, tmpY));
+ polPointList = polPointList->next;
+ }
+ embFile_printf(file, "\"/>");
+ }
+ polObjList = polObjList->next;
+ }
+
+ /* write rects */
+ rObjList = pattern->rectObjList;
+ while(rObjList)
+ {
+ rect = rObjList->rectObj.rect;
+ color = rObjList->rectObj.color;
+ /* TODO: use proper thread width for stoke-width rather than just 0.2 */
+ embFile_printf(file, "\n<rect stroke-width=\"0.2\" stroke=\"#%02x%02x%02x\" fill=\"none\" x=\"%f\" y=\"%f\" width=\"%f\" height=\"%f\" />",
+ color.r,
+ color.g,
+ color.b,
+ embRect_x(rect),
+ embRect_y(rect),
+ embRect_width(rect),
+ embRect_height(rect));
+ rObjList = rObjList->next;
+ }
+
+ stList = pattern->stitchList;
+ if(stList)
+ {
+ /*TODO: #ifdef SVG_DEBUG for Josh which outputs JUMPS/TRIMS instead of chopping them out */
+ char isNormal = 0;
+ while(stList)
+ {
+ if(stList->stitch.flags == NORMAL && !isNormal)
+ {
+ isNormal = 1;
+ color = embThreadList_getAt(pattern->threadList, stList->stitch.color).color;
+ /* TODO: use proper thread width for stoke-width rather than just 0.2 */
+ embFile_printf(file, "\n<polyline stroke-linejoin=\"round\" stroke-linecap=\"round\" stroke-width=\"0.2\" stroke=\"#%02x%02x%02x\" fill=\"none\" points=\"%s,%s",
+ color.r,
+ color.g,
+ color.b,
+ emb_optOut(stList->stitch.xx, tmpX),
+ emb_optOut(stList->stitch.yy, tmpY));
+ }
+ else if(stList->stitch.flags == NORMAL && isNormal)
+ {
+ embFile_printf(file, " %s,%s", emb_optOut(stList->stitch.xx, tmpX), emb_optOut(stList->stitch.yy, tmpY));
+ }
+ else if(stList->stitch.flags != NORMAL && isNormal)
+ {
+ isNormal = 0;
+ embFile_printf(file, "\"/>");
+ }
+
+ stList = stList->next;
+ }
+ }
+ embFile_printf(file, "\n</svg>\n");
+ embFile_close(file);
+
+ /* Reset the pattern so future writes(regardless of format) are not flipped */
+ embPattern_flipVertical(pattern);
+
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-svg.h b/Software/Visual_Studio/Embroidery/libembroidery/format-svg.h
new file mode 100644
index 000000000..9c12f1ea9
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-svg.h
@@ -0,0 +1,80 @@
+/*! @file format-svg.h */
+#ifndef FORMAT_SVG_H
+#define FORMAT_SVG_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct SvgAttribute_ SvgAttribute;
+typedef struct SvgAttributeList_ SvgAttributeList;
+typedef struct SvgElement_ SvgElement;
+
+struct SvgAttribute_
+{
+ char* name;
+ char* value;
+};
+
+struct SvgAttributeList_
+{
+ SvgAttribute attribute;
+ SvgAttributeList* next;
+};
+
+struct SvgElement_
+{
+ char* name;
+ SvgAttributeList* attributeList;
+ SvgAttributeList* lastAttribute;
+};
+
+typedef enum
+{
+ SVG_CREATOR_NULL,
+ SVG_CREATOR_EMBROIDERMODDER,
+ SVG_CREATOR_ILLUSTRATOR,
+ SVG_CREATOR_INKSCAPE
+} SVG_CREATOR;
+
+typedef enum
+{
+ SVG_EXPECT_NULL,
+ SVG_EXPECT_ELEMENT,
+ SVG_EXPECT_ATTRIBUTE,
+ SVG_EXPECT_VALUE
+} SVG_EXPECT;
+
+typedef enum
+{
+ SVG_NULL,
+ SVG_ELEMENT,
+ SVG_PROPERTY,
+ SVG_MEDIA_PROPERTY,
+ SVG_ATTRIBUTE,
+ SVG_CATCH_ALL
+} SVG_TYPES;
+
+extern EMB_PRIVATE int EMB_CALL readSvg(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeSvg(EmbPattern* pattern, const char* fileName);
+
+int svgCreator;
+
+int svgExpect;
+int svgMultiValue;
+
+SvgElement* currentElement;
+char* currentAttribute;
+char* currentValue;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_SVG_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-t01.c b/Software/Visual_Studio/Embroidery/libembroidery/format-t01.c
new file mode 100644
index 000000000..dc3bb0c18
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-t01.c
@@ -0,0 +1,220 @@
+#include "format-t01.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+#include "helpers-misc.h"
+#include <stdio.h>
+
+static int decodeRecordFlags(unsigned char b2)
+{
+ if (b2 == 0xF3)
+ {
+ return END;
+ }
+ switch(b2 & 0xC3)
+ {
+ case 0x03:
+ return NORMAL;
+ case 0x83:
+ return TRIM;
+ case 0xC3:
+ return STOP;
+ default:
+ return NORMAL;
+ }
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readT01(EmbPattern* pattern, const char* fileName)
+{
+ unsigned char b[3];
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-t01.c readt01(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-t01.c readt01(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-t01.c readt01(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embPattern_loadExternalColorFile(pattern, fileName);
+
+ while(embFile_read(b, 1, 3, file) == 3)
+ {
+ int flags;
+ int x = 0;
+ int y = 0;
+ if(b[0] & 0x01)
+ x += 1;
+ if(b[0] & 0x02)
+ x -= 1;
+ if(b[0] & 0x04)
+ x += 9;
+ if(b[0] & 0x08)
+ x -= 9;
+ if(b[0] & 0x80)
+ y += 1;
+ if(b[0] & 0x40)
+ y -= 1;
+ if(b[0] & 0x20)
+ y += 9;
+ if(b[0] & 0x10)
+ y -= 9;
+ if(b[1] & 0x01)
+ x += 3;
+ if(b[1] & 0x02)
+ x -= 3;
+ if(b[1] & 0x04)
+ x += 27;
+ if(b[1] & 0x08)
+ x -= 27;
+ if(b[1] & 0x80)
+ y += 3;
+ if(b[1] & 0x40)
+ y -= 3;
+ if(b[1] & 0x20)
+ y += 27;
+ if(b[1] & 0x10)
+ y -= 27;
+ if(b[2] & 0x04)
+ x += 81;
+ if(b[2] & 0x08)
+ x -= 81;
+ if(b[2] & 0x20)
+ y += 81;
+ if(b[2] & 0x10)
+ y -= 81;
+ flags = decodeRecordFlags(b[2]);
+ embPattern_addStitchRel(pattern, x / 10.0, y / 10.0, flags, 1);
+ if(flags == END)
+ break;
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+static unsigned char setbit(int pos)
+{
+ return (unsigned char)(1 << pos);
+}
+
+static void encode_record(EmbFile* file, int x, int y, int flags)
+{
+ char b0, b1, b2;
+ b0 = b1 = b2 = 0;
+
+ /* cannot encode values > +121 or < -121. */
+ if (x > 121 || x < -121) embLog_error("format-t01.c encode_record(), x is not in valid range [-121,121] , x = %d\n", x);
+ if (y > 121 || y < -121) embLog_error("format-t01.c encode_record(), y is not in valid range [-121,121] , y = %d\n", y);
+
+ if (x >= +41) { b2 += setbit(2); x -= 81; }
+ if (x <= -41) { b2 += setbit(3); x += 81; }
+ if (x >= +14) { b1 += setbit(2); x -= 27; }
+ if (x <= -14) { b1 += setbit(3); x += 27; }
+ if (x >= +5) { b0 += setbit(2); x -= 9; }
+ if (x <= -5) { b0 += setbit(3); x += 9; }
+ if (x >= +2) { b1 += setbit(0); x -= 3; }
+ if (x <= -2) { b1 += setbit(1); x += 3; }
+ if (x >= +1) { b0 += setbit(0); x -= 1; }
+ if (x <= -1) { b0 += setbit(1); x += 1; }
+ if (x != 0) { embLog_error("format-dst.c encode_record(), x should be zero yet x = %d\n", x); }
+ if (y >= +41) { b2 += setbit(5); y -= 81; }
+ if (y <= -41) { b2 += setbit(4); y += 81; }
+ if (y >= +14) { b1 += setbit(5); y -= 27; }
+ if (y <= -14) { b1 += setbit(4); y += 27; }
+ if (y >= +5) { b0 += setbit(5); y -= 9; }
+ if (y <= -5) { b0 += setbit(4); y += 9; }
+ if (y >= +2) { b1 += setbit(7); y -= 3; }
+ if (y <= -2) { b1 += setbit(6); y += 3; }
+ if (y >= +1) { b0 += setbit(7); y -= 1; }
+ if (y <= -1) { b0 += setbit(6); y += 1; }
+ if (y != 0) { embLog_error("format-dst.c encode_record(), y should be zero yet y = %d\n", y); }
+
+ b2 |= (char)3;
+
+ if (flags & END)
+ {
+ b0 = 0;
+ b1 = 0;
+ b2 = 0xF3;
+ }
+ if (flags & (JUMP | TRIM))
+ {
+ b2 = (char)(b2 | 0x83);
+ }
+ if (flags & STOP)
+ {
+ b2 = (char)(b2 | 0xC3);
+ }
+
+ binaryWriteByte(file, (unsigned char)b0);
+ binaryWriteByte(file, (unsigned char)b1);
+ binaryWriteByte(file, (unsigned char)b2);
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeT01(EmbPattern* pattern, const char* fileName)
+{
+ EmbRect boundingRect;
+ EmbFile* file = 0;
+ int xx, yy, dx, dy, flags;
+ int co = 1, st = 0;
+ int ax, ay, mx, my;
+ EmbStitchList* pointer = 0;
+
+ if (!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-t01.c writeDst(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if (pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ file = embFile_open(fileName, "wb");
+ if (!file)
+ {
+ embLog_error("format-t01.c writet01(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+
+ embPattern_correctForMaxStitchLength(pattern, 12.1, 12.1);
+
+ xx = yy = 0;
+ co = 1;
+ co = embThreadList_count(pattern->threadList);
+ st = 0;
+ st = embStitchList_count(pattern->stitchList);
+ flags = NORMAL;
+ boundingRect = embPattern_calcBoundingBox(pattern);
+ ax = ay = mx = my = 0;
+ xx = yy = 0;
+ pointer = pattern->stitchList;
+ while (pointer)
+ {
+ /* convert from mm to 0.1mm for file format */
+ dx = roundDouble(pointer->stitch.xx * 10.0) - xx;
+ dy = roundDouble(pointer->stitch.yy * 10.0) - yy;
+ xx = roundDouble(pointer->stitch.xx * 10.0);
+ yy = roundDouble(pointer->stitch.yy * 10.0);
+ flags = pointer->stitch.flags;
+ encode_record(file, dx, dy, flags);
+ pointer = pointer->next;
+ }
+ embFile_close(file);
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
+
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-t01.h b/Software/Visual_Studio/Embroidery/libembroidery/format-t01.h
new file mode 100644
index 000000000..6a5573b34
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-t01.h
@@ -0,0 +1,22 @@
+/*! @file format-tap.h */
+#ifndef FORMAT_T01_H
+#define FORMAT_T01_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readT01(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeT01(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_T01_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-t09.c b/Software/Visual_Studio/Embroidery/libembroidery/format-t09.c
new file mode 100644
index 000000000..60a01811f
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-t09.c
@@ -0,0 +1,72 @@
+#include "format-t09.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readT09(EmbPattern* pattern, const char* fileName)
+{
+ unsigned char b[3];
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-t09.c readT09(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-t09.c readT09(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-t09.c readT09(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embFile_seek(file, 0x0C, SEEK_SET);
+
+ while(embFile_read(b, 1, 3, file) == 3)
+ {
+ int stitchType = NORMAL;
+ int b1 = b[0];
+ int b2 = b[1];
+ unsigned char commandByte = b[2];
+ if(commandByte == 0x00)
+ {
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+ break;
+ }
+ if(commandByte & 0x10) stitchType = STOP;
+ if(commandByte & 0x20) b1 = -b1;
+ if(commandByte & 0x40) b2 = -b2;
+
+ embPattern_addStitchRel(pattern, b2 / 10.0, b1 / 10.0, stitchType, 1);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeT09(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-t09.c writeT09(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-t09.c writeT09(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-t09.c writeT09(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writeT09 */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-t09.h b/Software/Visual_Studio/Embroidery/libembroidery/format-t09.h
new file mode 100644
index 000000000..4d13bf323
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-t09.h
@@ -0,0 +1,22 @@
+/*! @file format-t09.h */
+#ifndef FORMAT_T09_H
+#define FORMAT_T09_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readT09(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeT09(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_T09_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-tap.c b/Software/Visual_Studio/Embroidery/libembroidery/format-tap.c
new file mode 100644
index 000000000..98e637a56
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-tap.c
@@ -0,0 +1,220 @@
+#include "format-tap.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+#include "helpers-misc.h"
+#include <stdio.h>
+
+static int decodeRecordFlags(unsigned char b2)
+{
+ if (b2 == 0xF3)
+ {
+ return END;
+ }
+ switch(b2 & 0xC3)
+ {
+ case 0x03:
+ return NORMAL;
+ case 0x83:
+ return TRIM;
+ case 0xC3:
+ return STOP;
+ default:
+ return NORMAL;
+ }
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readTap(EmbPattern* pattern, const char* fileName)
+{
+ unsigned char b[3];
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-tap.c readTap(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-tap.c readTap(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-tap.c readTap(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embPattern_loadExternalColorFile(pattern, fileName);
+
+ while(embFile_read(b, 1, 3, file) == 3)
+ {
+ int flags;
+ int x = 0;
+ int y = 0;
+ if(b[0] & 0x01)
+ x += 1;
+ if(b[0] & 0x02)
+ x -= 1;
+ if(b[0] & 0x04)
+ x += 9;
+ if(b[0] & 0x08)
+ x -= 9;
+ if(b[0] & 0x80)
+ y += 1;
+ if(b[0] & 0x40)
+ y -= 1;
+ if(b[0] & 0x20)
+ y += 9;
+ if(b[0] & 0x10)
+ y -= 9;
+ if(b[1] & 0x01)
+ x += 3;
+ if(b[1] & 0x02)
+ x -= 3;
+ if(b[1] & 0x04)
+ x += 27;
+ if(b[1] & 0x08)
+ x -= 27;
+ if(b[1] & 0x80)
+ y += 3;
+ if(b[1] & 0x40)
+ y -= 3;
+ if(b[1] & 0x20)
+ y += 27;
+ if(b[1] & 0x10)
+ y -= 27;
+ if(b[2] & 0x04)
+ x += 81;
+ if(b[2] & 0x08)
+ x -= 81;
+ if(b[2] & 0x20)
+ y += 81;
+ if(b[2] & 0x10)
+ y -= 81;
+ flags = decodeRecordFlags(b[2]);
+ embPattern_addStitchRel(pattern, x / 10.0, y / 10.0, flags, 1);
+ if(flags == END)
+ break;
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+static unsigned char setbit(int pos)
+{
+ return (unsigned char)(1 << pos);
+}
+
+static void encode_record(EmbFile* file, int x, int y, int flags)
+{
+ char b0, b1, b2;
+ b0 = b1 = b2 = 0;
+
+ /* cannot encode values > +121 or < -121. */
+ if (x > 121 || x < -121) embLog_error("format-tap.c encode_record(), x is not in valid range [-121,121] , x = %d\n", x);
+ if (y > 121 || y < -121) embLog_error("format-tap.c encode_record(), y is not in valid range [-121,121] , y = %d\n", y);
+
+ if (x >= +41) { b2 += setbit(2); x -= 81; }
+ if (x <= -41) { b2 += setbit(3); x += 81; }
+ if (x >= +14) { b1 += setbit(2); x -= 27; }
+ if (x <= -14) { b1 += setbit(3); x += 27; }
+ if (x >= +5) { b0 += setbit(2); x -= 9; }
+ if (x <= -5) { b0 += setbit(3); x += 9; }
+ if (x >= +2) { b1 += setbit(0); x -= 3; }
+ if (x <= -2) { b1 += setbit(1); x += 3; }
+ if (x >= +1) { b0 += setbit(0); x -= 1; }
+ if (x <= -1) { b0 += setbit(1); x += 1; }
+ if (x != 0) { embLog_error("format-tap.c encode_record(), x should be zero yet x = %d\n", x); }
+ if (y >= +41) { b2 += setbit(5); y -= 81; }
+ if (y <= -41) { b2 += setbit(4); y += 81; }
+ if (y >= +14) { b1 += setbit(5); y -= 27; }
+ if (y <= -14) { b1 += setbit(4); y += 27; }
+ if (y >= +5) { b0 += setbit(5); y -= 9; }
+ if (y <= -5) { b0 += setbit(4); y += 9; }
+ if (y >= +2) { b1 += setbit(7); y -= 3; }
+ if (y <= -2) { b1 += setbit(6); y += 3; }
+ if (y >= +1) { b0 += setbit(7); y -= 1; }
+ if (y <= -1) { b0 += setbit(6); y += 1; }
+ if (y != 0) { embLog_error("format-tap.c encode_record(), y should be zero yet y = %d\n", y); }
+
+ b2 |= (char)3;
+
+ if (flags & END)
+ {
+ b0 = 0;
+ b1 = 0;
+ b2 = 0xF3;
+ }
+ if (flags & (JUMP | TRIM))
+ {
+ b2 = (char)(b2 | 0x83);
+ }
+ if (flags & STOP)
+ {
+ b2 = (char)(b2 | 0xC3);
+ }
+
+ binaryWriteByte(file, (unsigned char)b0);
+ binaryWriteByte(file, (unsigned char)b1);
+ binaryWriteByte(file, (unsigned char)b2);
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeTap(EmbPattern* pattern, const char* fileName)
+{
+ EmbRect boundingRect;
+ EmbFile* file = 0;
+ int xx, yy, dx, dy, flags;
+ int co = 1, st = 0;
+ int ax, ay, mx, my;
+ EmbStitchList* pointer = 0;
+
+ if (!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-tap.c writeDst(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if (pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ file = embFile_open(fileName, "wb");
+ if (!file)
+ {
+ embLog_error("format-tap.c writeDst(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+
+ embPattern_correctForMaxStitchLength(pattern, 12.1, 12.1);
+
+ xx = yy = 0;
+ co = 1;
+ co = embThreadList_count(pattern->threadList);
+ st = 0;
+ st = embStitchList_count(pattern->stitchList);
+ flags = NORMAL;
+ boundingRect = embPattern_calcBoundingBox(pattern);
+ ax = ay = mx = my = 0;
+ xx = yy = 0;
+ pointer = pattern->stitchList;
+ while (pointer)
+ {
+ /* convert from mm to 0.1mm for file format */
+ dx = roundDouble(pointer->stitch.xx * 10.0) - xx;
+ dy = roundDouble(pointer->stitch.yy * 10.0) - yy;
+ xx = roundDouble(pointer->stitch.xx * 10.0);
+ yy = roundDouble(pointer->stitch.yy * 10.0);
+ flags = pointer->stitch.flags;
+ encode_record(file, dx, dy, flags);
+ pointer = pointer->next;
+ }
+ embFile_close(file);
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
+
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-tap.h b/Software/Visual_Studio/Embroidery/libembroidery/format-tap.h
new file mode 100644
index 000000000..463b05372
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-tap.h
@@ -0,0 +1,22 @@
+/*! @file format-tap.h */
+#ifndef FORMAT_TAP_H
+#define FORMAT_TAP_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readTap(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeTap(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_TAP_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-thr.c b/Software/Visual_Studio/Embroidery/libembroidery/format-thr.c
new file mode 100644
index 000000000..e327758ba
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-thr.c
@@ -0,0 +1,282 @@
+#include "format-thr.h"
+#include "helpers-binary.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include <string.h>
+
+#define NOTFRM 0x00080000
+
+typedef struct ThredHeader_ /* thred file header */
+{
+ unsigned int sigVersion; /* signature and version */
+ unsigned int length; /* length of ThredHeader + length of stitch data */
+ unsigned short numStiches; /* number of stitches */
+ unsigned short hoopSize; /* size of hoop */
+ unsigned short reserved[7]; /* reserved for expansion */
+} ThredHeader;
+
+typedef struct ThredExtension_ /* thred v1.0 file header extension */
+{
+ float hoopX; /* hoop size x dimension in 1/6 mm units */
+ float hoopY; /* hoop size y dimension in 1/6 mm units */
+ float stitchGranularity; /* stitches per millimeter--not implemented */
+ char creatorName[50]; /* name of the file creator */
+ char modifierName[50]; /* name of last file modifier */
+ char auxFormat; /* auxillary file format, 0=PCS,1=DST,2=PES */
+ char reserved[31]; /* reserved for expansion */
+} ThredExtension;
+
+/*
+bit definitions for attributes of stitch
+0-3 stitch color
+4-14 form pointer
+15-18 spares
+19 not a form stitch
+20 center walk stitch
+21 edge walk stitch
+22 underlay stitch
+23 knot stitch
+24 feather stitch
+25-27 layer
+28 spare
+29-30 stitch type 00=not a form stitch, 01=form fill, 10=form border fill, 11=applique stitches
+31 set for user edited stitches
+*/
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readThr(EmbPattern* pattern, const char* fileName)
+{
+ ThredHeader header;
+ unsigned char r, g, b;
+ int currentColor;
+ int i;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-thr.c readThr(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-thr.c readThr(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-thr.c readThr(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ header.sigVersion = binaryReadUInt32(file);
+ header.length = binaryReadUInt32(file);
+ header.numStiches = binaryReadUInt16(file);
+ header.hoopSize = binaryReadUInt16(file);
+ header.reserved[0] = binaryReadUInt16(file);
+ header.reserved[1] = binaryReadUInt16(file);
+ header.reserved[2] = binaryReadUInt16(file);
+ header.reserved[3] = binaryReadUInt16(file);
+ header.reserved[4] = binaryReadUInt16(file);
+ header.reserved[5] = binaryReadUInt16(file);
+ header.reserved[6] = binaryReadUInt16(file);
+
+ if((header.sigVersion & 0xffffff) == 0x746872)
+ {
+ unsigned int verVar = (header.sigVersion & 0xff000000) >> 24;
+ switch(verVar)
+ {
+ case 0:
+ break;
+ case 1:
+ case 2:
+ embFile_seek(file, 144, SEEK_CUR); /* skip the file header extension */
+ break;
+ default:
+ return 0; /* unsuported version */
+ }
+ }
+
+ currentColor = -1;
+ for(i = 0; i < header.numStiches; i++)
+ {
+ int type = NORMAL;
+ float x = binaryReadFloat(file) / 10.0f;
+ float y = binaryReadFloat(file) / 10.0f;
+ unsigned int color = binaryReadUInt32(file);
+
+ if((int)(color & 0xF) != currentColor)
+ {
+ currentColor = (int)color & 0xF;
+ embPattern_changeColor(pattern, currentColor);
+ type = STOP | TRIM;
+ }
+ embPattern_addStitchAbs(pattern, x, y, type, 0);
+ }
+ embFile_seek(file, 16, SEEK_CUR); /* skip bitmap name (16 chars) */
+
+ r = binaryReadByte(file);
+ g = binaryReadByte(file);
+ b = binaryReadByte(file);
+ binaryReadByte(file);
+
+ for(i = 0; i < 16; i++)
+ {
+ EmbThread thread;
+ thread.description = NULL;
+ thread.catalogNumber = NULL;
+ thread.color.r = binaryReadByte(file);
+ thread.color.g = binaryReadByte(file);
+ thread.color.b = binaryReadByte(file);
+ binaryReadByte(file);
+ embPattern_addThread(pattern, thread);
+ }
+ /* 64 bytes of rgbx(4 bytes) colors (16 custom colors) */
+ /* 16 bytes of thread size (ascii representation ie. '4') */
+
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeThr(EmbPattern* pattern, const char* fileName)
+{
+ int i, stitchCount;
+ unsigned char version = 0;
+ ThredHeader header;
+ ThredExtension extension;
+ char bitmapName[16];
+ EmbStitchList* pointer = 0;
+ EmbThreadList* colorpointer = 0;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-thr.c writeThr(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-thr.c writeThr(), fileName argument is null\n"); return 0; }
+
+ stitchCount = embStitchList_count(pattern->stitchList);
+ if(!stitchCount)
+ {
+ embLog_error("format-thr.c writeThr(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ {
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+ stitchCount++;
+ }
+
+ file = embFile_open(fileName, "wb");
+ if(!file)
+ {
+ embLog_error("format-thr.c writeThr(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+
+ memset(&header, 0, sizeof(ThredHeader));
+ header.sigVersion = 0x746872 | (version << 24);
+ header.length = stitchCount * 12 + 16;
+ if(version == 1 || version == 2)
+ {
+ header.length = header.length + sizeof(ThredHeader);
+ }
+ header.numStiches = (unsigned short)stitchCount; /* number of stitches in design */
+ header.hoopSize = 5;
+
+ binaryWriteUInt(file, header.sigVersion);
+ binaryWriteUInt(file, header.length);
+ binaryWriteUShort(file, header.numStiches);
+ binaryWriteUShort(file, header.hoopSize);
+ binaryWriteUShort(file, header.reserved[0]);
+ binaryWriteUShort(file, header.reserved[1]);
+ binaryWriteUShort(file, header.reserved[2]);
+ binaryWriteUShort(file, header.reserved[3]);
+ binaryWriteUShort(file, header.reserved[4]);
+ binaryWriteUShort(file, header.reserved[5]);
+ binaryWriteUShort(file, header.reserved[6]);
+
+ if(version == 1 || version == 2)
+ {
+ memset(&extension, 0, sizeof(ThredExtension));
+ extension.auxFormat = 1;
+ extension.hoopX = 640;
+ extension.hoopY = 640;
+
+ binaryWriteFloat(file, extension.hoopX);
+ binaryWriteFloat(file, extension.hoopY);
+ binaryWriteFloat(file, extension.stitchGranularity);
+ binaryWriteBytes(file, extension.creatorName, 50);
+ binaryWriteBytes(file, extension.modifierName, 50);
+ binaryWriteByte(file, extension.auxFormat);
+ binaryWriteBytes(file, extension.reserved, 31);
+ }
+
+ /* write stitches */
+ i = 0;
+ pointer = pattern->stitchList;
+ while(pointer)
+ {
+ binaryWriteFloat(file, (float)(pointer->stitch.xx * 10.0));
+ binaryWriteFloat(file, (float)(pointer->stitch.yy * 10.0));
+ binaryWriteUInt(file, NOTFRM | (pointer->stitch.color & 0x0F));
+ pointer = pointer->next;
+ i++;
+ if(i >= stitchCount) break;
+ }
+ binaryWriteBytes(file, bitmapName, 16);
+ /* background color */
+ binaryWriteByte(file, 0xFF); /* r */
+ binaryWriteByte(file, 0xFF); /* g */
+ binaryWriteByte(file, 0xFF); /* b */
+ binaryWriteByte(file, 0x00);
+
+ i = 0;
+ colorpointer = pattern->threadList;
+ while(colorpointer)
+ {
+ binaryWriteByte(file, colorpointer->thread.color.r);
+ binaryWriteByte(file, colorpointer->thread.color.g);
+ binaryWriteByte(file, colorpointer->thread.color.b);
+ binaryWriteByte(file, 0);
+ colorpointer = colorpointer->next;
+ i++;
+ if(i >= 16) break;
+ }
+
+ /* write remaining colors if not yet 16 */
+ for(; i < 16; i++)
+ {
+ binaryWriteUInt(file, 0);
+ }
+
+ /* write custom colors */
+ i = 0;
+ colorpointer = pattern->threadList;
+ while(colorpointer)
+ {
+ binaryWriteByte(file, colorpointer->thread.color.r);
+ binaryWriteByte(file, colorpointer->thread.color.g);
+ binaryWriteByte(file, colorpointer->thread.color.b);
+ binaryWriteByte(file, 0);
+ colorpointer = colorpointer->next;
+ i++;
+ if(i >= 16) break;
+ }
+
+ /* write remaining colors if not yet 16 */
+ for(; i < 16; i++)
+ {
+ binaryWriteUInt(file, 0);
+ }
+
+ for(i = 0; i < 16; i++)
+ {
+ binaryWriteByte(file, '4');
+ }
+
+ embFile_close(file);
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-thr.h b/Software/Visual_Studio/Embroidery/libembroidery/format-thr.h
new file mode 100644
index 000000000..f8f9741e4
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-thr.h
@@ -0,0 +1,22 @@
+/*! @file format-thr.h */
+#ifndef FORMAT_THR_H
+#define FORMAT_THR_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readThr(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeThr(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_THR_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-txt.c b/Software/Visual_Studio/Embroidery/libembroidery/format-txt.c
new file mode 100644
index 000000000..06976e728
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-txt.c
@@ -0,0 +1,55 @@
+#include "format-txt.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-misc.h"
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readTxt(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-txt.c readTxt(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-txt.c readTxt(), fileName argument is null\n"); return 0; }
+ return 0; /*TODO: finish readTxt */
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeTxt(EmbPattern* pattern, const char* fileName)
+{
+ EmbStitchList* pointer = 0;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-txt.c writeTxt(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-txt.c writeTxt(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-txt.c writeTxt(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ file = embFile_open(fileName, "w");
+ if(!file)
+ {
+ embLog_error("format-txt.c writeTxt(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+ pointer = pattern->stitchList;
+ embFile_printf(file, "%u\n", (unsigned int) embStitchList_count(pointer));
+
+ while(pointer)
+ {
+ EmbStitch s = pointer->stitch;
+ embFile_printf(file, "%.1f,%.1f color:%i flags:%i\n", s.xx, s.yy, s.color, s.flags);
+ pointer = pointer->next;
+ }
+
+ embFile_close(file);
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-txt.h b/Software/Visual_Studio/Embroidery/libembroidery/format-txt.h
new file mode 100644
index 000000000..bad1ec8b8
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-txt.h
@@ -0,0 +1,22 @@
+/*! @file format-txt.h */
+#ifndef FORMAT_TXT_H
+#define FORMAT_TXT_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readTxt(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeTxt(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_TXT_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-u00.c b/Software/Visual_Studio/Embroidery/libembroidery/format-u00.c
new file mode 100644
index 000000000..7796a8926
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-u00.c
@@ -0,0 +1,96 @@
+#include "format-u00.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include "helpers-binary.h"
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readU00(EmbPattern* pattern, const char* fileName)
+{
+ int i;
+ char dx = 0, dy = 0;
+ int flags = NORMAL;
+ char endOfStream = 0;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-u00.c readU00(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-u00.c readU00(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-u00.c readU00(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ /* 16 3byte RGB's start @ 0x08 followed by 14 bytes between 0 and 15 with index of color for each color change */
+ embFile_seek(file, 0x08, SEEK_SET);
+
+ for(i = 0; i < 16; i++)
+ {
+ EmbThread t;
+ t.color.r = binaryReadUInt8(file);
+ t.color.g = binaryReadUInt8(file);
+ t.color.b = binaryReadUInt8(file);
+ embPattern_addThread(pattern, t);
+ }
+
+ embFile_seek(file, 0x100, SEEK_SET);
+ for(i = 0; !endOfStream; i++)
+ {
+ char negativeX , negativeY;
+ unsigned char b0 = binaryReadUInt8(file);
+ unsigned char b1 = binaryReadUInt8(file);
+ unsigned char b2 = binaryReadUInt8(file);
+
+ if(b0 == 0xF8 || b0 == 0x87 || b0 == 0x91)
+ {
+ break;
+ }
+ if((b0 & 0x0F) == 0)
+ {
+ flags = NORMAL;
+ }
+ else if((b0 & 0x1f) == 1)
+ {
+ flags = JUMP;
+ }
+ else if((b0 & 0x0F) > 0)
+ {
+ flags = STOP;
+ }
+ negativeX = ((b0 & 0x20) > 0);
+ negativeY = ((b0 & 0x40) > 0);
+
+ dx = (char) b2;
+ dy = (char) b1;
+ if(negativeX) dx = (char) -dx;
+ if(negativeY) dy = (char) -dy;
+ embPattern_addStitchRel(pattern, dx / 10.0, dy / 10.0, flags, 1);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeU00(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-u00.c writeU00(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-u00.c writeU00(), fileName argument is null\n"); return 0; }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish WriteU00 */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-u00.h b/Software/Visual_Studio/Embroidery/libembroidery/format-u00.h
new file mode 100644
index 000000000..493ef0b90
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-u00.h
@@ -0,0 +1,22 @@
+/*! @file format-u00.h */
+#ifndef FORMAT_U00_H
+#define FORMAT_U00_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readU00(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeU00(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_U00_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-u01.c b/Software/Visual_Studio/Embroidery/libembroidery/format-u01.c
new file mode 100644
index 000000000..53c2dbbd2
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-u01.c
@@ -0,0 +1,76 @@
+#include "format-u01.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+
+/* TODO: AFAIK this is a duplicate of U00. Review for differences and merge files and handle accordingly. */
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readU01(EmbPattern* pattern, const char* fileName)
+{
+ int fileLength, negativeX = 0, negativeY = 0, flags = NORMAL;
+ char dx, dy;
+ unsigned char data[3];
+ EmbFile* file = 0;
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ return 0;
+ }
+ embFile_seek(file, 0, SEEK_END);
+ fileLength = embFile_tell(file);
+ embFile_seek(file, 0x100, SEEK_SET);
+ while(embFile_read(data, 1, 3, file) == 3)
+ {
+ if(data[0] == 0xF8 || data[0] == 0x87 || data[0] == 0x91)
+ {
+ break;
+ }
+ if((data[0] & 0x0F) == 0)
+ {
+ flags = NORMAL;
+ }
+ else if((data[0] & 0x1f) == 1)
+ {
+ flags = JUMP;
+ }
+ else if((data[0] & 0x0F) > 0)
+ {
+ flags = STOP;
+ }
+ negativeX = ((data[0] & 0x20) > 0);
+ negativeY = ((data[0] & 0x40) > 0);
+
+ dx = (char) data[2];
+ dy = (char) data[1];
+ if(negativeX) dx = (char) -dx;
+ if(negativeY) dy = (char) -dy;
+ embPattern_addStitchRel(pattern, dx / 10.0, dy / 10.0, flags, 1);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeU01(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-u01.c writeU01(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-u01.c writeU01(), fileName argument is null\n"); return 0; }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writeU01 */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-u01.h b/Software/Visual_Studio/Embroidery/libembroidery/format-u01.h
new file mode 100644
index 000000000..cff719e4a
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-u01.h
@@ -0,0 +1,22 @@
+/*! @file format-u01.h */
+#ifndef FORMAT_U01_H
+#define FORMAT_U01_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readU01(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeU01(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_U01_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-vip.c b/Software/Visual_Studio/Embroidery/libembroidery/format-vip.c
new file mode 100644
index 000000000..8d7c16313
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-vip.c
@@ -0,0 +1,350 @@
+#include "format-vip.h"
+#include "helpers-binary.h"
+#include "helpers-misc.h"
+#include "emb-compress.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include <stdlib.h>
+
+static int vipDecodeByte(unsigned char b)
+{
+ if (b >= 0x80) return (-(unsigned char) (~b + 1));
+ return b;
+}
+
+static int vipDecodeStitchType(unsigned char b)
+{
+ switch (b)
+ {
+ case 0x80:
+ return NORMAL;
+ case 0x81:
+ return TRIM;
+ case 0x84:
+ return STOP;
+ case 0x90:
+ return END;
+ default:
+ return NORMAL;
+ }
+}
+
+static unsigned char* vipDecompressData(unsigned char* input, int compressedInputLength, int decompressedContentLength)
+{
+ unsigned char* decompressedData = (unsigned char*)malloc(decompressedContentLength);
+ if(!decompressedData)
+ {
+ embLog_error("format-vip.c vipDecompressData(), cannot allocate memory for decompressedData\n");
+ return 0;
+ }
+ husExpand((unsigned char*)input, decompressedData, compressedInputLength, 10);
+ return decompressedData;
+}
+
+typedef struct VipHeader_
+{
+ int magicCode;
+ int numberOfStitches;
+ int numberOfColors;
+ short postitiveXHoopSize;
+ short postitiveYHoopSize;
+ short negativeXHoopSize;
+ short negativeYHoopSize;
+ int attributeOffset;
+ int xOffset;
+ int yOffset;
+ unsigned char stringVal[8];
+ short unknown;
+ int colorLength;
+} VipHeader;
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readVip(EmbPattern* pattern, const char* fileName)
+{
+ int fileLength;
+ int i;
+ unsigned char prevByte = 0;
+ unsigned char *attributeData = 0, *decodedColors = 0, *attributeDataDecompressed = 0;
+ unsigned char *xData = 0, *xDecompressed = 0, *yData = 0, *yDecompressed = 0;
+ VipHeader header;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-vip.c readVip(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-vip.c readVip(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-vip.c readVip(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embFile_seek(file, 0x0, SEEK_END);
+ fileLength = embFile_tell(file);
+ embFile_seek(file, 0x00, SEEK_SET);
+ header.magicCode = binaryReadInt32(file);
+ header.numberOfStitches = binaryReadInt32(file);
+ header.numberOfColors = binaryReadInt32(file);
+
+ header.postitiveXHoopSize = binaryReadInt16(file);
+ header.postitiveYHoopSize = binaryReadInt16(file);
+ header.negativeXHoopSize = binaryReadInt16(file);
+ header.negativeYHoopSize = binaryReadInt16(file);
+
+ header.attributeOffset = binaryReadInt32(file);
+ header.xOffset = binaryReadInt32(file);
+ header.yOffset = binaryReadInt32(file);
+
+ /*stringVal = (unsigned char*)malloc(sizeof(unsigned char)*8); TODO: review this and uncomment or remove
+ if(!stringVal) { embLog_error("format-vip.c readVip(), cannot allocate memory for stringVal\n"); return 0; }
+ */
+
+ binaryReadBytes(file, header.stringVal, 8); /* TODO: check return value */
+
+ header.unknown = binaryReadInt16(file);
+
+ header.colorLength = binaryReadInt32(file);
+ decodedColors = (unsigned char*)malloc(header.numberOfColors*4);
+ if(!decodedColors) { embLog_error("format-vip.c readVip(), cannot allocate memory for decodedColors\n"); return 0; }
+ for(i = 0; i < header.numberOfColors*4; ++i)
+ {
+ unsigned char inputByte = binaryReadByte(file);
+ unsigned char tmpByte = (unsigned char) (inputByte ^ vipDecodingTable[i]);
+ decodedColors[i] = (unsigned char) (tmpByte ^ prevByte);
+ prevByte = inputByte;
+ }
+ for(i = 0; i < header.numberOfColors; i++)
+ {
+ EmbThread thread;
+ int startIndex = i << 2;
+ thread.color.r = decodedColors[startIndex];
+ thread.color.g = decodedColors[startIndex + 1];
+ thread.color.b = decodedColors[startIndex + 2];
+ /* printf("%d\n", decodedColors[startIndex + 3]); */
+ embPattern_addThread(pattern, thread);
+ }
+ embFile_seek(file, header.attributeOffset, SEEK_SET);
+ attributeData = (unsigned char*)malloc(header.xOffset - header.attributeOffset);
+ if(!attributeData) { embLog_error("format-vip.c readVip(), cannot allocate memory for attributeData\n"); return 0; }
+ binaryReadBytes(file, attributeData, header.xOffset - header.attributeOffset); /* TODO: check return value */
+ attributeDataDecompressed = vipDecompressData(attributeData, header.xOffset - header.attributeOffset, header.numberOfStitches);
+
+ embFile_seek(file, header.xOffset, SEEK_SET);
+ xData = (unsigned char*)malloc(header.yOffset - header.xOffset);
+ if(!xData) { embLog_error("format-vip.c readVip(), cannot allocate memory for xData\n"); return 0; }
+ binaryReadBytes(file, xData, header.yOffset - header.xOffset); /* TODO: check return value */
+ xDecompressed = vipDecompressData(xData, header.yOffset - header.xOffset, header.numberOfStitches);
+
+ embFile_seek(file, header.yOffset, SEEK_SET);
+ yData = (unsigned char*)malloc(fileLength - header.yOffset);
+ if(!yData) { embLog_error("format-vip.c readVip(), cannot allocate memory for yData\n"); return 0; }
+ binaryReadBytes(file, yData, fileLength - header.yOffset); /* TODO: check return value */
+ yDecompressed = vipDecompressData(yData, fileLength - header.yOffset, header.numberOfStitches);
+
+ for(i = 0; i < header.numberOfStitches; i++)
+ {
+ embPattern_addStitchRel(pattern,
+ vipDecodeByte(xDecompressed[i]) / 10.0,
+ vipDecodeByte(yDecompressed[i]) / 10.0,
+ vipDecodeStitchType(attributeDataDecompressed[i]), 1);
+ }
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ embFile_close(file);
+
+ free(attributeData); attributeData = 0;
+ free(xData); xData = 0;
+ free(yData); yData = 0;
+ free(attributeDataDecompressed); attributeDataDecompressed = 0;
+ free(xDecompressed); xDecompressed = 0;
+ free(yDecompressed); yDecompressed = 0;
+
+ return 1;
+}
+
+static unsigned char* vipCompressData(unsigned char* input, int decompressedInputSize, int* compressedSize)
+{
+ unsigned char* compressedData = (unsigned char*)malloc(sizeof(unsigned char)*decompressedInputSize*2);
+ if(!compressedData)
+ {
+ embLog_error("format-vip.c vipCompressData(), cannot allocate memory for compressedData\n");
+ return 0;
+ }
+ *compressedSize = husCompress(input, (unsigned long) decompressedInputSize, compressedData, 10, 0);
+ return compressedData;
+}
+
+static unsigned char vipEncodeByte(double f)
+{
+ return (unsigned char)(int)roundDouble(f);
+}
+
+static unsigned char vipEncodeStitchType(int st)
+{
+ switch(st)
+ {
+ case NORMAL:
+ return (0x80);
+ case JUMP:
+ case TRIM:
+ return (0x81);
+ case STOP:
+ return (0x84);
+ case END:
+ return (0x90);
+ default:
+ return (0x80);
+ }
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeVip(EmbPattern* pattern, const char* fileName)
+{
+ EmbRect boundingRect;
+ int stitchCount, minColors, patternColor;
+ int attributeSize = 0;
+ int xCompressedSize = 0;
+ int yCompressedSize = 0;
+ double previousX = 0;
+ double previousY = 0;
+ unsigned char* xValues = 0, *yValues = 0, *attributeValues = 0;
+ EmbStitchList* pointer = 0;
+ double xx = 0.0;
+ double yy = 0.0;
+ int flags = 0;
+ int i = 0;
+ unsigned char* attributeCompressed = 0, *xCompressed = 0, *yCompressed = 0, *decodedColors = 0, *encodedColors = 0;
+ unsigned char prevByte = 0;
+ EmbThreadList* colorPointer = 0;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-vip.c writeVip(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-vip.c writeVip(), fileName argument is null\n"); return 0; }
+
+ stitchCount = embStitchList_count(pattern->stitchList);
+ if(!stitchCount)
+ {
+ embLog_error("format-vip.c writeVip(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ {
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+ stitchCount++;
+ }
+
+ file = embFile_open(fileName, "wb");
+ if(file == 0)
+ {
+ embLog_error("format-vip.c writeVip(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+
+ minColors = embThreadList_count(pattern->threadList);
+ decodedColors = (unsigned char*)malloc(minColors << 2);
+ if(!decodedColors) return 0;
+ encodedColors = (unsigned char*)malloc(minColors << 2);
+ if(encodedColors) /* TODO: review this line. It looks clearly wrong. If not, note why. */
+ {
+ free(decodedColors);
+ decodedColors = 0;
+ return 0;
+ }
+ /* embPattern_correctForMaxStitchLength(pattern, 0x7F, 0x7F); */
+
+ patternColor = minColors;
+ if(minColors > 24) minColors = 24;
+
+ binaryWriteUInt(file, 0x0190FC5D);
+ binaryWriteUInt(file, stitchCount);
+ binaryWriteUInt(file, minColors);
+
+ boundingRect = embPattern_calcBoundingBox(pattern);
+ binaryWriteShort(file, (short) roundDouble(boundingRect.right * 10.0));
+ binaryWriteShort(file, (short) -roundDouble(boundingRect.top * 10.0 - 1.0));
+ binaryWriteShort(file, (short) roundDouble(boundingRect.left * 10.0));
+ binaryWriteShort(file, (short) -roundDouble(boundingRect.bottom * 10.0 - 1.0));
+
+ binaryWriteUInt(file, 0x38 + (minColors << 3));
+
+ xValues = (unsigned char*)malloc(sizeof(unsigned char)*(stitchCount));
+ yValues = (unsigned char*)malloc(sizeof(unsigned char)*(stitchCount));
+ attributeValues = (unsigned char*)malloc(sizeof(unsigned char)*(stitchCount));
+ if(xValues && yValues && attributeValues)
+ {
+ pointer = pattern->stitchList;
+ while(pointer)
+ {
+ xx = pointer->stitch.xx;
+ yy = pointer->stitch.yy;
+ flags = pointer->stitch.flags;
+ xValues[i] = vipEncodeByte((xx - previousX) * 10.0);
+ previousX = xx;
+ yValues[i] = vipEncodeByte((yy - previousY) * 10.0);
+ previousY = yy;
+ attributeValues[i] = vipEncodeStitchType(flags);
+ pointer = pointer->next;
+ i++;
+ }
+ attributeCompressed = vipCompressData(attributeValues, stitchCount, &attributeSize);
+ xCompressed = vipCompressData(xValues, stitchCount, &xCompressedSize);
+ yCompressed = vipCompressData(yValues, stitchCount, &yCompressedSize);
+
+ binaryWriteUInt(file, (unsigned int) (0x38 + (minColors << 3) + attributeSize));
+ binaryWriteUInt(file, (unsigned int) (0x38 + (minColors << 3) + attributeSize + xCompressedSize));
+ binaryWriteUInt(file, 0x00000000);
+ binaryWriteUInt(file, 0x00000000);
+ binaryWriteUShort(file, 0x0000);
+
+ binaryWriteInt(file, minColors << 2);
+
+ colorPointer = pattern->threadList;
+
+ for(i = 0; i < minColors; i++)
+ {
+ int byteChunk = i << 2;
+ EmbColor currentColor = colorPointer->thread.color;
+ decodedColors[byteChunk] = currentColor.r;
+ decodedColors[byteChunk + 1] = currentColor.g;
+ decodedColors[byteChunk + 2] = currentColor.b;
+ decodedColors[byteChunk + 3] = 0x01;
+ colorPointer = colorPointer->next;
+ }
+
+ for(i = 0; i < minColors << 2; ++i)
+ {
+ unsigned char tmpByte = (unsigned char) (decodedColors[i] ^ vipDecodingTable[i]);
+ prevByte = (unsigned char) (tmpByte ^ prevByte);
+ binaryWriteByte(file, prevByte);
+ }
+ for(i = 0; i <= minColors; i++)
+ {
+ binaryWriteInt(file, 1);
+ }
+ binaryWriteUInt(file, 0); /* string length */
+ binaryWriteShort(file, 0);
+ binaryWriteBytes(file, (char*) attributeCompressed, attributeSize);
+ binaryWriteBytes(file, (char*) xCompressed, xCompressedSize);
+ binaryWriteBytes(file, (char*) yCompressed, yCompressedSize);
+ }
+
+ if(attributeCompressed) { free(attributeCompressed); attributeCompressed = 0; }
+ if(xCompressed) { free(xCompressed); xCompressed = 0; }
+ if(yCompressed) { free(yCompressed); yCompressed = 0; }
+
+ if(attributeValues) { free(attributeValues); attributeValues = 0; }
+ if(xValues) { free(xValues); xValues = 0; }
+ if(yValues) { free(yValues); yValues = 0; }
+
+ if(decodedColors) { free(decodedColors); decodedColors = 0; }
+ if(encodedColors) { free(encodedColors); encodedColors = 0; }
+
+ embFile_close(file);
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-vip.h b/Software/Visual_Studio/Embroidery/libembroidery/format-vip.h
new file mode 100644
index 000000000..0e4009b88
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-vip.h
@@ -0,0 +1,50 @@
+/*! @file format-vip.h */
+#ifndef FORMAT_VIP_H
+#define FORMAT_VIP_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readVip(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeVip(EmbPattern* pattern, const char* fileName);
+
+static const unsigned char vipDecodingTable[] = {
+ 0x2E, 0x82, 0xE4, 0x6F, 0x38, 0xA9, 0xDC, 0xC6, 0x7B, 0xB6, 0x28, 0xAC, 0xFD, 0xAA, 0x8A, 0x4E,
+ 0x76, 0x2E, 0xF0, 0xE4, 0x25, 0x1B, 0x8A, 0x68, 0x4E, 0x92, 0xB9, 0xB4, 0x95, 0xF0, 0x3E, 0xEF,
+ 0xF7, 0x40, 0x24, 0x18, 0x39, 0x31, 0xBB, 0xE1, 0x53, 0xA8, 0x1F, 0xB1, 0x3A, 0x07, 0xFB, 0xCB,
+ 0xE6, 0x00, 0x81, 0x50, 0x0E, 0x40, 0xE1, 0x2C, 0x73, 0x50, 0x0D, 0x91, 0xD6, 0x0A, 0x5D, 0xD6,
+ 0x8B, 0xB8, 0x62, 0xAE, 0x47, 0x00, 0x53, 0x5A, 0xB7, 0x80, 0xAA, 0x28, 0xF7, 0x5D, 0x70, 0x5E,
+ 0x2C, 0x0B, 0x98, 0xE3, 0xA0, 0x98, 0x60, 0x47, 0x89, 0x9B, 0x82, 0xFB, 0x40, 0xC9, 0xB4, 0x00,
+ 0x0E, 0x68, 0x6A, 0x1E, 0x09, 0x85, 0xC0, 0x53, 0x81, 0xD1, 0x98, 0x89, 0xAF, 0xE8, 0x85, 0x4F,
+ 0xE3, 0x69, 0x89, 0x03, 0xA1, 0x2E, 0x8F, 0xCF, 0xED, 0x91, 0x9F, 0x58, 0x1E, 0xD6, 0x84, 0x3C,
+ 0x09, 0x27, 0xBD, 0xF4, 0xC3, 0x90, 0xC0, 0x51, 0x1B, 0x2B, 0x63, 0xBC, 0xB9, 0x3D, 0x40, 0x4D,
+ 0x62, 0x6F, 0xE0, 0x8C, 0xF5, 0x5D, 0x08, 0xFD, 0x3D, 0x50, 0x36, 0xD7, 0xC9, 0xC9, 0x43, 0xE4,
+ 0x2D, 0xCB, 0x95, 0xB6, 0xF4, 0x0D, 0xEA, 0xC2, 0xFD, 0x66, 0x3F, 0x5E, 0xBD, 0x69, 0x06, 0x2A,
+ 0x03, 0x19, 0x47, 0x2B, 0xDF, 0x38, 0xEA, 0x4F, 0x80, 0x49, 0x95, 0xB2, 0xD6, 0xF9, 0x9A, 0x75,
+ 0xF4, 0xD8, 0x9B, 0x1D, 0xB0, 0xA4, 0x69, 0xDB, 0xA9, 0x21, 0x79, 0x6F, 0xD8, 0xDE, 0x33, 0xFE,
+ 0x9F, 0x04, 0xE5, 0x9A, 0x6B, 0x9B, 0x73, 0x83, 0x62, 0x7C, 0xB9, 0x66, 0x76, 0xF2, 0x5B, 0xC9,
+ 0x5E, 0xFC, 0x74, 0xAA, 0x6C, 0xF1, 0xCD, 0x93, 0xCE, 0xE9, 0x80, 0x53, 0x03, 0x3B, 0x97, 0x4B,
+ 0x39, 0x76, 0xC2, 0xC1, 0x56, 0xCB, 0x70, 0xFD, 0x3B, 0x3E, 0x52, 0x57, 0x81, 0x5D, 0x56, 0x8D,
+ 0x51, 0x90, 0xD4, 0x76, 0xD7, 0xD5, 0x16, 0x02, 0x6D, 0xF2, 0x4D, 0xE1, 0x0E, 0x96, 0x4F, 0xA1,
+ 0x3A, 0xA0, 0x60, 0x59, 0x64, 0x04, 0x1A, 0xE4, 0x67, 0xB6, 0xED, 0x3F, 0x74, 0x20, 0x55, 0x1F,
+ 0xFB, 0x23, 0x92, 0x91, 0x53, 0xC8, 0x65, 0xAB, 0x9D, 0x51, 0xD6, 0x73, 0xDE, 0x01, 0xB1, 0x80,
+ 0xB7, 0xC0, 0xD6, 0x80, 0x1C, 0x2E, 0x3C, 0x83, 0x63, 0xEE, 0xBC, 0x33, 0x25, 0xE2, 0x0E, 0x7A,
+ 0x67, 0xDE, 0x3F, 0x71, 0x14, 0x49, 0x9C, 0x92, 0x93, 0x0D, 0x26, 0x9A, 0x0E, 0xDA, 0xED, 0x6F,
+ 0xA4, 0x89, 0x0C, 0x1B, 0xF0, 0xA1, 0xDF, 0xE1, 0x9E, 0x3C, 0x04, 0x78, 0xE4, 0xAB, 0x6D, 0xFF,
+ 0x9C, 0xAF, 0xCA, 0xC7, 0x88, 0x17, 0x9C, 0xE5, 0xB7, 0x33, 0x6D, 0xDC, 0xED, 0x8F, 0x6C, 0x18,
+ 0x1D, 0x71, 0x06, 0xB1, 0xC5, 0xE2, 0xCF, 0x13, 0x77, 0x81, 0xC5, 0xB7, 0x0A, 0x14, 0x0A, 0x6B,
+ 0x40, 0x26, 0xA0, 0x88, 0xD1, 0x62, 0x6A, 0xB3, 0x50, 0x12, 0xB9, 0x9B, 0xB5, 0x83, 0x9B, 0x37
+ };
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_VIP_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-vp3.c b/Software/Visual_Studio/Embroidery/libembroidery/format-vp3.c
new file mode 100644
index 000000000..701d768a5
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-vp3.c
@@ -0,0 +1,533 @@
+#include "format-vp3.h"
+#include "helpers-binary.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include <stdlib.h>
+#include <string.h>
+
+static unsigned char* vp3ReadString(EmbFile* file)
+{
+ int stringLength = 0;
+ unsigned char* charString = 0;
+ if(!file) { embLog_error("format-vp3.c vp3ReadString(), file argument is null\n"); return 0; }
+ stringLength = binaryReadInt16BE(file);
+ charString = (unsigned char*)malloc(stringLength);
+ if(!charString) { embLog_error("format-vp3.c vp3ReadString(), cannot allocate memory for charString\n"); return 0; }
+ binaryReadBytes(file, charString, stringLength); /* TODO: check return value */
+ return charString;
+}
+
+static int vp3Decode(unsigned char inputByte)
+{
+ if(inputByte > 0x80)
+ {
+ return (int)-((unsigned char)((~inputByte) + 1));
+ }
+ return ((int)inputByte);
+}
+
+static short vp3DecodeInt16(unsigned short inputByte)
+{
+ if(inputByte > 0x8000)
+ {
+ return -((short) ((~inputByte) + 1));
+ }
+ return ((short)inputByte);
+}
+
+typedef struct _vp3Hoop
+{
+ int right;
+ int bottom;
+ int left;
+ int top;
+ int threadLength;
+ char unknown2;
+ unsigned char numberOfColors;
+ unsigned short unknown3;
+ int unknown4;
+ int numberOfBytesRemaining;
+
+ int xOffset;
+ int yOffset;
+
+ unsigned char byte1;
+ unsigned char byte2;
+ unsigned char byte3;
+
+ /* Centered hoop dimensions */
+ int right2;
+ int left2;
+ int bottom2;
+ int top2;
+
+ int width;
+ int height;
+} vp3Hoop;
+
+static vp3Hoop vp3ReadHoopSection(EmbFile* file)
+{
+ vp3Hoop hoop;
+
+ if(!file)
+ {
+ embLog_error("format-vp3.c vp3ReadHoopSection(), file argument is null\n");
+ hoop.bottom = 0;
+ hoop.left = 0;
+ hoop.right = 0;
+ hoop.top = 0;
+ return hoop;
+ }
+
+ hoop.right = binaryReadInt32BE(file);
+ hoop.bottom = binaryReadInt32BE(file);
+ hoop.left = binaryReadInt32BE(file);
+ hoop.top = binaryReadInt32BE(file);
+
+ hoop.threadLength = binaryReadInt32(file); /* yes, it seems this is _not_ big endian */
+ hoop.unknown2 = binaryReadByte(file);
+ hoop.numberOfColors = binaryReadByte(file);
+ hoop.unknown3 = binaryReadInt16BE(file);
+ hoop.unknown4 = binaryReadInt32BE(file);
+ hoop.numberOfBytesRemaining = binaryReadInt32BE(file);
+
+ hoop.xOffset = binaryReadInt32BE(file);
+ hoop.yOffset = binaryReadInt32BE(file);
+
+ hoop.byte1 = binaryReadByte(file);
+ hoop.byte2 = binaryReadByte(file);
+ hoop.byte3 = binaryReadByte(file);
+
+ /* Centered hoop dimensions */
+ hoop.right2 = binaryReadInt32BE(file);
+ hoop.left2 = binaryReadInt32BE(file);
+ hoop.bottom2 = binaryReadInt32BE(file);
+ hoop.top2 = binaryReadInt32BE(file);
+
+ hoop.width = binaryReadInt32BE(file);
+ hoop.height = binaryReadInt32BE(file);
+ return hoop;
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readVp3(EmbPattern* pattern, const char* fileName)
+{
+ unsigned char magicString[5];
+ unsigned char some;
+ unsigned char* softwareVendorString = 0;
+ unsigned char v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18;
+ unsigned char* anotherSoftwareVendorString = 0;
+ int numberOfColors;
+ long colorSectionOffset;
+ unsigned char magicCode[6];
+ short someShort;
+ unsigned char someByte;
+ int bytesRemainingInFile;
+ unsigned char* fileCommentString = 0; /* some software writes used settings here */
+ int hoopConfigurationOffset;
+ unsigned char* anotherCommentString = 0;
+ int i;
+ EmbFile* file = 0;
+
+ if(!pattern) { embLog_error("format-vp3.c readVp3(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-vp3.c readVp3(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-vp3.c readVp3(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ binaryReadBytes(file, magicString, 5); /* %vsm% */ /* TODO: check return value */
+
+ some = binaryReadByte(file); /* 0 */
+ softwareVendorString = vp3ReadString(file);
+ someShort = binaryReadInt16(file);
+ someByte = binaryReadByte(file);
+ bytesRemainingInFile = binaryReadInt32(file);
+ fileCommentString = vp3ReadString(file);
+ hoopConfigurationOffset = (int)embFile_tell(file);
+
+ vp3ReadHoopSection(file);
+
+ anotherCommentString = vp3ReadString(file);
+
+ /* TODO: review v1 thru v18 variables and use emb_unused() if needed */
+ v1 = binaryReadByte(file);
+ v2 = binaryReadByte(file);
+ v3 = binaryReadByte(file);
+ v4 = binaryReadByte(file);
+ v5 = binaryReadByte(file);
+ v6 = binaryReadByte(file);
+ v7 = binaryReadByte(file);
+ v8 = binaryReadByte(file);
+ v9 = binaryReadByte(file);
+ v10 = binaryReadByte(file);
+ v11 = binaryReadByte(file);
+ v12 = binaryReadByte(file);
+ v13 = binaryReadByte(file);
+ v14 = binaryReadByte(file);
+ v15 = binaryReadByte(file);
+ v16 = binaryReadByte(file);
+ v17 = binaryReadByte(file);
+ v18 = binaryReadByte(file);
+
+ binaryReadBytes(file, magicCode, 6); /* 0x78 0x78 0x55 0x55 0x01 0x00 */ /* TODO: check return value */
+
+ anotherSoftwareVendorString = vp3ReadString(file);
+
+ numberOfColors = binaryReadInt16BE(file);
+ embLog_error("format-vp3.c Number of Colors: %d\n", numberOfColors);
+ colorSectionOffset = (int)embFile_tell(file);
+
+ for(i = 0; i < numberOfColors; i++)
+ {
+ EmbThread t;
+ char tableSize;
+ int startX, startY, offsetToNextColorX, offsetToNextColorY;
+ unsigned char* threadColorNumber, *colorName, *threadVendor;
+ int unknownThreadString, numberOfBytesInColor;
+
+ embFile_seek(file, colorSectionOffset, SEEK_SET);
+ embLog_error("format-vp3.c Color Check Byte #1: 0 == %d\n", binaryReadByte(file));
+ embLog_error("format-vp3.c Color Check Byte #2: 5 == %d\n", binaryReadByte(file));
+ embLog_error("format-vp3.c Color Check Byte #3: 0 == %d\n", binaryReadByte(file));
+ colorSectionOffset = binaryReadInt32BE(file);
+ colorSectionOffset += embFile_tell(file);
+ startX = binaryReadInt32BE(file);
+ startY = binaryReadInt32BE(file);
+ embPattern_addStitchAbs(pattern, startX / 1000.0, -startY / 1000.0, JUMP, 1);
+
+ tableSize = binaryReadByte(file);
+ binaryReadByte(file);
+ t.color.r = binaryReadByte(file);
+ t.color.g = binaryReadByte(file);
+ t.color.b = binaryReadByte(file);
+ embPattern_addThread(pattern, t);
+ embFile_seek(file, 6*tableSize - 1, SEEK_CUR);
+
+ threadColorNumber = vp3ReadString(file);
+ colorName = vp3ReadString(file);
+ threadVendor = vp3ReadString(file);
+
+ offsetToNextColorX = binaryReadInt32BE(file);
+ offsetToNextColorY = binaryReadInt32BE(file);
+
+ unknownThreadString = binaryReadInt16BE(file);
+ embFile_seek(file, unknownThreadString, SEEK_CUR);
+ numberOfBytesInColor = binaryReadInt32BE(file);
+ embFile_seek(file, 0x3, SEEK_CUR);
+ while(embFile_tell(file) < colorSectionOffset - 1)
+ {
+ int lastFilePosition = embFile_tell(file);
+
+ int x = vp3Decode(binaryReadByte(file));
+ int y = vp3Decode(binaryReadByte(file));
+ if(x == 0x80)
+ {
+ switch (y)
+ {
+ case 0x00:
+ case 0x03:
+ break;
+ case 0x01:
+ x = vp3DecodeInt16(binaryReadUInt16BE(file));
+ y = vp3DecodeInt16(binaryReadUInt16BE(file));
+ binaryReadInt16BE(file);
+ embPattern_addStitchRel(pattern, x/ 10.0, y / 10.0, TRIM, 1);
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ embPattern_addStitchRel(pattern, x / 10.0, y / 10.0, NORMAL, 1);
+ }
+
+ if(embFile_tell(file) == lastFilePosition)
+ {
+ embLog_error("format-vp3.c could not read stitch block in entirety\n");
+ return 0;
+ }
+ }
+ if(i + 1 < numberOfColors)
+ embPattern_addStitchRel(pattern, 0, 0, STOP, 1);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ embPattern_flipVertical(pattern);
+
+ return 1;
+}
+
+void vp3WriteStringLen(EmbFile* file, const char* str, int len)
+{
+ binaryWriteUShortBE(file, len);
+ binaryWriteBytes(file, str, len);
+}
+
+void vp3WriteString(EmbFile* file, const char* str)
+{
+ vp3WriteStringLen(file, str, strlen(str));
+}
+
+void vp3PatchByteCount(EmbFile* file, int offset, int adjustment)
+{
+ int currentPos = embFile_tell(file);
+ embFile_seek(file, offset, SEEK_SET);
+ embLog_print("Patching byte count: %d\n", currentPos - offset + adjustment);
+ binaryWriteIntBE(file, currentPos - offset + adjustment);
+ embFile_seek(file, currentPos, SEEK_SET);
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeVp3(EmbPattern* pattern, const char* fileName)
+{
+ EmbFile *file = 0;
+ EmbRect bounds;
+ int remainingBytesPos, remainingBytesPos2;
+ int colorSectionStitchBytes;
+ int first = 1;
+ int numberOfColors = 0;
+ EmbColor color = embColor_make(0xFE, 0xFE, 0xFE);
+ EmbStitchList *mainPointer = 0, *pointer = 0;
+
+ if(!pattern) { embLog_error("format-vp3.c writeVp3(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-vp3.c writeVp3(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-vp3.c writeVp3(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ bounds = embPattern_calcBoundingBox(pattern);
+
+ file = embFile_open(fileName, "wb");
+ if(!file)
+ {
+ embLog_error("format-vp3.c writeVp3(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+
+ embPattern_correctForMaxStitchLength(pattern, 3200.0, 3200.0); /* VP3 can encode signed 16bit deltas */
+
+ embPattern_flipVertical(pattern);
+
+ binaryWriteBytes(file, "%vsm%", 5);
+ binaryWriteByte(file, 0);
+ vp3WriteString(file, "Embroidermodder");
+ binaryWriteByte(file, 0);
+ binaryWriteByte(file, 2);
+ binaryWriteByte(file, 0);
+
+ remainingBytesPos = embFile_tell(file);
+ binaryWriteInt(file, 0); /* placeholder */
+ vp3WriteString(file, "");
+ binaryWriteIntBE(file, bounds.right * 1000);
+ binaryWriteIntBE(file, bounds.bottom * 1000);
+ binaryWriteIntBE(file, bounds.left * 1000);
+ binaryWriteIntBE(file, bounds.top * 1000);
+ binaryWriteInt(file, 0); /* this would be some (unknown) function of thread length */
+ binaryWriteByte(file, 0);
+
+ numberOfColors = 0;
+
+ mainPointer = pattern->stitchList;
+ while(mainPointer)
+ {
+ int flag;
+ EmbColor newColor;
+
+ pointer = mainPointer;
+ flag = pointer->stitch.flags;
+ newColor = embThreadList_getAt(pattern->threadList, pointer->stitch.color).color;
+ if(newColor.r != color.r || newColor.g != color.g || newColor.b != color.b)
+ {
+ numberOfColors++;
+ color.r = newColor.r;
+ color.g = newColor.g;
+ color.b = newColor.b;
+ }
+ else if(flag & END || flag & STOP)
+ {
+ numberOfColors++;
+ }
+
+ while(pointer && (flag == pointer->stitch.flags))
+ {
+ pointer = pointer->next;
+ }
+ mainPointer = pointer;
+ }
+
+ binaryWriteByte(file, numberOfColors);
+ binaryWriteByte(file, 12);
+ binaryWriteByte(file, 0);
+ binaryWriteByte(file, 1);
+ binaryWriteByte(file, 0);
+ binaryWriteByte(file, 3);
+ binaryWriteByte(file, 0);
+
+ remainingBytesPos2 = embFile_tell(file);
+ binaryWriteInt(file, 0); /* placeholder */
+
+ binaryWriteIntBE(file, 0); /* origin X */
+ binaryWriteIntBE(file, 0); /* origin Y */
+ binaryWriteByte(file, 0);
+ binaryWriteByte(file, 0);
+ binaryWriteByte(file, 0);
+
+ binaryWriteIntBE(file, bounds.right * 1000);
+ binaryWriteIntBE(file, bounds.bottom * 1000);
+ binaryWriteIntBE(file, bounds.left * 1000);
+ binaryWriteIntBE(file, bounds.top * 1000);
+
+ binaryWriteIntBE(file, (bounds.right - bounds.left) * 1000);
+ binaryWriteIntBE(file, (bounds.bottom - bounds.top) * 1000);
+
+ vp3WriteString(file, "");
+ binaryWriteShortBE(file, 25700);
+ binaryWriteIntBE(file, 4096);
+ binaryWriteIntBE(file, 0);
+ binaryWriteIntBE(file, 0);
+ binaryWriteIntBE(file, 4096);
+
+ binaryWriteBytes(file, "xxPP\x01\0", 6);
+ vp3WriteString(file, "");
+ binaryWriteShortBE(file, numberOfColors);
+
+ mainPointer = pattern->stitchList;
+ while(mainPointer)
+ {
+ char colorName[8] = { 0 };
+ double lastX, lastY;
+ int colorSectionLengthPos;
+ EmbStitch s;
+ int lastColor;
+
+ if (!first)
+ {
+ binaryWriteByte(file, 0);
+ }
+ binaryWriteByte(file, 0);
+ binaryWriteByte(file, 5);
+ binaryWriteByte(file, 0);
+
+ colorSectionLengthPos = embFile_tell(file);
+ binaryWriteInt(file, 0); /* placeholder */
+
+ pointer = mainPointer;
+ color = embThreadList_getAt(pattern->threadList, pointer->stitch.color).color;
+
+ if (first && pointer->stitch.flags & JUMP && pointer->next->stitch.flags & JUMP)
+ {
+ pointer = pointer->next;
+ }
+
+ s = pointer->stitch;
+ embLog_print("format-vp3.c DEBUG %d, %lf, %lf\n", s.flags, s.xx, s.yy);
+ binaryWriteIntBE(file, s.xx * 1000);
+ binaryWriteIntBE(file, -s.yy * 1000);
+ pointer = pointer->next;
+
+ first = 0;
+
+ lastX = s.xx;
+ lastY = s.yy;
+ lastColor = s.color;
+
+ binaryWriteByte(file, 1);
+ binaryWriteByte(file, 0);
+
+ embLog_print("format-vp3.c writeVp3(), switching to color (%d, %d, %d)\n", color.r, color.g, color.b);
+ binaryWriteByte(file, color.r);
+ binaryWriteByte(file, color.g);
+ binaryWriteByte(file, color.b);
+
+ binaryWriteByte(file, 0);
+ binaryWriteByte(file, 0);
+ binaryWriteByte(file, 0);
+ binaryWriteByte(file, 5);
+ binaryWriteByte(file, 40);
+
+ vp3WriteString(file, "");
+
+ sprintf(colorName, "#%02x%02x%02x", color.b, color.g, color.r);
+
+ vp3WriteString(file, colorName);
+ vp3WriteString(file, "");
+
+ binaryWriteIntBE(file, 0);
+ binaryWriteIntBE(file, 0);
+
+ vp3WriteStringLen(file, "\0", 1);
+
+ colorSectionStitchBytes = embFile_tell(file);
+ binaryWriteInt(file, 0); /* placeholder */
+
+ binaryWriteByte(file, 10);
+ binaryWriteByte(file, 246);
+ binaryWriteByte(file, 0);
+
+ while(pointer)
+ {
+ int dx, dy;
+
+ EmbStitch s = pointer->stitch;
+ if (s.color != lastColor)
+ {
+ break;
+ }
+ if (s.flags & END || s.flags & STOP)
+ {
+ break;
+ }
+ dx = (s.xx - lastX) * 10;
+ dy = (s.yy - lastY) * 10;
+ lastX = lastX + dx / 10.0; /* output is in ints, ensure rounding errors do not sum up */
+ lastY = lastY + dy / 10.0;
+
+ if(dx < -127 || dx > 127 || dy < -127 || dy > 127)
+ {
+ binaryWriteByte(file, 128);
+ binaryWriteByte(file, 1);
+ binaryWriteShortBE(file, dx);
+ binaryWriteShortBE(file, dy);
+ binaryWriteByte(file, 128);
+ binaryWriteByte(file, 2);
+ }
+ else
+ {
+ binaryWriteByte(file, dx);
+ binaryWriteByte(file, dy);
+ }
+
+ pointer = pointer->next;
+ }
+
+ vp3PatchByteCount(file, colorSectionStitchBytes, -4);
+ vp3PatchByteCount(file, colorSectionLengthPos, -3);
+
+ mainPointer = pointer;
+ }
+
+ vp3PatchByteCount(file, remainingBytesPos2, -4);
+ vp3PatchByteCount(file, remainingBytesPos, -4);
+
+ embFile_close(file);
+
+ embPattern_flipVertical(pattern);
+
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-vp3.h b/Software/Visual_Studio/Embroidery/libembroidery/format-vp3.h
new file mode 100644
index 000000000..0294ed1ed
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-vp3.h
@@ -0,0 +1,22 @@
+/*! @file format-vp3.h */
+#ifndef FORMAT_VP3_H
+#define FORMAT_VP3_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readVp3(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeVp3(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_VP3_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-xxx.c b/Software/Visual_Studio/Embroidery/libembroidery/format-xxx.c
new file mode 100644
index 000000000..dbdba676a
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-xxx.c
@@ -0,0 +1,283 @@
+#include "format-xxx.h"
+#include "helpers-binary.h"
+#include "helpers-misc.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+#include <stdlib.h>
+#include <string.h>
+
+static char xxxDecodeByte(unsigned char inputByte)
+{
+ if(inputByte >= 0x80)
+ return (char) ((-~inputByte) - 1);
+ return ((char) inputByte);
+}
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readXxx(EmbPattern* pattern, const char* fileName)
+{
+ EmbFile* file = 0;
+ unsigned char b0, b1;
+ int dx = 0, dy = 0;
+ int flags;
+ char endOfStream = 0;
+ int numberOfColors;
+ int paletteOffset;
+ int i;
+ char thisStitchJump = 0;
+ EmbStitchList* lastStitch = 0;
+ EmbStitchList* secondLast = 0;
+
+ if(!pattern) { embLog_error("format-xxx.c readXxx(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-xxx.c readXxx(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-xxx.c readXxx(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embFile_seek(file, 0x27, SEEK_SET);
+ numberOfColors = binaryReadInt16(file);
+ embFile_seek(file, 0xFC, SEEK_SET);
+ paletteOffset = binaryReadInt32(file);
+ embFile_seek(file, paletteOffset + 6, SEEK_SET);
+
+ for(i = 0; i < numberOfColors; i++)
+ {
+ EmbThread thread;
+ binaryReadByte(file);
+ thread.color.r = binaryReadByte(file);
+ thread.color.g = binaryReadByte(file);
+ thread.color.b = binaryReadByte(file);
+ embPattern_addThread(pattern, thread);
+ }
+ embFile_seek(file, 0x100, SEEK_SET);
+
+ for(i = 0; !endOfStream && embFile_tell(file) < paletteOffset; i++)
+ {
+ flags = NORMAL;
+ if(thisStitchJump) flags = TRIM;
+ thisStitchJump = 0;
+ b0 = binaryReadByte(file);
+ b1 = binaryReadByte(file);
+
+ if(b0 == 0x7E || b0 == 0x7D) /* TODO: ARE THERE OTHER BIG JUMP CODES? */
+ {
+ dx = b1 + (binaryReadByte(file) << 8);
+ dx = ((short) dx);
+ dy = binaryReadInt16(file);
+ flags = TRIM;
+ }
+ else if(b0 == 0x7F)
+ {
+ if(b1 != 0x17 && b1 != 0x46 && b1 >= 8) /* TODO: LOOKS LIKE THESE CODES ARE IN THE HEADER */
+ {
+ b0 = 0;
+ b1 = 0;
+ thisStitchJump = 1;
+ flags = STOP;
+ }
+ else if(b1 == 1)
+ {
+ flags = TRIM;
+ b0 = binaryReadByte(file);
+ b1 = binaryReadByte(file);
+ }
+ else
+ {
+ continue;
+ }
+ dx = xxxDecodeByte(b0);
+ dy = xxxDecodeByte(b1);
+ }
+ else
+ {
+ dx = xxxDecodeByte(b0);
+ dy = xxxDecodeByte(b1);
+ }
+ embPattern_addStitchRel(pattern, dx / 10.0, dy / 10.0, flags, 1);
+ }
+ lastStitch = pattern->stitchList;
+ secondLast = 0;
+ if(lastStitch)
+ {
+ while(lastStitch->next)
+ {
+ secondLast = lastStitch;
+ lastStitch = lastStitch->next;
+ }
+ if((!pattern->stitchList) && lastStitch->stitch.flags == STOP && secondLast)
+ {
+ free(lastStitch);
+ lastStitch = 0;
+ secondLast->next = NULL;
+ embPattern_changeColor(pattern, pattern->currentColorIndex - 1);
+ }
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ return 1;
+}
+
+static void xxxEncodeStop(EmbFile* file, EmbStitch s)
+{
+ binaryWriteByte(file, (unsigned char)0x7F);
+ binaryWriteByte(file, (unsigned char)(s.color + 8));
+}
+
+static void xxxEncodeStitch(EmbFile* file, double deltaX, double deltaY, int flags)
+{
+ if((flags & (JUMP | TRIM)) && (fabs(deltaX) > 124 || fabs(deltaY) > 124))
+ {
+ binaryWriteByte(file, 0x7E);
+ binaryWriteShort(file, (short)deltaX);
+ binaryWriteShort(file, (short)deltaY);
+ }
+ else
+ {
+ /* TODO: Verify this works after changing this to unsigned char */
+ binaryWriteByte(file, (unsigned char)roundDouble(deltaX));
+ binaryWriteByte(file, (unsigned char)roundDouble(deltaY));
+ }
+}
+
+static void xxxEncodeDesign(EmbFile* file, EmbPattern* p)
+{
+ double thisX = 0.0f;
+ double thisY = 0.0f;
+ EmbStitchList* stitches = 0;
+
+ if(!embStitchList_empty(p->stitchList))
+ {
+ thisX = (float)p->stitchList->stitch.xx;
+ thisY = (float)p->stitchList->stitch.yy;
+ }
+ stitches = p->stitchList;
+ while(stitches)
+ {
+ EmbStitch s = stitches->stitch;
+ double deltaX, deltaY;
+ double previousX = thisX;
+ double previousY = thisY;
+ thisX = s.xx;
+ thisY = s.yy;
+ deltaX = thisX - previousX;
+ deltaY = thisY - previousY;
+ if(s.flags & STOP)
+ {
+ xxxEncodeStop(file, s);
+ }
+ else if(s.flags & END)
+ {
+ }
+ else
+ {
+ xxxEncodeStitch(file, deltaX * 10.0f, deltaY * 10.0f, s.flags);
+ }
+ stitches = stitches->next;
+ }
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeXxx(EmbPattern* pattern, const char* fileName)
+{
+ EmbFile* file = 0;
+ int i;
+ EmbRect rect;
+ int endOfStitches;
+ EmbThreadList* colors = 0;
+ int curColor = 0;
+
+ if(!pattern) { embLog_error("format-xxx.c writeXxx(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-xxx.c writeXxx(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-xxx.c writeXxx(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ file = embFile_open(fileName, "wb");
+ if(!file)
+ {
+ embLog_error("format-xxx.c writeXxx(), cannot open %s for writing\n", fileName);
+ return 0;
+ }
+
+ embPattern_correctForMaxStitchLength(pattern, 124, 127);
+
+ for(i = 0; i < 0x17; i++)
+ {
+ binaryWriteByte(file, 0x00);
+ }
+ binaryWriteUInt(file, (unsigned int) embStitchList_count(pattern->stitchList));
+ for(i = 0; i < 0x0C; i++)
+ {
+ binaryWriteByte(file, 0x00);
+ }
+ binaryWriteUShort(file, (unsigned short)embThreadList_count(pattern->threadList));
+ binaryWriteShort(file, 0x0000);
+
+ rect = embPattern_calcBoundingBox(pattern);
+ binaryWriteShort(file, (short)(embRect_width(rect) * 10.0));
+ binaryWriteShort(file, (short)(embRect_height(rect) * 10.0));
+
+ binaryWriteShort(file, (short)(embRect_width(rect) / 2.0 * 10)); /*TODO: xEnd from start point x=0 */
+ binaryWriteShort(file, (short)(embRect_height(rect) / 2.0 * 10)); /*TODO: yEnd from start point y=0 */
+ binaryWriteShort(file, (short)(embRect_width(rect)/2.0 * 10)); /*TODO: left from start x = 0 */
+ binaryWriteShort(file, (short)(embRect_height(rect)/2.0 * 10)); /*TODO: bottom from start y = 0 */
+ for(i = 0; i < 0xC5; i++)
+ {
+ binaryWriteByte(file, 0x00);
+ }
+ binaryWriteInt(file, 0x0000); /* place holder for end of stitches */
+
+ xxxEncodeDesign(file, pattern);
+
+ endOfStitches = embFile_tell(file);
+
+ embFile_seek(file, 0xFC, SEEK_SET);
+
+ binaryWriteUInt(file, endOfStitches);
+
+ embFile_seek(file, 0, SEEK_END);
+
+ binaryWriteByte(file, 0x7F); /* is this really correct? */
+ binaryWriteByte(file, 0x7F);
+ binaryWriteByte(file, 0x03);
+ binaryWriteByte(file, 0x14);
+ binaryWriteByte(file, 0x00);
+ binaryWriteByte(file, 0x00);
+ colors = pattern->threadList;
+ while(colors)
+ {
+ binaryWriteByte(file, 0x00);
+ binaryWriteByte(file, colors->thread.color.r);
+ binaryWriteByte(file, colors->thread.color.g);
+ binaryWriteByte(file, colors->thread.color.b);
+ curColor++;
+ colors = colors->next;
+ }
+ for(i = 0; i < (22 - curColor); i++)
+ {
+ binaryWriteUInt(file, 0x01000000);
+ }
+ binaryWriteByte(file, 0x00);
+ binaryWriteByte(file, 0x01);
+ embFile_close(file);
+ return 1;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-xxx.h b/Software/Visual_Studio/Embroidery/libembroidery/format-xxx.h
new file mode 100644
index 000000000..42c1a421b
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-xxx.h
@@ -0,0 +1,22 @@
+/*! @file format-xxx.h */
+#ifndef FORMAT_XXX_H
+#define FORMAT_XXX_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readXxx(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeXxx(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_XXX_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-zsk.c b/Software/Visual_Studio/Embroidery/libembroidery/format-zsk.c
new file mode 100644
index 000000000..1d6ab5376
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-zsk.c
@@ -0,0 +1,112 @@
+#include "format-zsk.h"
+#include "helpers-binary.h"
+#include "helpers-misc.h"
+#include "emb-file.h"
+#include "emb-logging.h"
+
+/*! Reads a file with the given \a fileName and loads the data into \a pattern.
+ * Returns \c true if successful, otherwise returns \c false. */
+int readZsk(EmbPattern* pattern, const char* fileName)
+{
+ char b[3];
+ EmbFile* file = 0;
+ int stitchType;
+ unsigned char colorNumber;
+ if(!pattern) { embLog_error("format-zsk.c readZsk(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-zsk.c readZsk(), fileName argument is null\n"); return 0; }
+
+ file = embFile_open(fileName, "rb");
+ if(!file)
+ {
+ embLog_error("format-zsk.c readZsk(), cannot open %s for reading\n", fileName);
+ return 0;
+ }
+
+ embFile_seek(file, 0x230, SEEK_SET);
+ colorNumber = binaryReadUInt8(file);
+ while(colorNumber != 0)
+ {
+ EmbThread t;
+ t.color.r = binaryReadUInt8(file);
+ t.color.g = binaryReadUInt8(file);
+ t.color.b = binaryReadUInt8(file);
+ t.catalogNumber = "";
+ t.description = "";
+ embPattern_addThread(pattern, t);
+ embFile_seek(file, 0x48, SEEK_CUR);
+ colorNumber = binaryReadUInt8(file);
+ }
+ embFile_seek(file, 0x2E, SEEK_CUR);
+
+ while(embFile_read(b, 1, 3, file) == 3)
+ {
+ stitchType = NORMAL;
+ if (b[0] & 0x4)
+ {
+ b[2] = -b[2];
+ }
+ if (b[0] & 0x8)
+ {
+ b[1] = -b[1];
+ }
+ if (b[0] & 0x02)
+ {
+ stitchType = JUMP;
+ }
+ if(b[0] & 0x20)
+ {
+ if (b[1] == 2)
+ {
+ stitchType = TRIM;
+ }
+ else if (b[1] == -1)
+ {
+ break;
+ }
+ else
+ {
+ if (b[2] != 0)
+ {
+ colorNumber = b[2];
+ }
+ stitchType = STOP; /* TODO: need to determine what b[1] is used for.*/
+ embPattern_changeColor(pattern, colorNumber - 1);
+ }
+ b[1] = 0;
+ b[2] = 0;
+ }
+ embPattern_addStitchRel(pattern, b[1] / 10.0, b[2] / 10.0, stitchType, 0);
+ }
+ embFile_close(file);
+
+ /* Check for an END stitch and add one if it is not present */
+ if (pattern->lastStitch->stitch.flags != END)
+ {
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+ }
+ return 1;
+}
+
+/*! Writes the data from \a pattern to a file with the given \a fileName.
+ * Returns \c true if successful, otherwise returns \c false. */
+int writeZsk(EmbPattern* pattern, const char* fileName)
+{
+ if(!pattern) { embLog_error("format-zsk.c writeZsk(), pattern argument is null\n"); return 0; }
+ if(!fileName) { embLog_error("format-zsk.c writeZsk(), fileName argument is null\n"); return 0; }
+
+ if(!embStitchList_count(pattern->stitchList))
+ {
+ embLog_error("format-zsk.c writeZsk(), pattern contains no stitches\n");
+ return 0;
+ }
+
+ /* Check for an END stitch and add one if it is not present */
+ if(pattern->lastStitch->stitch.flags != END)
+ embPattern_addStitchRel(pattern, 0, 0, END, 1);
+
+ /* TODO: embFile_open() needs to occur here after the check for no stitches */
+
+ return 0; /*TODO: finish writeZsk */
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/format-zsk.h b/Software/Visual_Studio/Embroidery/libembroidery/format-zsk.h
new file mode 100644
index 000000000..610c8d348
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/format-zsk.h
@@ -0,0 +1,22 @@
+/*! @file format-zsk.h */
+#ifndef FORMAT_ZSK_H
+#define FORMAT_ZSK_H
+
+#include "emb-pattern.h"
+
+#include "api-start.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EMB_PRIVATE int EMB_CALL readZsk(EmbPattern* pattern, const char* fileName);
+extern EMB_PRIVATE int EMB_CALL writeZsk(EmbPattern* pattern, const char* fileName);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#include "api-stop.h"
+
+#endif /* FORMAT_ZSK_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/formats.h b/Software/Visual_Studio/Embroidery/libembroidery/formats.h
new file mode 100644
index 000000000..2235193b6
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/formats.h
@@ -0,0 +1,76 @@
+#ifndef FORMATS_H
+#define FORMATS_H
+
+#ifdef ARDUINO /* ARDUINO TODO: This is temporary. Remove when complete. */
+
+#include "format-exp.h"
+
+#else /* ARDUINO TODO: This is temporary. Remove when complete. */
+
+#include "format-10o.h"
+#include "format-100.h"
+#include "format-art.h"
+#include "format-bmc.h"
+#include "format-bro.h"
+#include "format-cnd.h"
+#include "format-col.h"
+#include "format-csd.h"
+#include "format-csv.h"
+#include "format-dat.h"
+#include "format-dem.h"
+#include "format-dsb.h"
+#include "format-dst.h"
+#include "format-dsz.h"
+#include "format-dxf.h"
+#include "format-edr.h"
+#include "format-emd.h"
+#include "format-exp.h"
+#include "format-exy.h"
+#include "format-eys.h"
+#include "format-fxy.h"
+#include "format-gc.h"
+#include "format-gnc.h"
+#include "format-gt.h"
+#include "format-hus.h"
+#include "format-inb.h"
+#include "format-inf.h"
+#include "format-jef.h"
+#include "format-ksm.h"
+#include "format-max.h"
+#include "format-mit.h"
+#include "format-new.h"
+#include "format-ofm.h"
+#include "format-pcd.h"
+#include "format-pcm.h"
+#include "format-pcq.h"
+#include "format-pcs.h"
+#include "format-pec.h"
+#include "format-pel.h"
+#include "format-pem.h"
+#include "format-pes.h"
+#include "format-phb.h"
+#include "format-phc.h"
+#include "format-plt.h"
+#include "format-rgb.h"
+#include "format-sew.h"
+#include "format-shv.h"
+#include "format-sst.h"
+#include "format-stx.h"
+#include "format-svg.h"
+#include "format-t01.h"
+#include "format-t09.h"
+#include "format-tap.h"
+#include "format-thr.h"
+#include "format-txt.h"
+#include "format-u00.h"
+#include "format-u01.h"
+#include "format-vip.h"
+#include "format-vp3.h"
+#include "format-xxx.h"
+#include "format-zsk.h"
+
+#endif /* ARDUINO TODO: This is temporary. Remove when complete. */
+
+#endif /* FORMATS_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/geom-arc.c b/Software/Visual_Studio/Embroidery/libembroidery/geom-arc.c
new file mode 100644
index 000000000..2406605a9
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/geom-arc.c
@@ -0,0 +1,279 @@
+/* Computational Geometry for Arcs */
+#include "geom-arc.h"
+#include "geom-line.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265358979
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+double radians(double degree) { return (double)(degree*M_PI/180.0); }
+double degrees(double radian) { return (double)(radian*180.0/M_PI); }
+
+/* Calculus based approach at determining whether a polygon is clockwise or counterclockwise.
+ * Returns true if arc is clockwise. */
+char isArcClockwise(double startx, double starty, double midx, double midy, double endx, double endy)
+{
+ double edge1 = (midx-startx)*(midy+starty);
+ double edge2 = (endx-midx)*(endy+midy);
+ double edge3 = (startx-endx)*(starty+endy);
+ if(edge1 + edge2 + edge3 >= 0.0)
+ return 1;
+ return 0;
+}
+
+/* Calculates the CenterPoint of the Arc */
+void getArcCenter(double arcStartX, double arcStartY,
+ double arcMidX, double arcMidY,
+ double arcEndX, double arcEndY,
+ /* returned data */
+ double* arcCenterX, double* arcCenterY)
+{
+ double ax = arcMidX - arcStartX;
+ double ay = arcMidY - arcStartY;
+ double aAngleInRadians = atan2(ay, ax);
+ double aMidX = (arcMidX + arcStartX)/2.0;
+ double aMidY = (arcMidY + arcStartY)/2.0;
+
+ double paAngleInRadians = aAngleInRadians + radians(90.0);
+ double pax = cos(paAngleInRadians);
+ double pay = sin(paAngleInRadians);
+ double aPerpX = aMidX + pax;
+ double aPerpY = aMidY + pay;
+
+ double bx = arcEndX - arcMidX;
+ double by = arcEndY - arcMidY;
+ double bAngleInRadians = atan2(by, bx);
+ double bMidX = (arcEndX + arcMidX)/2.0;
+ double bMidY = (arcEndY + arcMidY)/2.0;
+
+ double pbAngleInRadians = bAngleInRadians + radians(90.0);
+ double pbx = cos(pbAngleInRadians);
+ double pby = sin(pbAngleInRadians);
+ double bPerpX = bMidX + pbx;
+ double bPerpY = bMidY + pby;
+
+ getLineIntersection(aMidX, aMidY, aPerpX, aPerpY,
+ bMidX, bMidY, bPerpX, bPerpY,
+ arcCenterX, arcCenterY);
+}
+
+/* Calculates Arc Geometry from Bulge Data.
+ * Returns false if there was an error calculating the data. */
+char getArcDataFromBulge(double bulge,
+ double arcStartX, double arcStartY,
+ double arcEndX, double arcEndY,
+ /* returned data */
+ double* arcMidX, double* arcMidY,
+ double* arcCenterX, double* arcCenterY,
+ double* radius, double* diameter,
+ double* chord,
+ double* chordMidX, double* chordMidY,
+ double* sagitta, double* apothem,
+ double* incAngleInDegrees, char* clockwise)
+{
+ double incAngleInRadians;
+ double chordAngleInRadians;
+ double sagittaAngleInRadians;
+
+ double w, h, fx ,fy, dx, dy;
+
+ /* Confirm the direction of the Bulge */
+ if(bulge >= 0.0) { *clockwise = 0; }
+ else { *clockwise = 1; }
+
+ /* Calculate the Included Angle in Radians */
+ incAngleInRadians = atan(bulge)*4.0;
+
+ /* Calculate the Chord */
+ w = fabs(arcStartX-arcEndX);
+ h = fabs(arcStartY-arcEndY);
+ *chord = sqrt(w*w + h*h);
+
+ /* Calculate the Radius */
+ *radius = fabs(*chord / (2.0 * sin(incAngleInRadians / 2.0)));
+
+ /* Calculate the Diameter */
+ *diameter = fabs(*radius * 2.0);
+
+ /* Calculate the Sagitta */
+ *sagitta = fabs((*chord / 2.0) * bulge);
+
+ /* Calculate the Apothem */
+ *apothem = fabs(*radius - *sagitta);
+
+ /* Calculate the Chord MidPoint */
+ *chordMidX = (arcStartX + arcEndX) / 2.0;
+ *chordMidY = (arcStartY + arcEndY) / 2.0;
+
+ /* Calculate the Chord Angle (from arcStart to arcEnd) */
+ dx = arcEndX - arcStartX;
+ dy = arcEndY - arcStartY;
+ chordAngleInRadians = atan2(dy, dx);
+
+ /* Calculate the Sagitta Angle (from chordMid to arcMid) */
+ if(*clockwise) sagittaAngleInRadians = chordAngleInRadians + radians(90.0);
+ else sagittaAngleInRadians = chordAngleInRadians - radians(90.0);
+
+ /* Calculate the Arc MidPoint */
+ fx = *sagitta * cos(sagittaAngleInRadians);
+ fy = *sagitta * sin(sagittaAngleInRadians);
+ *arcMidX = *chordMidX + fx;
+ *arcMidY = *chordMidY + fy;
+
+ /* Calculate the Arc CenterPoint */
+ getArcCenter(arcStartX, arcStartY, *arcMidX, *arcMidY, arcEndX, arcEndY, arcCenterX, arcCenterY);
+
+ /* Convert the Included Angle from Radians to Degrees */
+ *incAngleInDegrees = degrees(incAngleInRadians);
+
+ /* Confirm the direction of the Arc, it should match the Bulge */
+ if(*clockwise != isArcClockwise(arcStartX, arcStartY, *arcMidX, *arcMidY, arcEndX, arcEndY))
+ {
+ fprintf(stderr, "Arc and Bulge direction do not match.\n");
+ return 0;
+ }
+
+ return 1;
+}
+
+/* NOTE: Uncomment the #define below to compile test
+ * gcc -std=c89 -o geom-arc geom-arc.c geom-line.c -lm
+*/
+
+/* #define TEST_GEOM_ARC */
+
+#ifdef TEST_GEOM_ARC
+
+#include <stdio.h>
+
+void printArcResults(double bulge,
+ double startX, double startY,
+ double endX, double endY,
+ double midX, double midY,
+ double centerX, double centerY,
+ double radius, double diameter,
+ double chord,
+ double chordMidX, double chordMidY,
+ double sagitta, double apothem,
+ double incAngle, char clockwise)
+{
+ fprintf(stdout, "bulge = %f\n"
+ "startX = %f\n"
+ "startY = %f\n"
+ "endX = %f\n"
+ "endY = %f\n"
+ "midX = %f\n"
+ "midY = %f\n"
+ "centerX = %f\n"
+ "centerY = %f\n"
+ "radius = %f\n"
+ "diameter = %f\n"
+ "chord = %f\n"
+ "chordMidX = %f\n"
+ "chordMidY = %f\n"
+ "sagitta = %f\n"
+ "apothem = %f\n"
+ "incAngle = %f\n"
+ "clockwise = %d\n"
+ "\n",
+ bulge,
+ startX,
+ startY,
+ endX,
+ endY,
+ midX,
+ midY,
+ centerX,
+ centerY,
+ radius,
+ diameter,
+ chord,
+ chordMidX,
+ chordMidY,
+ sagitta,
+ apothem,
+ incAngle,
+ clockwise);
+}
+
+int main(void)
+{
+ double bulge;
+ double startX; double startY;
+ double endX; double endY;
+ /* returned data */
+ double midX; double midY;
+ double centerX; double centerY;
+ double radius; double diameter;
+ double chord;
+ double chordMidX; double chordMidY;
+ double sagitta; double apothem;
+ double incAngle; char clockwise;
+
+ fprintf(stdout, "Clockwise Test:\n");
+ bulge = -0.414213562373095;
+ startX = 1.0;
+ startY = 0.0;
+ endX = 2.0;
+ endY = 1.0;
+ if(getArcDataFromBulge(bulge,
+ startX, startY,
+ endX, endY,
+ /* returned data */
+ &midX, &midY,
+ &centerX, &centerY,
+ &radius, &diameter,
+ &chord,
+ &chordMidX, &chordMidY,
+ &sagitta, &apothem,
+ &incAngle, &clockwise))
+ {
+ printArcResults(bulge,
+ startX, startY,
+ endX, endY,
+ midX, midY,
+ centerX, centerY,
+ radius, diameter,
+ chord,
+ chordMidX, chordMidY,
+ sagitta, apothem,
+ incAngle, clockwise);
+ }
+
+ fprintf(stdout, "Counter-Clockwise Test:\n");
+ bulge = 2.414213562373095;
+ startX = 4.0;
+ startY = 0.0;
+ endX = 5.0;
+ endY = 1.0;
+ if(getArcDataFromBulge(bulge,
+ startX, startY,
+ endX, endY,
+ /* returned data */
+ &midX, &midY,
+ &centerX, &centerY,
+ &radius, &diameter,
+ &chord,
+ &chordMidX, &chordMidY,
+ &sagitta, &apothem,
+ &incAngle, &clockwise))
+ {
+ printArcResults(bulge,
+ startX, startY,
+ endX, endY,
+ midX, midY,
+ centerX, centerY,
+ radius, diameter,
+ chord,
+ chordMidX, chordMidY,
+ sagitta, apothem,
+ incAngle, clockwise);
+ }
+
+ return 0;
+}
+
+#endif
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/geom-arc.dxf b/Software/Visual_Studio/Embroidery/libembroidery/geom-arc.dxf
new file mode 100644
index 000000000..3bf3aad6d
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/geom-arc.dxf
@@ -0,0 +1,1834 @@
+ 0
+SECTION
+ 2
+HEADER
+ 9
+$ACADVER
+ 1
+AC1009
+ 9
+$DWGCODEPAGE
+ 3
+ansi_1252
+ 9
+$INSBASE
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 9
+$EXTMIN
+ 10
+0.0
+ 20
+-1.421349385152084
+ 30
+0.0
+ 9
+$EXTMAX
+ 10
+6.421349385152085
+ 20
+2.101909959072306
+ 30
+0.0
+ 9
+$LIMMIN
+ 10
+0.0
+ 20
+0.0
+ 9
+$LIMMAX
+ 10
+12.0
+ 20
+9.0
+ 9
+$ORTHOMODE
+ 70
+ 0
+ 9
+$REGENMODE
+ 70
+ 1
+ 9
+$FILLMODE
+ 70
+ 1
+ 9
+$QTEXTMODE
+ 70
+ 0
+ 9
+$MIRRTEXT
+ 70
+ 0
+ 9
+$DRAGMODE
+ 70
+ 2
+ 9
+$LTSCALE
+ 40
+1.0
+ 9
+$OSMODE
+ 70
+ 511
+ 9
+$ATTMODE
+ 70
+ 1
+ 9
+$TEXTSIZE
+ 40
+0.3391056447777574
+ 9
+$TRACEWID
+ 40
+0.05
+ 9
+$TEXTSTYLE
+ 7
+STANDARD
+ 9
+$CLAYER
+ 8
+0
+ 9
+$CELTYPE
+ 6
+BYLAYER
+ 9
+$CECOLOR
+ 62
+ 256
+ 9
+$DIMSCALE
+ 40
+1.0
+ 9
+$DIMASZ
+ 40
+0.18
+ 9
+$DIMEXO
+ 40
+0.0625
+ 9
+$DIMDLI
+ 40
+0.38
+ 9
+$DIMRND
+ 40
+0.0
+ 9
+$DIMDLE
+ 40
+0.0
+ 9
+$DIMEXE
+ 40
+0.18
+ 9
+$DIMTP
+ 40
+0.0
+ 9
+$DIMTM
+ 40
+0.0
+ 9
+$DIMTXT
+ 40
+0.18
+ 9
+$DIMCEN
+ 40
+0.09
+ 9
+$DIMTSZ
+ 40
+0.0
+ 9
+$DIMTOL
+ 70
+ 0
+ 9
+$DIMLIM
+ 70
+ 0
+ 9
+$DIMTIH
+ 70
+ 1
+ 9
+$DIMTOH
+ 70
+ 1
+ 9
+$DIMSE1
+ 70
+ 0
+ 9
+$DIMSE2
+ 70
+ 0
+ 9
+$DIMTAD
+ 70
+ 0
+ 9
+$DIMZIN
+ 70
+ 0
+ 9
+$DIMBLK
+ 1
+
+ 9
+$DIMASO
+ 70
+ 1
+ 9
+$DIMSHO
+ 70
+ 1
+ 9
+$DIMPOST
+ 1
+
+ 9
+$DIMAPOST
+ 1
+
+ 9
+$DIMALT
+ 70
+ 0
+ 9
+$DIMALTD
+ 70
+ 2
+ 9
+$DIMALTF
+ 40
+25.4
+ 9
+$DIMLFAC
+ 40
+1.0
+ 9
+$DIMTOFL
+ 70
+ 0
+ 9
+$DIMTVP
+ 40
+0.0
+ 9
+$DIMTIX
+ 70
+ 0
+ 9
+$DIMSOXD
+ 70
+ 0
+ 9
+$DIMSAH
+ 70
+ 0
+ 9
+$DIMBLK1
+ 1
+
+ 9
+$DIMBLK2
+ 1
+
+ 9
+$DIMSTYLE
+ 2
+STANDARD
+ 9
+$DIMCLRD
+ 70
+ 0
+ 9
+$DIMCLRE
+ 70
+ 0
+ 9
+$DIMCLRT
+ 70
+ 0
+ 9
+$DIMTFAC
+ 40
+1.0
+ 9
+$DIMGAP
+ 40
+0.09
+ 9
+$LUNITS
+ 70
+ 2
+ 9
+$LUPREC
+ 70
+ 6
+ 9
+$SKETCHINC
+ 40
+0.1
+ 9
+$FILLETRAD
+ 40
+0.0
+ 9
+$AUNITS
+ 70
+ 0
+ 9
+$AUPREC
+ 70
+ 0
+ 9
+$MENU
+ 1
+.
+ 9
+$ELEVATION
+ 40
+0.0
+ 9
+$PELEVATION
+ 40
+0.0
+ 9
+$THICKNESS
+ 40
+0.0
+ 9
+$LIMCHECK
+ 70
+ 0
+ 9
+$CHAMFERA
+ 40
+0.0
+ 9
+$CHAMFERB
+ 40
+0.0
+ 9
+$SKPOLY
+ 70
+ 0
+ 9
+$TDCREATE
+ 40
+2452643.063384259
+ 9
+$TDUPDATE
+ 40
+2456472.663020833
+ 9
+$TDINDWG
+ 40
+0.0
+ 9
+$TDUSRTIMER
+ 40
+2456472.653680556
+ 9
+$USRTIMER
+ 70
+ 1
+ 9
+$ANGBASE
+ 50
+0.0
+ 9
+$ANGDIR
+ 70
+ 0
+ 9
+$PDMODE
+ 70
+ 0
+ 9
+$PDSIZE
+ 40
+0.0
+ 9
+$PLINEWID
+ 40
+0.0
+ 9
+$COORDS
+ 70
+ 1
+ 9
+$SPLFRAME
+ 70
+ 0
+ 9
+$SPLINETYPE
+ 70
+ 6
+ 9
+$SPLINESEGS
+ 70
+ 8
+ 9
+$ATTDIA
+ 70
+ 0
+ 9
+$ATTREQ
+ 70
+ 1
+ 9
+$HANDLING
+ 70
+ 1
+ 9
+$HANDSEED
+ 5
+16F
+ 9
+$SURFTAB1
+ 70
+ 6
+ 9
+$SURFTAB2
+ 70
+ 6
+ 9
+$SURFTYPE
+ 70
+ 6
+ 9
+$SURFU
+ 70
+ 6
+ 9
+$SURFV
+ 70
+ 6
+ 9
+$UCSNAME
+ 2
+
+ 9
+$UCSORG
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 9
+$UCSXDIR
+ 10
+1.0
+ 20
+0.0
+ 30
+0.0
+ 9
+$UCSYDIR
+ 10
+0.0
+ 20
+1.0
+ 30
+0.0
+ 9
+$PUCSNAME
+ 2
+
+ 9
+$PUCSORG
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 9
+$PUCSXDIR
+ 10
+1.0
+ 20
+0.0
+ 30
+0.0
+ 9
+$PUCSYDIR
+ 10
+0.0
+ 20
+1.0
+ 30
+0.0
+ 9
+$USERI1
+ 70
+ 0
+ 9
+$USERI2
+ 70
+ 0
+ 9
+$USERI3
+ 70
+ 0
+ 9
+$USERI4
+ 70
+ 0
+ 9
+$USERI5
+ 70
+ 0
+ 9
+$USERR1
+ 40
+0.0
+ 9
+$USERR2
+ 40
+0.0
+ 9
+$USERR3
+ 40
+0.0
+ 9
+$USERR4
+ 40
+0.0
+ 9
+$USERR5
+ 40
+0.0
+ 9
+$WORLDVIEW
+ 70
+ 1
+ 9
+$SHADEDGE
+ 70
+ 3
+ 9
+$SHADEDIF
+ 70
+ 70
+ 9
+$TILEMODE
+ 70
+ 1
+ 9
+$MAXACTVP
+ 70
+ 64
+ 9
+$PLIMCHECK
+ 70
+ 0
+ 9
+$PEXTMIN
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 9
+$PEXTMAX
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 9
+$PLIMMIN
+ 10
+0.0
+ 20
+0.0
+ 9
+$PLIMMAX
+ 10
+0.0
+ 20
+0.0
+ 9
+$UNITMODE
+ 70
+ 0
+ 9
+$VISRETAIN
+ 70
+ 1
+ 9
+$PLINEGEN
+ 70
+ 0
+ 9
+$PSLTSCALE
+ 70
+ 1
+ 0
+ENDSEC
+ 0
+SECTION
+ 2
+TABLES
+ 0
+TABLE
+ 2
+VPORT
+ 70
+ 1
+ 0
+VPORT
+ 2
+*ACTIVE
+ 70
+ 0
+ 10
+0.0
+ 20
+0.0
+ 11
+1.0
+ 21
+1.0
+ 12
+30.88026825855589
+ 22
+19.87898324482213
+ 13
+0.0
+ 23
+0.0
+ 14
+0.5
+ 24
+0.5
+ 15
+0.5
+ 25
+0.5
+ 16
+0.0
+ 26
+0.0
+ 36
+1.0
+ 17
+-27.66959356597985
+ 27
+-19.53870295786202
+ 37
+0.0
+ 40
+3.638247046372585
+ 41
+1.800256081946223
+ 42
+50.0
+ 43
+0.0
+ 44
+0.0
+ 50
+0.0
+ 51
+0.0
+ 71
+ 16
+ 72
+ 1000
+ 73
+ 1
+ 74
+ 3
+ 75
+ 0
+ 76
+ 0
+ 77
+ 0
+ 78
+ 0
+ 0
+ENDTAB
+ 0
+TABLE
+ 2
+LTYPE
+ 70
+ 1
+ 0
+LTYPE
+ 2
+CONTINUOUS
+ 70
+ 0
+ 3
+Solid line
+ 72
+ 65
+ 73
+ 0
+ 40
+0.0
+ 0
+ENDTAB
+ 0
+TABLE
+ 2
+LAYER
+ 70
+ 5
+ 0
+LAYER
+ 2
+0
+ 70
+ 0
+ 62
+ 7
+ 6
+CONTINUOUS
+ 0
+LAYER
+ 2
+CHORD
+ 70
+ 0
+ 62
+ 1
+ 6
+CONTINUOUS
+ 0
+LAYER
+ 2
+SAGITTA
+ 70
+ 0
+ 62
+ 5
+ 6
+CONTINUOUS
+ 0
+LAYER
+ 2
+APOTHEM
+ 70
+ 0
+ 62
+ 3
+ 6
+CONTINUOUS
+ 0
+LAYER
+ 2
+DEFPOINTS
+ 70
+ 0
+ 62
+ 7
+ 6
+CONTINUOUS
+ 0
+ENDTAB
+ 0
+TABLE
+ 2
+STYLE
+ 70
+ 1
+ 0
+STYLE
+ 2
+STANDARD
+ 70
+ 0
+ 40
+0.0
+ 41
+1.0
+ 50
+0.0
+ 71
+ 0
+ 42
+0.3391056447777574
+ 3
+arial.ttf
+ 4
+
+ 0
+ENDTAB
+ 0
+TABLE
+ 2
+VIEW
+ 70
+ 0
+ 0
+ENDTAB
+ 0
+TABLE
+ 2
+UCS
+ 70
+ 0
+ 0
+ENDTAB
+ 0
+TABLE
+ 2
+APPID
+ 70
+ 2
+ 0
+APPID
+ 2
+ACAD
+ 70
+ 0
+ 0
+APPID
+ 2
+ACAECLAYERSTANDARD
+ 70
+ 0
+ 0
+ENDTAB
+ 0
+TABLE
+ 2
+DIMSTYLE
+ 70
+ 1
+ 0
+DIMSTYLE
+ 2
+STANDARD
+ 70
+ 0
+ 3
+
+ 4
+
+ 5
+
+ 6
+
+ 7
+
+ 40
+1.0
+ 41
+0.18
+ 42
+0.0625
+ 43
+0.38
+ 44
+0.18
+ 45
+0.0
+ 46
+0.0
+ 47
+0.0
+ 48
+0.0
+140
+0.18
+141
+0.09
+142
+0.0
+143
+25.4
+144
+1.0
+145
+0.0
+146
+1.0
+147
+0.09
+ 71
+ 0
+ 72
+ 0
+ 73
+ 1
+ 74
+ 1
+ 75
+ 0
+ 76
+ 0
+ 77
+ 0
+ 78
+ 0
+170
+ 0
+171
+ 2
+172
+ 0
+173
+ 0
+174
+ 0
+175
+ 0
+176
+ 0
+177
+ 0
+178
+ 0
+ 0
+ENDTAB
+ 0
+ENDSEC
+ 0
+SECTION
+ 2
+BLOCKS
+ 0
+BLOCK
+ 8
+0
+ 2
+$MODEL_SPACE
+ 70
+ 0
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 3
+$MODEL_SPACE
+ 1
+
+ 0
+ENDBLK
+ 5
+21
+ 8
+0
+ 0
+BLOCK
+ 67
+ 1
+ 8
+0
+ 2
+$PAPER_SPACE
+ 70
+ 0
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 3
+$PAPER_SPACE
+ 1
+
+ 0
+ENDBLK
+ 5
+5B
+ 67
+ 1
+ 8
+0
+ 0
+BLOCK
+ 8
+0
+ 2
+*D1
+ 70
+ 1
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 3
+*D1
+ 1
+
+ 0
+LINE
+ 5
+138
+ 8
+0
+ 62
+ 0
+ 10
+3.9375
+ 20
+0.0
+ 30
+0.0
+ 11
+3.398650614847916
+ 21
+0.0
+ 31
+0.0
+ 0
+LINE
+ 5
+139
+ 8
+0
+ 62
+ 0
+ 10
+5.0
+ 20
+1.0625
+ 30
+0.0
+ 11
+5.0
+ 21
+1.601349385152084
+ 31
+0.0
+ 0
+ARC
+ 5
+13A
+ 8
+0
+ 62
+ 0
+ 10
+5.0
+ 20
+0.0000000000000001
+ 30
+0.0
+ 40
+1.421349385152084
+ 50
+187.2608076506428
+ 51
+303.2896395921853
+ 0
+ARC
+ 5
+13B
+ 8
+0
+ 62
+ 0
+ 10
+5.0
+ 20
+0.0000000000000001
+ 30
+0.0
+ 40
+1.421349385152084
+ 50
+324.6684503828189
+ 51
+82.73919234935721
+ 0
+SOLID
+ 5
+13C
+ 8
+0
+ 62
+ 0
+ 10
+3.619988032771524
+ 20
+-0.177739184985779
+ 30
+0.0
+ 11
+3.560108436672158
+ 21
+-0.1815383916104206
+ 31
+0.0
+ 12
+3.578650614847916
+ 22
+0.0
+ 32
+0.0
+ 13
+3.578650614847916
+ 23
+0.0
+ 33
+0.0
+ 0
+SOLID
+ 5
+13D
+ 8
+0
+ 62
+ 0
+ 10
+5.18153839161042
+ 20
+1.439891563327842
+ 30
+0.0
+ 11
+5.177739184985779
+ 21
+1.380011967228476
+ 31
+0.0
+ 12
+5.0
+ 22
+1.421349385152084
+ 32
+0.0
+ 13
+5.0
+ 23
+1.421349385152084
+ 33
+0.0
+ 0
+TEXT
+ 5
+13E
+ 8
+0
+ 6
+CONTINUOUS
+ 62
+ 0
+ 10
+5.747201313915113
+ 20
+-1.093572391677732
+ 30
+0.0
+ 40
+0.18
+ 1
+270°
+ 0
+POINT
+ 5
+13F
+ 8
+DEFPOINTS
+ 62
+ 0
+ 10
+5.0
+ 20
+0.0000000000000001
+ 30
+0.0
+ 0
+POINT
+ 5
+140
+ 8
+DEFPOINTS
+ 62
+ 0
+ 10
+4.0
+ 20
+0.0
+ 30
+0.0
+ 0
+POINT
+ 5
+141
+ 8
+DEFPOINTS
+ 62
+ 0
+ 10
+5.0
+ 20
+1.0
+ 30
+0.0
+ 0
+POINT
+ 5
+142
+ 8
+DEFPOINTS
+ 62
+ 0
+ 10
+5.0
+ 20
+-1.421349385152084
+ 30
+0.0
+ 0
+ENDBLK
+ 5
+144
+ 8
+0
+ 0
+BLOCK
+ 8
+0
+ 2
+*D2
+ 70
+ 1
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 3
+*D2
+ 1
+
+ 0
+LINE
+ 5
+149
+ 8
+0
+ 62
+ 0
+ 10
+2.0
+ 20
+1.0625
+ 30
+0.0
+ 11
+2.0
+ 21
+1.564382110351848
+ 31
+0.0
+ 0
+LINE
+ 5
+14A
+ 8
+0
+ 62
+ 0
+ 10
+0.9375
+ 20
+0.0000000000000001
+ 30
+0.0
+ 11
+0.4356178896481517
+ 21
+0.0000000000000002
+ 31
+0.0
+ 0
+ARC
+ 5
+14B
+ 8
+0
+ 62
+ 0
+ 10
+2.0
+ 20
+0.0
+ 30
+0.0
+ 40
+1.384382110351848
+ 50
+97.45496404091041
+ 51
+122.9288792763932
+ 0
+ARC
+ 5
+14C
+ 8
+0
+ 62
+ 0
+ 10
+2.0
+ 20
+0.0
+ 30
+0.0
+ 40
+1.384382110351848
+ 50
+144.909640359484
+ 51
+172.5450359590896
+ 0
+SOLID
+ 5
+14D
+ 8
+0
+ 62
+ 0
+ 10
+1.822331109502969
+ 20
+1.342743602338786
+ 30
+0.0
+ 11
+1.818430452336409
+ 21
+1.402616675365557
+ 31
+0.0
+ 12
+2.0
+ 22
+1.384382110351848
+ 32
+0.0
+ 13
+2.0
+ 23
+1.384382110351848
+ 33
+0.0
+ 0
+SOLID
+ 5
+14E
+ 8
+0
+ 62
+ 0
+ 10
+0.5973833246344435
+ 20
+0.1815695476635907
+ 30
+0.0
+ 11
+0.6572563976612138
+ 21
+0.1776688904970316
+ 31
+0.0
+ 12
+0.6156178896481517
+ 22
+0.0000000000000002
+ 32
+0.0
+ 13
+0.6156178896481517
+ 23
+0.0000000000000002
+ 33
+0.0
+ 0
+TEXT
+ 5
+14F
+ 8
+0
+ 6
+CONTINUOUS
+ 62
+ 0
+ 10
+0.831762507692172
+ 20
+0.8903793749817713
+ 30
+0.0
+ 40
+0.18
+ 1
+90°
+ 0
+POINT
+ 5
+150
+ 8
+DEFPOINTS
+ 62
+ 0
+ 10
+2.0
+ 20
+0.0
+ 30
+0.0
+ 0
+POINT
+ 5
+151
+ 8
+DEFPOINTS
+ 62
+ 0
+ 10
+2.0
+ 20
+1.0
+ 30
+0.0
+ 0
+POINT
+ 5
+152
+ 8
+DEFPOINTS
+ 62
+ 0
+ 10
+1.0
+ 20
+0.0000000000000001
+ 30
+0.0
+ 0
+POINT
+ 5
+153
+ 8
+DEFPOINTS
+ 62
+ 0
+ 10
+1.307808944824076
+ 20
+1.198910076109413
+ 30
+0.0
+ 0
+ENDBLK
+ 5
+155
+ 8
+0
+ 0
+ENDSEC
+ 0
+SECTION
+ 2
+ENTITIES
+ 0
+POLYLINE
+ 5
+E7
+ 8
+0
+ 66
+ 1
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 0
+VERTEX
+ 5
+165
+ 8
+0
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 0
+VERTEX
+ 5
+166
+ 8
+0
+ 10
+1.0
+ 20
+0.0
+ 30
+0.0
+ 42
+-0.414213562373095
+ 0
+VERTEX
+ 5
+167
+ 8
+0
+ 10
+2.0
+ 20
+1.0
+ 30
+0.0
+ 0
+VERTEX
+ 5
+168
+ 8
+0
+ 10
+2.0
+ 20
+2.0
+ 30
+0.0
+ 0
+SEQEND
+ 5
+16D
+ 8
+0
+ 0
+POLYLINE
+ 5
+F8
+ 8
+0
+ 66
+ 1
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 0
+VERTEX
+ 5
+169
+ 8
+0
+ 10
+3.0
+ 20
+0.0
+ 30
+0.0
+ 0
+VERTEX
+ 5
+16A
+ 8
+0
+ 10
+4.0
+ 20
+0.0
+ 30
+0.0
+ 42
+2.414213562373095
+ 0
+VERTEX
+ 5
+16B
+ 8
+0
+ 10
+5.0
+ 20
+1.0
+ 30
+0.0
+ 0
+VERTEX
+ 5
+16C
+ 8
+0
+ 10
+5.0
+ 20
+2.0
+ 30
+0.0
+ 0
+SEQEND
+ 5
+16E
+ 8
+0
+ 0
+TEXT
+ 5
+106
+ 8
+0
+ 10
+0.0
+ 20
+2.0
+ 30
+0.0
+ 40
+0.1
+ 1
+CLOCKWISE
+ 0
+TEXT
+ 5
+107
+ 8
+0
+ 10
+3.0
+ 20
+2.0
+ 30
+0.0
+ 40
+0.1
+ 1
+COUNTER-CLOCKWISE
+ 0
+LINE
+ 5
+11C
+ 8
+CHORD
+ 10
+1.0
+ 20
+0.0
+ 30
+0.0
+ 11
+2.0
+ 21
+1.0
+ 31
+0.0
+ 0
+LINE
+ 5
+123
+ 8
+CHORD
+ 10
+4.0
+ 20
+0.0000000000000002
+ 30
+0.0
+ 11
+5.0
+ 21
+1.0
+ 31
+0.0
+ 0
+LINE
+ 5
+131
+ 8
+APOTHEM
+ 10
+2.0
+ 20
+0.0
+ 30
+0.0
+ 11
+1.5
+ 21
+0.5
+ 31
+0.0
+ 0
+LINE
+ 5
+132
+ 8
+SAGITTA
+ 10
+1.5
+ 20
+0.5
+ 30
+0.0
+ 11
+1.292893218813453
+ 21
+0.7071067811865475
+ 31
+0.0
+ 0
+DIMENSION
+ 5
+134
+ 8
+0
+ 2
+*D1
+ 10
+5.0
+ 20
+-1.421349385152084
+ 30
+0.0
+ 11
+6.005045788676368
+ 21
+-1.005045788676368
+ 31
+0.0
+ 70
+ 37
+ 1
+<>
+ 3
+STANDARD
+ 13
+4.0
+ 23
+0.0
+ 33
+0.0
+ 14
+5.0
+ 24
+1.0
+ 34
+0.0
+ 15
+5.0
+ 25
+0.0000000000000001
+ 35
+0.0
+ 0
+DIMENSION
+ 5
+145
+ 8
+0
+ 2
+*D2
+ 10
+1.307808944824076
+ 20
+1.198910076109413
+ 30
+0.0
+ 11
+1.021094022016865
+ 21
+0.9789059779831355
+ 31
+0.0
+ 70
+ 37
+ 1
+<>
+ 3
+STANDARD
+ 13
+2.0
+ 23
+1.0
+ 33
+0.0
+ 14
+1.0
+ 24
+0.0000000000000001
+ 34
+0.0
+ 15
+2.0
+ 25
+0.0
+ 35
+0.0
+ 0
+LINE
+ 5
+156
+ 8
+APOTHEM
+ 10
+5.0
+ 20
+0.0000000000000001
+ 30
+0.0
+ 11
+4.5
+ 21
+0.5000000000000001
+ 31
+0.0
+ 0
+LINE
+ 5
+158
+ 8
+SAGITTA
+ 10
+4.5
+ 20
+0.5
+ 30
+0.0
+ 11
+5.707106781186547
+ 21
+-0.7071067811865477
+ 31
+0.0
+ 0
+ENDSEC
+ 0
+EOF
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/geom-arc.h b/Software/Visual_Studio/Embroidery/libembroidery/geom-arc.h
new file mode 100644
index 000000000..1a221110c
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/geom-arc.h
@@ -0,0 +1,35 @@
+/* Computational Geometry for Arcs */
+#ifndef LIB_C_GEOMETRY_ARC_H
+#define LIB_C_GEOMETRY_ARC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+char isArcClockwise(double startx, double starty,
+ double midx, double midy,
+ double endx, double endy);
+
+void getArcCenter(double arcStartX, double arcStartY,
+ double arcMidX, double arcMidY,
+ double arcEndX, double arcEndY,
+ /* returned data */
+ double *arcCenterX, double *arcCenterY);
+
+char getArcDataFromBulge(double bulge,
+ double arcStartX, double arcStartY,
+ double arcEndX, double arcEndY,
+ /* returned data */
+ double* arcMidX, double* arcMidY,
+ double* arcCenterX, double* arcCenterY,
+ double* radius, double* diameter,
+ double* chord,
+ double* chordMidX, double* chordMidY,
+ double* sagitta, double* apothem,
+ double* incAngleInDegrees, char* clockwise);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LIB_C_GEOMETRY_ARC_H */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/geom-circle.c b/Software/Visual_Studio/Embroidery/libembroidery/geom-circle.c
new file mode 100644
index 000000000..c6497dafc
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/geom-circle.c
@@ -0,0 +1,181 @@
+/* Computational Geometry for Circles */
+#include "geom-circle.h"
+#include <math.h>
+
+/****************************************************************
+ * Calculates the intersection points of two overlapping circles.
+ * Returns true if the circles intersect.
+ * Returns false if the circles do not intersect.
+ ****************************************************************/
+int getCircleCircleIntersections(/* Circle 0 Radius */
+ double r0,
+ /* Circle 0 Center */
+ double px0, double py0,
+ /* Circle 1 Radius */
+ double r1,
+ /* Circle 1 Center */
+ double px1, double py1,
+ /* Intersection Point */
+ double* px3, double* py3,
+ /* Intersection Point */
+ double* px4, double* py4)
+{
+ double a, h, px2, py2, mx, my;
+ double dx = px1-px0;
+ double dy = py1-py0;
+ double d = sqrt(dx*dx + dy*dy); /* Distance between centers */
+
+ /*Circles share centers. This results in division by zero,
+ infinite solutions or one circle being contained within the other. */
+ if(d == 0.0)
+ return 0;
+ /* Circles do not touch each other */
+ else if(d > (r0 + r1))
+ return 0;
+ /* One circle is contained within the other */
+ else if(d < (r0 - r1))
+ return 0;
+
+ /*
+ * Considering the two right triangles p0p2p3 and p1p2p3 we can write:
+ * a^2 + h^2 = r0^2 and b^2 + h^2 = r1^2
+ *
+ * BEGIN PROOF
+ *
+ * Remove h^2 from the equation by setting them equal to themselves:
+ * r0^2 - a^2 = r1^2 - b^2
+ * Substitute b with (d - a) since it is proven that d = a + b:
+ * r0^2 - a^2 = r1^2 - (d - a)^2
+ * Complete the square:
+ * r0^2 - a^2 = r1^2 - (d^2 -2da + a^2)
+ * Subtract r1^2 from both sides:
+ * r0^2 - r1^2 - a^2 = -(d^2 -2da + a^2)
+ * Invert the signs:
+ * r0^2 - r1^2 - a^2 = -d^2 + 2da - a^2
+ * Adding a^2 to each side cancels them out:
+ * r0^2 - r1^2 = -d^2 + 2da
+ * Add d^2 to both sides to shift it to the other side:
+ * r0^2 - r1^2 + d^2 = 2da
+ * Divide by 2d to finally solve for a:
+ * a = (r0^2 - r1^2 + d^2)/ (2d)
+ *
+ * END PROOF
+ */
+
+ a = ((r0*r0) - (r1*r1) + (d*d)) / (2.0 * d);
+ /* Solve for h by substituting a into a^2 + h^2 = r0^2 */
+ h = sqrt((r0*r0) - (a*a));
+
+ /*Find point p2 by adding the a offset in relation to line d to point p0 */
+ px2 = px0 + (dx * a/d);
+ py2 = py0 + (dy * a/d);
+
+ /* Tangent circles have only one intersection */
+ if(d == (r0 + r1))
+ {
+ *px3 = *py4 = px2;
+ *py3 = *py4 = py2;
+ return 1;
+ }
+
+ /* Get the perpendicular slope by multiplying by the negative reciprocal
+ * Then multiply by the h offset in relation to d to get the actual offsets */
+ mx = -(dy * h/d);
+ my = (dx * h/d);
+
+ /* Add the offsets to point p2 to obtain the intersection points */
+ *px3 = px2 + mx;
+ *py3 = py2 + my;
+ *px4 = px2 - mx;
+ *py4 = py2 - my;
+
+ return 1;
+}
+
+/****************************************************************
+ * Calculates the tangent points on circle from a given point.
+ * Returns true if the given point lies outside the circle.
+ * Returns false if the given point is inside the circle.
+ ****************************************************************/
+int getCircleTangentPoints(/* Circle Radius and Center */
+ double cr, double cx, double cy,
+ /* Point to determine tangency */
+ double px, double py,
+ /* Tangent Point 0 */
+ double* tx0, double* ty0,
+ /* Tangent Point 1 */
+ double* tx1, double* ty1)
+{
+ double pr;
+ double dx = px-cx;
+ double dy = py-cy;
+ double hyp = sqrt(dx*dx + dy*dy); /* Distance to center of circle */
+
+ /* Point is inside the circle */
+ if(hyp < cr)
+ return 0;
+ /* Point is lies on the circle, so there is only one tangent point */
+ else if(hyp == cr)
+ {
+ *tx0 = *tx1 = px;
+ *ty0 = *ty1 = py;
+ return 1;
+ }
+
+ /* Since the tangent lines are always perpendicular to the radius, so
+ * we can use the Pythagorean theorem to solve for the missing side */
+ pr = sqrt((hyp*hyp) - (cr*cr));
+
+ return getCircleCircleIntersections(cr,
+ cx, cy,
+ pr,
+ px, py,
+ tx0, ty0,
+ tx1, ty1);
+}
+
+/* NOTE: Uncomment the #define below to compile test
+ * gcc -std=c89 -o geom-circle geom-circle.c -lm
+*/
+
+/* #define TEST_GEOM_CIRCLE */
+
+#ifdef TEST_GEOM_CIRCLE
+
+#include <stdio.h>
+
+void testTangentPoints(double cr, double cx, double cy,
+ double px, double py)
+{
+ double tx0, ty0, tx1, ty1;
+
+ if(!getCircleTangentPoints(cr, cx, cy,
+ px, py,
+ &tx0, &ty0,
+ &tx1, &ty1))
+ printf("Error calculating tangent points.\n");
+ else
+ printf("Circle : cr=%f, cx=%f, cy=%f\n"
+ "Point : px=%f, py=%f\n"
+ "Tangent: tx0=%f, ty0=%f\n"
+ "Tangent: tx1=%f, ty1=%f\n\n",
+ cr, cx, cy,
+ px, py,
+ tx0, ty0,
+ tx1, ty1);
+}
+
+int main(void)
+{
+ testTangentPoints(3.0, 0.0, 0.0, 4.0, 0.0);
+ /* Solution: tx0 = 2.2500, ty0 = 1.9843 */
+ /* Solution: tx1 = 2.2500, ty1 = -1.9843 */
+
+ testTangentPoints(6.8221, 20.1762, 10.7170, 24.3411, 18.2980);
+ /* Solution: tx0 = 19.0911, ty0 = 17.4522 */
+ /* Solution: tx1 = 26.4428, ty1 = 13.4133 */
+
+ return 0;
+}
+
+#endif
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/geom-circle.dxf b/Software/Visual_Studio/Embroidery/libembroidery/geom-circle.dxf
new file mode 100644
index 000000000..232a0c8dd
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/geom-circle.dxf
@@ -0,0 +1,2460 @@
+ 0
+SECTION
+ 2
+HEADER
+ 9
+$ACADVER
+ 1
+AC1009
+ 9
+$INSBASE
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 9
+$EXTMIN
+ 10
+-3.1080321917636797
+ 20
+-3.7050118510566357
+ 30
+-0.0015258207003583
+ 9
+$EXTMAX
+ 10
+6.7933960249570546
+ 20
+3.0006502771233134
+ 30
+0.0000000349246037
+ 9
+$LIMMIN
+ 10
+0.0
+ 20
+0.0
+ 9
+$LIMMAX
+ 10
+12.0
+ 20
+9.0
+ 9
+$ORTHOMODE
+ 70
+ 0
+ 9
+$REGENMODE
+ 70
+ 1
+ 9
+$FILLMODE
+ 70
+ 1
+ 9
+$QTEXTMODE
+ 70
+ 0
+ 9
+$MIRRTEXT
+ 70
+ 1
+ 9
+$DRAGMODE
+ 70
+ 2
+ 9
+$LTSCALE
+ 40
+1.0
+ 9
+$OSMODE
+ 70
+ 447
+ 9
+$ATTMODE
+ 70
+ 1
+ 9
+$TEXTSIZE
+ 40
+0.2
+ 9
+$TRACEWID
+ 40
+0.05
+ 9
+$TEXTSTYLE
+ 7
+STANDARD
+ 9
+$CLAYER
+ 8
+0
+ 9
+$CELTYPE
+ 6
+BYLAYER
+ 9
+$CECOLOR
+ 62
+ 256
+ 9
+$DIMSCALE
+ 40
+1.0
+ 9
+$DIMASZ
+ 40
+0.18
+ 9
+$DIMEXO
+ 40
+0.0625
+ 9
+$DIMDLI
+ 40
+0.3800000000000001
+ 9
+$DIMRND
+ 40
+0.0
+ 9
+$DIMDLE
+ 40
+0.0
+ 9
+$DIMEXE
+ 40
+0.18
+ 9
+$DIMTP
+ 40
+0.0
+ 9
+$DIMTM
+ 40
+0.0
+ 9
+$DIMTXT
+ 40
+0.18
+ 9
+$DIMCEN
+ 40
+0.09
+ 9
+$DIMTSZ
+ 40
+0.0
+ 9
+$DIMTOL
+ 70
+ 0
+ 9
+$DIMLIM
+ 70
+ 0
+ 9
+$DIMTIH
+ 70
+ 1
+ 9
+$DIMTOH
+ 70
+ 1
+ 9
+$DIMSE1
+ 70
+ 0
+ 9
+$DIMSE2
+ 70
+ 0
+ 9
+$DIMTAD
+ 70
+ 0
+ 9
+$DIMZIN
+ 70
+ 0
+ 9
+$DIMBLK
+ 1
+
+ 9
+$DIMASO
+ 70
+ 1
+ 9
+$DIMSHO
+ 70
+ 1
+ 9
+$DIMPOST
+ 1
+
+ 9
+$DIMAPOST
+ 1
+
+ 9
+$DIMALT
+ 70
+ 0
+ 9
+$DIMALTD
+ 70
+ 2
+ 9
+$DIMALTF
+ 40
+25.3999999999999986
+ 9
+$DIMLFAC
+ 40
+1.0
+ 9
+$DIMTOFL
+ 70
+ 0
+ 9
+$DIMTVP
+ 40
+0.0
+ 9
+$DIMTIX
+ 70
+ 0
+ 9
+$DIMSOXD
+ 70
+ 0
+ 9
+$DIMSAH
+ 70
+ 0
+ 9
+$DIMBLK1
+ 1
+
+ 9
+$DIMBLK2
+ 1
+
+ 9
+$DIMSTYLE
+ 2
+STANDARD
+ 9
+$DIMCLRD
+ 70
+ 0
+ 9
+$DIMCLRE
+ 70
+ 0
+ 9
+$DIMCLRT
+ 70
+ 0
+ 9
+$DIMTFAC
+ 40
+1.0
+ 9
+$DIMGAP
+ 40
+0.09
+ 9
+$LUNITS
+ 70
+ 2
+ 9
+$LUPREC
+ 70
+ 4
+ 9
+$SKETCHINC
+ 40
+0.1
+ 9
+$FILLETRAD
+ 40
+0.5
+ 9
+$AUNITS
+ 70
+ 0
+ 9
+$AUPREC
+ 70
+ 0
+ 9
+$MENU
+ 1
+.
+ 9
+$ELEVATION
+ 40
+0.0
+ 9
+$PELEVATION
+ 40
+0.0
+ 9
+$THICKNESS
+ 40
+0.0
+ 9
+$LIMCHECK
+ 70
+ 0
+ 9
+$BLIPMODE
+ 70
+ 0
+ 9
+$CHAMFERA
+ 40
+0.5
+ 9
+$CHAMFERB
+ 40
+0.5
+ 9
+$SKPOLY
+ 70
+ 0
+ 9
+$TDCREATE
+ 40
+2456217.9688479858450592
+ 9
+$TDUPDATE
+ 40
+2456217.989564826246351
+ 9
+$TDINDWG
+ 40
+0.0207171528
+ 9
+$TDUSRTIMER
+ 40
+0.0207170833
+ 9
+$USRTIMER
+ 70
+ 1
+ 9
+$ANGBASE
+ 50
+0.0
+ 9
+$ANGDIR
+ 70
+ 0
+ 9
+$PDMODE
+ 70
+ 0
+ 9
+$PDSIZE
+ 40
+0.0
+ 9
+$PLINEWID
+ 40
+0.0
+ 9
+$COORDS
+ 70
+ 1
+ 9
+$SPLFRAME
+ 70
+ 0
+ 9
+$SPLINETYPE
+ 70
+ 6
+ 9
+$SPLINESEGS
+ 70
+ 8
+ 9
+$ATTDIA
+ 70
+ 1
+ 9
+$ATTREQ
+ 70
+ 1
+ 9
+$HANDLING
+ 70
+ 22529
+ 9
+$HANDSEED
+ 5
+2C3
+ 9
+$SURFTAB1
+ 70
+ 6
+ 9
+$SURFTAB2
+ 70
+ 6
+ 9
+$SURFTYPE
+ 70
+ 6
+ 9
+$SURFU
+ 70
+ 6
+ 9
+$SURFV
+ 70
+ 6
+ 9
+$UCSNAME
+ 2
+
+ 9
+$UCSORG
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 9
+$UCSXDIR
+ 10
+1.0
+ 20
+0.0
+ 30
+0.0
+ 9
+$UCSYDIR
+ 10
+0.0
+ 20
+1.0
+ 30
+0.0
+ 9
+$PUCSNAME
+ 2
+
+ 9
+$PUCSORG
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 9
+$PUCSXDIR
+ 10
+1.0
+ 20
+0.0
+ 30
+0.0
+ 9
+$PUCSYDIR
+ 10
+0.0
+ 20
+1.0
+ 30
+0.0
+ 9
+$USERI1
+ 70
+ 0
+ 9
+$USERI2
+ 70
+ 0
+ 9
+$USERI3
+ 70
+ 0
+ 9
+$USERI4
+ 70
+ 0
+ 9
+$USERI5
+ 70
+ 0
+ 9
+$USERR1
+ 40
+0.0
+ 9
+$USERR2
+ 40
+0.0
+ 9
+$USERR3
+ 40
+0.0
+ 9
+$USERR4
+ 40
+0.0
+ 9
+$USERR5
+ 40
+0.0
+ 9
+$WORLDVIEW
+ 70
+ 1
+ 9
+$SHADEDGE
+ 70
+ 3
+ 9
+$SHADEDIF
+ 70
+ 70
+ 9
+$TILEMODE
+ 70
+ 1
+ 9
+$MAXACTVP
+ 70
+ 64
+ 9
+$PLIMCHECK
+ 70
+ 0
+ 9
+$PEXTMIN
+ 10
+1.0000000000000000E+020
+ 20
+1.0000000000000000E+020
+ 30
+1.0000000000000000E+020
+ 9
+$PEXTMAX
+ 10
+-1.0000000000000000E+020
+ 20
+-1.0000000000000000E+020
+ 30
+-1.0000000000000000E+020
+ 9
+$PLIMMIN
+ 10
+0.0
+ 20
+0.0
+ 9
+$PLIMMAX
+ 10
+12.0
+ 20
+9.0
+ 9
+$UNITMODE
+ 70
+ 0
+ 9
+$VISRETAIN
+ 70
+ 1
+ 9
+$PLINEGEN
+ 70
+ 0
+ 9
+$PSLTSCALE
+ 70
+ 1
+ 0
+ENDSEC
+ 0
+SECTION
+ 2
+TABLES
+ 0
+TABLE
+ 2
+VPORT
+ 70
+ 31
+ 0
+VPORT
+ 2
+*ACTIVE
+ 70
+ 0
+ 10
+0.0
+ 20
+0.0
+ 11
+1.0
+ 21
+1.0
+ 12
+1.8426819165966852
+ 22
+-0.3521807869666614
+ 13
+0.0
+ 23
+0.0
+ 14
+0.5
+ 24
+0.5
+ 15
+0.5
+ 25
+0.5
+ 16
+0.0
+ 26
+0.0
+ 36
+1.0
+ 17
+0.0
+ 27
+0.0
+ 37
+0.0
+ 40
+6.7821525707067147
+ 41
+2.1295238095238087
+ 42
+50.0
+ 43
+0.0
+ 44
+0.0
+ 50
+0.0
+ 51
+0.0
+ 71
+ 0
+ 72
+ 100
+ 73
+ 1
+ 74
+ 3
+ 75
+ 0
+ 76
+ 0
+ 77
+ 0
+ 78
+ 0
+ 0
+ENDTAB
+ 0
+TABLE
+ 2
+LTYPE
+ 70
+ 1
+ 0
+LTYPE
+ 2
+CONTINUOUS
+ 70
+ 0
+ 3
+Solid line
+ 72
+ 65
+ 73
+ 0
+ 40
+0.0
+ 0
+ENDTAB
+ 0
+TABLE
+ 2
+LAYER
+ 70
+ 5
+ 0
+LAYER
+ 2
+0
+ 70
+ 0
+ 62
+ 7
+ 6
+CONTINUOUS
+ 0
+LAYER
+ 2
+A
+ 70
+ 0
+ 62
+ 1
+ 6
+CONTINUOUS
+ 0
+LAYER
+ 2
+B
+ 70
+ 0
+ 62
+ 3
+ 6
+CONTINUOUS
+ 0
+LAYER
+ 2
+H
+ 70
+ 0
+ 62
+ 5
+ 6
+CONTINUOUS
+ 0
+LAYER
+ 2
+DEFPOINTS
+ 70
+ 0
+ 62
+ 7
+ 6
+CONTINUOUS
+ 0
+ENDTAB
+ 0
+TABLE
+ 2
+STYLE
+ 70
+ 2
+ 0
+STYLE
+ 2
+STANDARD
+ 70
+ 0
+ 40
+0.0
+ 41
+1.0
+ 50
+0.0
+ 71
+ 0
+ 42
+0.2
+ 3
+txt
+ 4
+
+ 0
+STYLE
+ 2
+ROMANS
+ 70
+ 0
+ 40
+0.0
+ 41
+1.0
+ 50
+0.0
+ 71
+ 0
+ 42
+0.125
+ 3
+romans.shx
+ 4
+
+ 0
+ENDTAB
+ 0
+TABLE
+ 2
+VIEW
+ 70
+ 0
+ 0
+ENDTAB
+ 0
+TABLE
+ 2
+UCS
+ 70
+ 0
+ 0
+ENDTAB
+ 0
+TABLE
+ 2
+APPID
+ 70
+ 1
+ 0
+APPID
+ 2
+ACAD
+ 70
+ 0
+ 0
+ENDTAB
+ 0
+TABLE
+ 2
+DIMSTYLE
+ 70
+ 2
+ 0
+DIMSTYLE
+ 2
+STANDARD
+ 70
+ 0
+ 3
+
+ 4
+
+ 5
+
+ 6
+
+ 7
+
+ 40
+1.0
+ 41
+0.18
+ 42
+0.0625
+ 43
+0.3800000000000001
+ 44
+0.18
+ 45
+0.0
+ 46
+0.0
+ 47
+0.0
+ 48
+0.0
+140
+0.18
+141
+0.09
+142
+0.0
+143
+25.3999999999999986
+144
+1.0
+145
+0.0
+146
+1.0
+147
+0.09
+ 71
+ 0
+ 72
+ 0
+ 73
+ 1
+ 74
+ 1
+ 75
+ 0
+ 76
+ 0
+ 77
+ 0
+ 78
+ 0
+170
+ 0
+171
+ 2
+172
+ 0
+173
+ 0
+174
+ 0
+175
+ 0
+176
+ 0
+177
+ 0
+178
+ 0
+ 0
+DIMSTYLE
+ 2
+AEC_ARCH_I
+ 70
+ 0
+ 3
+
+ 4
+
+ 5
+
+ 6
+
+ 7
+
+ 40
+96.0
+ 41
+0.09375
+ 42
+0.125
+ 43
+0.3750000000000002
+ 44
+0.125
+ 45
+0.0
+ 46
+0.125
+ 47
+0.0
+ 48
+0.0
+140
+0.09375
+141
+0.09375
+142
+0.0
+143
+25.3999999999999986
+144
+1.0
+145
+0.0
+146
+0.7500000000000002
+147
+0.0625
+ 71
+ 0
+ 72
+ 0
+ 73
+ 0
+ 74
+ 0
+ 75
+ 0
+ 76
+ 0
+ 77
+ 1
+ 78
+ 3
+170
+ 0
+171
+ 2
+172
+ 1
+173
+ 1
+174
+ 0
+175
+ 0
+176
+ 0
+177
+ 0
+178
+ 0
+ 0
+ENDTAB
+ 0
+ENDSEC
+ 0
+SECTION
+ 2
+BLOCKS
+ 0
+BLOCK
+ 8
+0
+ 2
+$MODEL_SPACE
+ 70
+ 0
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 3
+$MODEL_SPACE
+ 1
+
+ 0
+ENDBLK
+ 5
+21
+ 8
+0
+ 0
+BLOCK
+ 67
+ 1
+ 8
+0
+ 2
+$PAPER_SPACE
+ 70
+ 0
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 3
+$PAPER_SPACE
+ 1
+
+ 0
+ENDBLK
+ 5
+1D
+ 67
+ 1
+ 8
+0
+ 0
+BLOCK
+ 8
+0
+ 2
+_ARCHTICK
+ 70
+ 0
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 3
+_ARCHTICK
+ 1
+
+ 0
+POLYLINE
+ 5
+2C
+ 8
+0
+ 6
+BYBLOCK
+ 62
+ 0
+ 66
+ 1
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 40
+0.15
+ 41
+0.15
+ 0
+VERTEX
+ 5
+29C
+ 8
+0
+ 6
+BYBLOCK
+ 62
+ 0
+ 10
+-0.5
+ 20
+-0.5
+ 30
+0.0
+ 0
+VERTEX
+ 5
+29D
+ 8
+0
+ 6
+BYBLOCK
+ 62
+ 0
+ 10
+0.5
+ 20
+0.5
+ 30
+0.0
+ 0
+SEQEND
+ 5
+29E
+ 8
+0
+ 6
+BYBLOCK
+ 62
+ 0
+ 0
+ENDBLK
+ 5
+2E
+ 8
+0
+ 0
+BLOCK
+ 8
+0
+ 2
+A$C5CEA06D8
+ 70
+ 0
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 3
+A$C5CEA06D8
+ 1
+
+ 0
+POLYLINE
+ 5
+B3
+ 8
+0
+ 66
+ 1
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 70
+ 1
+ 40
+0.0625
+ 41
+0.0625
+ 0
+VERTEX
+ 5
+2A2
+ 8
+0
+ 10
+-0.03125
+ 20
+0.0
+ 30
+0.0
+ 42
+1.0
+ 0
+VERTEX
+ 5
+2A3
+ 8
+0
+ 10
+0.03125
+ 20
+0.0
+ 30
+0.0
+ 42
+1.0
+ 0
+SEQEND
+ 5
+2A4
+ 8
+0
+ 0
+ENDBLK
+ 5
+B5
+ 8
+0
+ 0
+BLOCK
+ 8
+0
+ 2
+*D22
+ 70
+ 1
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 3
+*D22
+ 1
+
+ 0
+ARC
+ 5
+13B
+ 8
+0
+ 62
+ 0
+ 10
+2.2499999999999991
+ 20
+1.9843134832984419
+ 30
+0.0
+ 40
+0.8032982016330007
+ 50
+234.27525445338037
+ 51
+245.3288089869425335
+ 0
+ARC
+ 5
+13C
+ 8
+0
+ 62
+ 0
+ 10
+2.2499999999999991
+ 20
+1.9843134832984419
+ 30
+0.0
+ 40
+0.8032982016330007
+ 50
+286.9875792580969573
+ 51
+298.5439897651612569
+ 0
+SOLID
+ 5
+13D
+ 8
+0
+ 62
+ 0
+ 10
+1.7608255448506693
+ 20
+1.3099317018727898
+ 30
+0.0
+ 11
+1.8010958468646678
+ 21
+1.3544098175669299
+ 31
+0.0
+ 12
+1.6475263487752489
+ 22
+1.4529816657618571
+ 32
+0.0
+ 13
+1.6475263487752489
+ 23
+1.4529816657618571
+ 33
+0.0
+ 0
+SOLID
+ 5
+13E
+ 8
+0
+ 62
+ 0
+ 10
+2.6166453236711131
+ 20
+1.3032372956114477
+ 30
+0.0
+ 11
+2.6510400108407843
+ 21
+1.2540742455179028
+ 31
+0.0
+ 12
+2.781331817536584
+ 22
+1.3818398320736909
+ 32
+0.0
+ 13
+2.781331817536584
+ 23
+1.3818398320736909
+ 33
+0.0
+ 0
+TEXT
+ 5
+13F
+ 8
+0
+ 62
+ 0
+ 10
+2.0046951269730506
+ 20
+1.0925919477909098
+ 30
+0.0
+ 40
+0.18
+ 1
+90°
+ 0
+POINT
+ 5
+140
+ 8
+DEFPOINTS
+ 62
+ 0
+ 10
+1.9939084216968921
+ 20
+1.2229298058604268
+ 30
+0.0
+ 0
+POINT
+ 5
+141
+ 8
+DEFPOINTS
+ 62
+ 0
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 0
+POINT
+ 5
+142
+ 8
+DEFPOINTS
+ 62
+ 0
+ 10
+3.9999999999999987
+ 20
+0.0
+ 30
+0.0
+ 0
+POINT
+ 5
+143
+ 8
+DEFPOINTS
+ 62
+ 0
+ 10
+2.2499999999999991
+ 20
+1.984313483298443
+ 30
+0.0
+ 0
+POINT
+ 5
+144
+ 8
+DEFPOINTS
+ 62
+ 0
+ 10
+2.25
+ 20
+1.9843134832984419
+ 30
+0.0
+ 0
+ENDBLK
+ 5
+139
+ 8
+0
+ 0
+BLOCK
+ 8
+0
+ 2
+*D23
+ 70
+ 1
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 3
+*D23
+ 1
+
+ 0
+ARC
+ 5
+17C
+ 8
+0
+ 62
+ 0
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 40
+1.690456274509142
+ 50
+6.1037477556722211
+ 51
+14.3043902923016013
+ 0
+ARC
+ 5
+17D
+ 8
+0
+ 62
+ 0
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 40
+1.690456274509142
+ 50
+27.3892703985352171
+ 51
+35.3058743535985968
+ 0
+SOLID
+ 5
+17E
+ 8
+0
+ 62
+ 0
+ 10
+1.710830515277308
+ 20
+0.1813419154887269
+ 30
+0.0
+ 11
+1.650915610752955
+ 21
+0.1781475116573898
+ 31
+0.0
+ 12
+1.690456274509142
+ 22
+-0.0000000000000007
+ 32
+0.0
+ 13
+1.690456274509142
+ 23
+-0.0000000000000007
+ 33
+0.0
+ 0
+SOLID
+ 5
+17F
+ 8
+0
+ 62
+ 0
+ 10
+1.3560202111973239
+ 20
+0.9583674016586144
+ 30
+0.0
+ 11
+1.4030692891217957
+ 21
+0.9956015830845156
+ 31
+0.0
+ 12
+1.267842205881857
+ 22
+1.118131726144981
+ 32
+0.0
+ 13
+1.267842205881857
+ 23
+1.118131726144981
+ 33
+0.0
+ 0
+TEXT
+ 5
+180
+ 8
+0
+ 62
+ 0
+ 10
+1.4012770516338731
+ 20
+0.507666547502381
+ 30
+0.0
+ 40
+0.18
+ 1
+41°
+ 0
+POINT
+ 5
+181
+ 8
+DEFPOINTS
+ 62
+ 0
+ 10
+1.6416374617929612
+ 20
+0.4033222781663469
+ 30
+0.0
+ 0
+POINT
+ 5
+182
+ 8
+DEFPOINTS
+ 62
+ 0
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 0
+POINT
+ 5
+183
+ 8
+DEFPOINTS
+ 62
+ 0
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 0
+POINT
+ 5
+184
+ 8
+DEFPOINTS
+ 62
+ 0
+ 10
+2.25
+ 20
+1.9843134832984419
+ 30
+0.0
+ 0
+POINT
+ 5
+185
+ 8
+DEFPOINTS
+ 62
+ 0
+ 10
+2.6249999999999991
+ 20
+0.0
+ 30
+0.0
+ 0
+ENDBLK
+ 5
+153
+ 8
+0
+ 0
+BLOCK
+ 8
+0
+ 2
+*D24
+ 70
+ 1
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 3
+*D24
+ 1
+
+ 0
+ARC
+ 5
+170
+ 8
+0
+ 62
+ 0
+ 10
+4.0
+ 20
+0.0
+ 30
+0.0
+ 40
+0.6894876543980887
+ 50
+116.4089847898932106
+ 51
+131.4096221092707708
+ 0
+LINE
+ 5
+171
+ 8
+0
+ 62
+ 0
+ 10
+3.6933326913728282
+ 20
+0.6175341183989312
+ 30
+0.0
+ 11
+3.8733326913728279
+ 21
+0.6175341183989309
+ 31
+0.0
+ 0
+ARC
+ 5
+172
+ 8
+0
+ 62
+ 0
+ 10
+4.0
+ 20
+-0.0000000000000002
+ 30
+0.0
+ 40
+0.6894876543980887
+ 50
+146.4102594286484873
+ 51
+164.9993626806223119
+ 0
+SOLID
+ 5
+173
+ 8
+0
+ 62
+ 0
+ 10
+3.4030324517603505
+ 20
+0.4011711372965472
+ 30
+0.0
+ 11
+3.4482530978606261
+ 21
+0.3617364676989259
+ 31
+0.0
+ 12
+3.5439467836033525
+ 22
+0.5171157407985658
+ 32
+0.0
+ 13
+3.5439467836033525
+ 23
+0.5171157407985658
+ 33
+0.0
+ 0
+SOLID
+ 5
+174
+ 8
+0
+ 62
+ 0
+ 10
+3.3637513767980374
+ 20
+0.1745439931859529
+ 30
+0.0
+ 11
+3.3042647286730724
+ 21
+0.1823758955638339
+ 31
+0.0
+ 12
+3.3105123456019112
+ 22
+-0.0000000000000002
+ 32
+0.0
+ 13
+3.3105123456019112
+ 23
+-0.0000000000000002
+ 33
+0.0
+ 0
+TEXT
+ 5
+175
+ 8
+0
+ 62
+ 0
+ 10
+3.9633326913728273
+ 20
+0.5275341183989295
+ 30
+0.0
+ 40
+0.18
+ 1
+49°
+ 0
+POINT
+ 5
+176
+ 8
+DEFPOINTS
+ 62
+ 0
+ 10
+3.3378785919633298
+ 20
+0.1923238586003217
+ 30
+0.0
+ 0
+POINT
+ 5
+177
+ 8
+DEFPOINTS
+ 62
+ 0
+ 10
+4.0
+ 20
+0.0
+ 30
+0.0
+ 0
+POINT
+ 5
+178
+ 8
+DEFPOINTS
+ 62
+ 0
+ 10
+2.6249999999999991
+ 20
+0.0
+ 30
+0.0
+ 0
+POINT
+ 5
+179
+ 8
+DEFPOINTS
+ 62
+ 0
+ 10
+4.0
+ 20
+0.0
+ 30
+0.0
+ 0
+POINT
+ 5
+17A
+ 8
+DEFPOINTS
+ 62
+ 0
+ 10
+2.25
+ 20
+1.984313483298443
+ 30
+0.0
+ 0
+ENDBLK
+ 5
+16E
+ 8
+0
+ 0
+ENDSEC
+ 0
+SECTION
+ 2
+ENTITIES
+ 0
+LINE
+ 5
+41
+ 8
+0
+ 10
+4.0
+ 20
+0.0
+ 30
+0.0
+ 11
+2.25
+ 21
+-1.984313483298443
+ 31
+0.0
+ 0
+LINE
+ 5
+42
+ 8
+0
+ 10
+4.0
+ 20
+0.0
+ 30
+0.0
+ 11
+2.25
+ 21
+1.984313483298443
+ 31
+0.0
+ 0
+CIRCLE
+ 5
+44
+ 8
+0
+ 10
+4.0
+ 20
+0.0
+ 30
+0.0
+ 40
+2.6457513110645903
+ 0
+CIRCLE
+ 5
+46
+ 8
+0
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 40
+3.0
+ 0
+TEXT
+ 5
+4F
+ 8
+A
+ 10
+1.0360771691798543
+ 20
+-0.2303887972606944
+ 30
+0.0
+ 40
+0.2
+ 1
+a
+ 0
+TEXT
+ 5
+56
+ 8
+B
+ 10
+3.2322403045144186
+ 20
+-0.2705788697011543
+ 30
+0.0
+ 40
+0.2
+ 1
+b
+ 0
+TEXT
+ 5
+5C
+ 8
+H
+ 10
+2.3455882267484887
+ 20
+0.6679689957108331
+ 30
+0.0
+ 40
+0.2
+ 1
+h
+ 0
+TEXT
+ 5
+64
+ 8
+0
+ 10
+-0.3284506570923043
+ 20
+-0.0739334606736257
+ 30
+0.0
+ 40
+0.2
+ 1
+c
+ 0
+TEXT
+ 5
+6D
+ 8
+0
+ 10
+4.1238525561894033
+ 20
+-0.0531618136025927
+ 30
+0.0
+ 40
+0.2
+ 1
+p
+ 0
+TEXT
+ 5
+79
+ 8
+0
+ 10
+2.1015714677740505
+ 20
+2.185072440363597
+ 30
+0.0
+ 40
+0.2
+ 1
+t0
+ 0
+TEXT
+ 5
+7F
+ 8
+0
+ 10
+2.1220818237398897
+ 20
+-2.433140442808948
+ 30
+0.0
+ 40
+0.2
+ 1
+t1
+ 0
+POLYLINE
+ 5
+BE
+ 8
+0
+ 66
+ 1
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 70
+ 1
+ 40
+0.03125
+ 41
+0.03125
+ 0
+VERTEX
+ 5
+2A5
+ 8
+0
+ 10
+-0.015625
+ 20
+0.0
+ 30
+0.0
+ 42
+1.0
+ 0
+VERTEX
+ 5
+2A6
+ 8
+0
+ 10
+0.015625
+ 20
+0.0
+ 30
+0.0
+ 42
+1.0
+ 0
+SEQEND
+ 5
+2A7
+ 8
+0
+ 0
+POLYLINE
+ 5
+CB
+ 8
+0
+ 66
+ 1
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 70
+ 1
+ 40
+0.03125
+ 41
+0.03125
+ 0
+VERTEX
+ 5
+2AE
+ 8
+0
+ 10
+3.984375
+ 20
+0.0
+ 30
+0.0
+ 42
+1.0
+ 0
+VERTEX
+ 5
+2AF
+ 8
+0
+ 10
+4.015625
+ 20
+0.0
+ 30
+0.0
+ 42
+1.0
+ 0
+SEQEND
+ 5
+2B0
+ 8
+0
+ 0
+POLYLINE
+ 5
+D7
+ 8
+0
+ 66
+ 1
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 70
+ 1
+ 40
+0.03125
+ 41
+0.03125
+ 0
+VERTEX
+ 5
+2B7
+ 8
+0
+ 10
+2.234375
+ 20
+1.9843134832984419
+ 30
+0.0
+ 42
+1.0
+ 0
+VERTEX
+ 5
+2B8
+ 8
+0
+ 10
+2.265625
+ 20
+1.9843134832984419
+ 30
+0.0
+ 42
+1.0
+ 0
+SEQEND
+ 5
+2B9
+ 8
+0
+ 0
+POLYLINE
+ 5
+E3
+ 8
+0
+ 66
+ 1
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 70
+ 1
+ 40
+0.03125
+ 41
+0.03125
+ 0
+VERTEX
+ 5
+2C0
+ 8
+0
+ 10
+2.234375
+ 20
+-1.9843134832984419
+ 30
+0.0
+ 42
+1.0
+ 0
+VERTEX
+ 5
+2C1
+ 8
+0
+ 10
+2.265625
+ 20
+-1.9843134832984419
+ 30
+0.0
+ 42
+1.0
+ 0
+SEQEND
+ 5
+2C2
+ 8
+0
+ 0
+TEXT
+ 5
+EA
+ 8
+0
+ 10
+-3.1070954717005743
+ 20
+-3.6382167408313038
+ 30
+0.0
+ 40
+0.2
+ 1
+point tangent to circle using circle circle intersection
+ 0
+LINE
+ 5
+126
+ 8
+0
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 11
+2.25
+ 21
+1.9843134832984419
+ 31
+0.0
+ 0
+LINE
+ 5
+129
+ 8
+0
+ 10
+2.2278594569415375
+ 20
+1.6314540263569053
+ 30
+0.0
+ 11
+2.4153594569415371
+ 21
+1.7968134832984421
+ 31
+0.0
+ 0
+LINE
+ 5
+12A
+ 8
+0
+ 10
+2.2278594569415375
+ 20
+1.6314540263569053
+ 30
+0.0
+ 11
+2.0625
+ 21
+1.8189540263569062
+ 31
+0.0
+ 0
+TEXT
+ 5
+18C
+ 8
+0
+ 10
+0.7987336233068805
+ 20
+1.093397199879564
+ 30
+0.0
+ 40
+0.2
+ 1
+cr
+ 0
+LINE
+ 5
+1FC
+ 8
+A
+ 10
+0.0
+ 20
+0.0
+ 30
+0.0
+ 11
+2.25
+ 21
+0.0
+ 31
+0.0
+ 0
+LINE
+ 5
+1FD
+ 8
+H
+ 10
+2.25
+ 20
+1.9843134832984419
+ 30
+0.0
+ 11
+2.25
+ 21
+0.0
+ 31
+0.0
+ 0
+LINE
+ 5
+1FE
+ 8
+B
+ 10
+2.25
+ 20
+0.0
+ 30
+0.0
+ 11
+4.0
+ 21
+0.0
+ 31
+0.0
+ 0
+LINE
+ 5
+1FF
+ 8
+0
+ 10
+2.25
+ 20
+0.0
+ 30
+0.0
+ 11
+2.25
+ 21
+-1.984313483298443
+ 31
+0.0
+ 0
+ENDSEC
+ 0
+EOF
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/geom-circle.h b/Software/Visual_Studio/Embroidery/libembroidery/geom-circle.h
new file mode 100644
index 000000000..fa90bdc80
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/geom-circle.h
@@ -0,0 +1,35 @@
+/* Computational Geometry for Circles */
+#ifndef LIB_C_GEOMETRY_CIRCLE_H
+#define LIB_C_GEOMETRY_CIRCLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int getCircleCircleIntersections(/* Circle 0 Radius */
+ double r0,
+ /* Circle 0 Center */
+ double px0, double py0,
+ /* Circle 1 Radius */
+ double r1,
+ /* Circle 1 Center */
+ double px1, double py1,
+ /* Intersection Point */
+ double* px3, double* py3,
+ /* Intersection Point */
+ double* px4, double* py4);
+
+int getCircleTangentPoints(/* Circle Radius and Center */
+ double cr, double cx, double cy,
+ /* Point to determine tangency */
+ double px, double py,
+ /* Tangent Point 0 */
+ double* tx0, double* ty0,
+ /* Tangent Point 1 */
+ double* tx1, double* ty1);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LIB_C_GEOMETRY_CIRCLE_H */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/geom-line.c b/Software/Visual_Studio/Embroidery/libembroidery/geom-line.c
new file mode 100644
index 000000000..79f0415b2
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/geom-line.c
@@ -0,0 +1,32 @@
+/* Computational Geometry for Lines */
+#include <stdio.h>
+
+/* Line Intersection
+ * intersectX and intersectY are set to the CenterPoint */
+void getLineIntersection(double lineAx1, double lineAy1,
+ double lineAx2, double lineAy2,
+ double lineBx1, double lineBy1,
+ double lineBx2, double lineBy2,
+ double* intersectX, double* intersectY)
+{
+ double A1 = lineAy2-lineAy1;
+ double B1 = lineAx1-lineAx2;
+ double C1 = A1*lineAx1+B1*lineAy1;
+
+ double A2 = lineBy2-lineBy1;
+ double B2 = lineBx1-lineBx2;
+ double C2 = A2*lineBx1+B2*lineBy1;
+
+ double det = A1*B2 - A2*B1;
+
+ if(det == 0)
+ {
+ printf("Intersecting lines cannot be parallel.\n");
+ return;
+ }
+ else
+ {
+ *intersectX = (B2*C1 - B1*C2)/det;
+ *intersectY = (A1*C2 - A2*C1)/det;
+ }
+}
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/geom-line.h b/Software/Visual_Studio/Embroidery/libembroidery/geom-line.h
new file mode 100644
index 000000000..d7e00ff71
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/geom-line.h
@@ -0,0 +1,19 @@
+/* Computational Geometry for Lines */
+#ifndef LIB_C_GEOMETRY_LINE_H
+#define LIB_C_GEOMETRY_LINE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void getLineIntersection(double lineAx1, double lineAy1,
+ double lineAx2, double lineAy2,
+ double lineBx1, double lineBy1,
+ double lineBx2, double lineBy2,
+ double *intersectX, double *intersectY);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* LIB_C_GEOMETRY_LINE_H */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/hashtable.c b/Software/Visual_Studio/Embroidery/libembroidery/hashtable.c
new file mode 100644
index 000000000..0da855286
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/hashtable.c
@@ -0,0 +1,706 @@
+/*--------------------------------------------------------------------------*\
+ * -----===== HashTable =====-----
+ *
+ * Author: Keith Pomakis (pomakis@pobox.com)
+ * Date: August, 1998
+ * Released to the public domain.
+ *
+ *--------------------------------------------------------------------------
+ * $Id: hashtable.c,v 1.5 2012/03/16 18:32:37 pomakis Exp pomakis $
+\*--------------------------------------------------------------------------*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "hashtable.h"
+
+static int pointercmp(const void *pointer1, const void *pointer2);
+static unsigned long pointerHashFunction(const void *pointer);
+static int isProbablePrime(long number);
+static long calculateIdealNumOfBuckets(HashTable *hashTable);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableCreate() - creates a new HashTable
+ * DESCRIPTION:
+ * Creates a new HashTable. When finished with this HashTable, it
+ * should be explicitly destroyed by calling the HashTableDestroy()
+ * function.
+ * EFFICIENCY:
+ * O(1)
+ * ARGUMENTS:
+ * numOfBuckets - the number of buckets to start the HashTable out with.
+ * Must be greater than zero, and should be prime.
+ * Ideally, the number of buckets should between 1/5
+ * and 1 times the expected number of elements in the
+ * HashTable. Values much more or less than this will
+ * result in wasted memory or decreased performance
+ * respectively. The number of buckets in a HashTable
+ * can be re-calculated to an appropriate number by
+ * calling the HashTableRehash() function once the
+ * HashTable has been populated. The number of buckets
+ * in a HashTable may also be re-calculated
+ * automatically if the ratio of elements to buckets
+ * passes the thresholds set by HashTableSetIdealRatio().
+ * RETURNS:
+ * HashTable - a new Hashtable, or NULL on error
+\*--------------------------------------------------------------------------*/
+
+HashTable *HashTableCreate(long numOfBuckets) {
+ HashTable *hashTable;
+ int i;
+
+ assert(numOfBuckets > 0);
+
+ hashTable = (HashTable *) malloc(sizeof(HashTable));
+ if (hashTable == NULL)
+ return NULL;
+
+ hashTable->bucketArray = (KeyValuePair **)
+ malloc(numOfBuckets * sizeof(KeyValuePair *));
+ if (hashTable->bucketArray == NULL) {
+ free(hashTable);
+ return NULL;
+ }
+
+ hashTable->numOfBuckets = numOfBuckets;
+ hashTable->numOfElements = 0;
+
+ for (i=0; i<numOfBuckets; i++)
+ hashTable->bucketArray[i] = NULL;
+
+ hashTable->idealRatio = 3.0;
+ hashTable->lowerRehashThreshold = 0.0;
+ hashTable->upperRehashThreshold = 15.0;
+
+ hashTable->keycmp = pointercmp;
+ hashTable->valuecmp = pointercmp;
+ hashTable->hashFunction = pointerHashFunction;
+ hashTable->keyDeallocator = NULL;
+ hashTable->valueDeallocator = NULL;
+
+ return hashTable;
+}
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableDestroy() - destroys an existing HashTable
+ * DESCRIPTION:
+ * Destroys an existing HashTable.
+ * EFFICIENCY:
+ * O(n)
+ * ARGUMENTS:
+ * hashTable - the HashTable to destroy
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void HashTableDestroy(HashTable *hashTable) {
+ int i;
+
+ for (i=0; i<hashTable->numOfBuckets; i++) {
+ KeyValuePair *pair = hashTable->bucketArray[i];
+ while (pair != NULL) {
+ KeyValuePair *nextPair = pair->next;
+ if (hashTable->keyDeallocator != NULL)
+ hashTable->keyDeallocator((void *) pair->key);
+ if (hashTable->valueDeallocator != NULL)
+ hashTable->valueDeallocator(pair->value);
+ free(pair);
+ pair = nextPair;
+ }
+ }
+
+ free(hashTable->bucketArray);
+ free(hashTable);
+}
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableContainsKey() - checks the existence of a key in a HashTable
+ * DESCRIPTION:
+ * Determines whether or not the specified HashTable contains the
+ * specified key. Uses the comparison function specified by
+ * HashTableSetKeyComparisonFunction().
+ * EFFICIENCY:
+ * O(1), assuming a good hash function and element-to-bucket ratio
+ * ARGUMENTS:
+ * hashTable - the HashTable to search
+ * key - the key to search for
+ * RETURNS:
+ * bool - whether or not the specified HashTable contains the
+ * specified key.
+\*--------------------------------------------------------------------------*/
+
+int HashTableContainsKey(const HashTable *hashTable, const void *key) {
+ return (HashTableGet(hashTable, key) != NULL);
+}
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableContainsValue()
+ * - checks the existence of a value in a HashTable
+ * DESCRIPTION:
+ * Determines whether or not the specified HashTable contains the
+ * specified value. Unlike HashTableContainsKey(), this function is
+ * not very efficient, since it has to scan linearly looking for a
+ * match. Uses the comparison function specified by
+ * HashTableSetValueComparisonFunction().
+ * EFFICIENCY:
+ * O(n)
+ * ARGUMENTS:
+ * hashTable - the HashTable to search
+ * value - the value to search for
+ * RETURNS:
+ * bool - whether or not the specified HashTable contains the
+ * specified value.
+\*--------------------------------------------------------------------------*/
+
+int HashTableContainsValue(const HashTable *hashTable, const void *value) {
+ int i;
+
+ for (i=0; i<hashTable->numOfBuckets; i++) {
+ KeyValuePair *pair = hashTable->bucketArray[i];
+ while (pair != NULL) {
+ if (hashTable->valuecmp(value, pair->value) == 0)
+ return 1;
+ pair = pair->next;
+ }
+ }
+
+ return 0;
+}
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTablePut() - adds a key/value pair to a HashTable
+ * DESCRIPTION:
+ * Adds the specified key/value pair to the specified HashTable. If
+ * the key already exists in the HashTable (determined by the comparison
+ * function specified by HashTableSetKeyComparisonFunction()), its value
+ * is replaced by the new value. May trigger an auto-rehash (see
+ * HashTableSetIdealRatio()). It is illegal to specify NULL as the
+ * key or value.
+ * EFFICIENCY:
+ * O(1), assuming a good hash function and element-to-bucket ratio
+ * ARGUMENTS:
+ * hashTable - the HashTable to add to
+ * key - the key to add or whose value to replace
+ * value - the value associated with the key
+ * RETURNS:
+ * err - 0 if successful, -1 if an error was encountered
+\*--------------------------------------------------------------------------*/
+
+int HashTablePut(HashTable *hashTable, const void *key, void *value) {
+ long hashValue;
+ KeyValuePair *pair;
+
+ assert(key != NULL);
+ assert(value != NULL);
+
+ hashValue = hashTable->hashFunction(key) % hashTable->numOfBuckets;
+ pair = hashTable->bucketArray[hashValue];
+
+ while (pair != NULL && hashTable->keycmp(key, pair->key) != 0)
+ pair = pair->next;
+
+ if (pair) {
+ if (pair->key != key) {
+ if (hashTable->keyDeallocator != NULL)
+ hashTable->keyDeallocator((void *) pair->key);
+ pair->key = key;
+ }
+ if (pair->value != value) {
+ if (hashTable->valueDeallocator != NULL)
+ hashTable->valueDeallocator(pair->value);
+ pair->value = value;
+ }
+ }
+ else {
+ KeyValuePair *newPair = (KeyValuePair *) malloc(sizeof(KeyValuePair));
+ if (newPair == NULL) {
+ return -1;
+ }
+ else {
+ newPair->key = key;
+ newPair->value = value;
+ newPair->next = hashTable->bucketArray[hashValue];
+ hashTable->bucketArray[hashValue] = newPair;
+ hashTable->numOfElements++;
+
+ if (hashTable->upperRehashThreshold > hashTable->idealRatio) {
+ float elementToBucketRatio = (float) hashTable->numOfElements /
+ (float) hashTable->numOfBuckets;
+ if (elementToBucketRatio > hashTable->upperRehashThreshold)
+ HashTableRehash(hashTable, 0);
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableGet() - retrieves the value of a key in a HashTable
+ * DESCRIPTION:
+ * Retrieves the value of the specified key in the specified HashTable.
+ * Uses the comparison function specified by
+ * HashTableSetKeyComparisonFunction().
+ * EFFICIENCY:
+ * O(1), assuming a good hash function and element-to-bucket ratio
+ * ARGUMENTS:
+ * hashTable - the HashTable to search
+ * key - the key whose value is desired
+ * RETURNS:
+ * void * - the value of the specified key, or NULL if the key
+ * doesn't exist in the HashTable
+\*--------------------------------------------------------------------------*/
+
+void *HashTableGet(const HashTable *hashTable, const void *key) {
+ long hashValue = hashTable->hashFunction(key) % hashTable->numOfBuckets;
+ KeyValuePair *pair = hashTable->bucketArray[hashValue];
+
+ while (pair != NULL && hashTable->keycmp(key, pair->key) != 0)
+ pair = pair->next;
+
+ return (pair == NULL)? NULL : pair->value;
+}
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableRemove() - removes a key/value pair from a HashTable
+ * DESCRIPTION:
+ * Removes the key/value pair identified by the specified key from the
+ * specified HashTable if the key exists in the HashTable. May trigger
+ * an auto-rehash (see HashTableSetIdealRatio()).
+ * EFFICIENCY:
+ * O(1), assuming a good hash function and element-to-bucket ratio
+ * ARGUMENTS:
+ * hashTable - the HashTable to remove the key/value pair from
+ * key - the key specifying the key/value pair to be removed
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void HashTableRemove(HashTable *hashTable, const void *key) {
+ long hashValue = hashTable->hashFunction(key) % hashTable->numOfBuckets;
+ KeyValuePair *pair = hashTable->bucketArray[hashValue];
+ KeyValuePair *previousPair = NULL;
+
+ while (pair != NULL && hashTable->keycmp(key, pair->key) != 0) {
+ previousPair = pair;
+ pair = pair->next;
+ }
+
+ if (pair != NULL) {
+ if (hashTable->keyDeallocator != NULL)
+ hashTable->keyDeallocator((void *) pair->key);
+ if (hashTable->valueDeallocator != NULL)
+ hashTable->valueDeallocator(pair->value);
+ if (previousPair != NULL)
+ previousPair->next = pair->next;
+ else
+ hashTable->bucketArray[hashValue] = pair->next;
+ free(pair);
+ hashTable->numOfElements--;
+
+ if (hashTable->lowerRehashThreshold > 0.0) {
+ float elementToBucketRatio = (float) hashTable->numOfElements /
+ (float) hashTable->numOfBuckets;
+ if (elementToBucketRatio < hashTable->lowerRehashThreshold)
+ HashTableRehash(hashTable, 0);
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableRemoveAll() - removes all key/value pairs from a HashTable
+ * DESCRIPTION:
+ * Removes all key/value pairs from the specified HashTable. May trigger
+ * an auto-rehash (see HashTableSetIdealRatio()).
+ * EFFICIENCY:
+ * O(n)
+ * ARGUMENTS:
+ * hashTable - the HashTable to remove all key/value pairs from
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void HashTableRemoveAll(HashTable *hashTable) {
+ int i;
+
+ for (i=0; i<hashTable->numOfBuckets; i++) {
+ KeyValuePair *pair = hashTable->bucketArray[i];
+ while (pair != NULL) {
+ KeyValuePair *nextPair = pair->next;
+ if (hashTable->keyDeallocator != NULL)
+ hashTable->keyDeallocator((void *) pair->key);
+ if (hashTable->valueDeallocator != NULL)
+ hashTable->valueDeallocator(pair->value);
+ free(pair);
+ pair = nextPair;
+ }
+ hashTable->bucketArray[i] = NULL;
+ }
+
+ hashTable->numOfElements = 0;
+ HashTableRehash(hashTable, 5);
+}
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableIsEmpty() - determines if a HashTable is empty
+ * DESCRIPTION:
+ * Determines whether or not the specified HashTable contains any
+ * key/value pairs.
+ * EFFICIENCY:
+ * O(1)
+ * ARGUMENTS:
+ * hashTable - the HashTable to check
+ * RETURNS:
+ * bool - whether or not the specified HashTable contains any
+ * key/value pairs
+\*--------------------------------------------------------------------------*/
+
+int HashTableIsEmpty(const HashTable *hashTable) {
+ return (hashTable->numOfElements == 0);
+}
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableSize() - returns the number of elements in a HashTable
+ * DESCRIPTION:
+ * Returns the number of key/value pairs that are present in the
+ * specified HashTable.
+ * EFFICIENCY:
+ * O(1)
+ * ARGUMENTS:
+ * hashTable - the HashTable whose size is requested
+ * RETURNS:
+ * long - the number of key/value pairs that are present in
+ * the specified HashTable
+\*--------------------------------------------------------------------------*/
+
+long HashTableSize(const HashTable *hashTable) {
+ return hashTable->numOfElements;
+}
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableGetNumBuckets() - returns the number of buckets in a HashTable
+ * DESCRIPTION:
+ * Returns the number of buckets that are in the specified HashTable.
+ * This may change dynamically throughout the life of a HashTable if
+ * automatic or manual rehashing is performed.
+ * EFFICIENCY:
+ * O(1)
+ * ARGUMENTS:
+ * hashTable - the HashTable whose number of buckets is requested
+ * RETURNS:
+ * long - the number of buckets that are in the specified
+ * HashTable
+\*--------------------------------------------------------------------------*/
+
+long HashTableGetNumBuckets(const HashTable *hashTable) {
+ return hashTable->numOfBuckets;
+}
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableSetKeyComparisonFunction()
+ * - specifies the function used to compare keys in a HashTable
+ * DESCRIPTION:
+ * Specifies the function used to compare keys in the specified
+ * HashTable. The specified function should return zero if the two
+ * keys are considered equal, and non-zero otherwise. The default
+ * function is one that simply compares pointers.
+ * ARGUMENTS:
+ * hashTable - the HashTable whose key comparison function is being
+ * specified
+ * keycmp - a function which returns zero if the two arguments
+ * passed to it are considered "equal" keys and non-zero
+ * otherwise
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void HashTableSetKeyComparisonFunction(HashTable *hashTable,
+ int (*keycmp)(const void *key1, const void *key2)) {
+ assert(keycmp != NULL);
+ hashTable->keycmp = keycmp;
+}
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableSetValueComparisonFunction()
+ * - specifies the function used to compare values in a HashTable
+ * DESCRIPTION:
+ * Specifies the function used to compare values in the specified
+ * HashTable. The specified function should return zero if the two
+ * values are considered equal, and non-zero otherwise. The default
+ * function is one that simply compares pointers.
+ * ARGUMENTS:
+ * hashTable - the HashTable whose value comparison function is being
+ * specified
+ * valuecmp - a function which returns zero if the two arguments
+ * passed to it are considered "equal" values and non-zero
+ * otherwise
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void HashTableSetValueComparisonFunction(HashTable *hashTable,
+ int (*valuecmp)(const void *value1, const void *value2)) {
+ assert(valuecmp != NULL);
+ hashTable->valuecmp = valuecmp;
+}
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableSetHashFunction()
+ * - specifies the hash function used by a HashTable
+ * DESCRIPTION:
+ * Specifies the function used to determine the hash value for a key
+ * in the specified HashTable (before modulation). An ideal hash
+ * function is one which is easy to compute and approximates a
+ * "random" function. The default function is one that works
+ * relatively well for pointers. If the HashTable keys are to be
+ * strings (which is probably the case), then this default function
+ * will not suffice, in which case consider using the provided
+ * HashTableStringHashFunction() function.
+ * ARGUMENTS:
+ * hashTable - the HashTable whose hash function is being specified
+ * hashFunction - a function which returns an appropriate hash code
+ * for a given key
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void HashTableSetHashFunction(HashTable *hashTable,
+ unsigned long (*hashFunction)(const void *key))
+{
+ assert(hashFunction != NULL);
+ hashTable->hashFunction = hashFunction;
+}
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableRehash() - reorganizes a HashTable to be more efficient
+ * DESCRIPTION:
+ * Reorganizes a HashTable to be more efficient. If a number of
+ * buckets is specified, the HashTable is rehashed to that number of
+ * buckets. If 0 is specified, the HashTable is rehashed to a number
+ * of buckets which is automatically calculated to be a prime number
+ * that achieves (as closely as possible) the ideal element-to-bucket
+ * ratio specified by the HashTableSetIdealRatio() function.
+ * EFFICIENCY:
+ * O(n)
+ * ARGUMENTS:
+ * hashTable - the HashTable to be reorganized
+ * numOfBuckets - the number of buckets to rehash the HashTable to.
+ * Should be prime. Ideally, the number of buckets
+ * should be between 1/5 and 1 times the expected
+ * number of elements in the HashTable. Values much
+ * more or less than this will result in wasted memory
+ * or decreased performance respectively. If 0 is
+ * specified, an appropriate number of buckets is
+ * automatically calculated.
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void HashTableRehash(HashTable *hashTable, long numOfBuckets) {
+ KeyValuePair **newBucketArray;
+ int i;
+
+ assert(numOfBuckets >= 0);
+ if (numOfBuckets == 0)
+ numOfBuckets = calculateIdealNumOfBuckets(hashTable);
+
+ if (numOfBuckets == hashTable->numOfBuckets)
+ return; /* already the right size! */
+
+ newBucketArray = (KeyValuePair **)
+ malloc(numOfBuckets * sizeof(KeyValuePair *));
+ if (newBucketArray == NULL) {
+ /* Couldn't allocate memory for the new array. This isn't a fatal
+ * error; we just can't perform the rehash. */
+ return;
+ }
+
+ for (i=0; i<numOfBuckets; i++)
+ newBucketArray[i] = NULL;
+
+ for (i=0; i<hashTable->numOfBuckets; i++) {
+ KeyValuePair *pair = hashTable->bucketArray[i];
+ while (pair != NULL) {
+ KeyValuePair *nextPair = pair->next;
+ long hashValue = hashTable->hashFunction(pair->key) % numOfBuckets;
+ pair->next = newBucketArray[hashValue];
+ newBucketArray[hashValue] = pair;
+ pair = nextPair;
+ }
+ }
+
+ free(hashTable->bucketArray);
+ hashTable->bucketArray = newBucketArray;
+ hashTable->numOfBuckets = numOfBuckets;
+}
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableSetIdealRatio()
+ * - sets the ideal element-to-bucket ratio of a HashTable
+ * DESCRIPTION:
+ * Sets the ideal element-to-bucket ratio, as well as the lower and
+ * upper auto-rehash thresholds, of the specified HashTable. Note
+ * that this function doesn't actually perform a rehash.
+ *
+ * The default values for these properties are 3.0, 0.0 and 15.0
+ * respectively. This is likely fine for most situations, so there
+ * is probably no need to call this function.
+ * ARGUMENTS:
+ * hashTable - a HashTable
+ * idealRatio - the ideal element-to-bucket ratio. When a rehash
+ * occurs (either manually via a call to the
+ * HashTableRehash() function or automatically due the
+ * the triggering of one of the thresholds below), the
+ * number of buckets in the HashTable will be
+ * recalculated to be a prime number that achieves (as
+ * closely as possible) this ideal ratio. Must be a
+ * positive number.
+ * lowerRehashThreshold
+ * - the element-to-bucket ratio that is considered
+ * unacceptably low (i.e., too few elements per bucket).
+ * If the actual ratio falls below this number, a
+ * rehash will automatically be performed. Must be
+ * lower than the value of idealRatio. If no ratio
+ * is considered unacceptably low, a value of 0.0 can
+ * be specified.
+ * upperRehashThreshold
+ * - the element-to-bucket ratio that is considered
+ * unacceptably high (i.e., too many elements per bucket).
+ * If the actual ratio rises above this number, a
+ * rehash will automatically be performed. Must be
+ * higher than idealRatio. However, if no ratio
+ * is considered unacceptably high, a value of 0.0 can
+ * be specified.
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void HashTableSetIdealRatio(HashTable *hashTable, float idealRatio,
+ float lowerRehashThreshold, float upperRehashThreshold) {
+ assert(idealRatio > 0.0);
+ assert(lowerRehashThreshold < idealRatio);
+ assert(upperRehashThreshold == 0.0 || upperRehashThreshold > idealRatio);
+
+ hashTable->idealRatio = idealRatio;
+ hashTable->lowerRehashThreshold = lowerRehashThreshold;
+ hashTable->upperRehashThreshold = upperRehashThreshold;
+}
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableSetDeallocationFunctions()
+ * - sets the key and value deallocation functions of a HashTable
+ * DESCRIPTION:
+ * Sets the key and value deallocation functions of the specified
+ * HashTable. This determines what happens to a key or a value when it
+ * is removed from the HashTable. If the deallocation function is NULL
+ * (the default if this function is never called), its reference is
+ * simply dropped and it is up to the calling program to perform the
+ * proper memory management. If the deallocation function is non-NULL,
+ * it is called to free the memory used by the object. E.g., for simple
+ * objects, an appropriate deallocation function may be free().
+ *
+ * This affects the behaviour of the HashTableDestroy(), HashTablePut(),
+ * HashTableRemove() and HashTableRemoveAll() functions.
+ * ARGUMENTS:
+ * hashTable - a HashTable
+ * keyDeallocator
+ * - if non-NULL, the function to be called when a key is
+ * removed from the HashTable.
+ * valueDeallocator
+ * - if non-NULL, the function to be called when a value is
+ * removed from the HashTable.
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void HashTableSetDeallocationFunctions(HashTable *hashTable,
+ void (*keyDeallocator)(void *key),
+ void (*valueDeallocator)(void *value)) {
+ hashTable->keyDeallocator = keyDeallocator;
+ hashTable->valueDeallocator = valueDeallocator;
+}
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableStringHashFunction() - a good hash function for strings
+ * DESCRIPTION:
+ * A hash function that is appropriate for hashing strings. Note that
+ * this is not the default hash function. To make it the default hash
+ * function, call HashTableSetHashFunction(hashTable,
+ * HashTableStringHashFunction).
+ * ARGUMENTS:
+ * key - the key to be hashed
+ * RETURNS:
+ * unsigned long - the unmodulated hash value of the key
+\*--------------------------------------------------------------------------*/
+
+unsigned long HashTableStringHashFunction(const void *key) {
+ const unsigned char *str = (const unsigned char *) key;
+ unsigned long hash = 5381;
+ int c;
+
+ /* djb2 algorithm */
+ while ((c = *str++) != '\0')
+ {
+ hash = hash * 33 + c;
+ }
+ return hash;
+}
+
+static int pointercmp(const void *pointer1, const void *pointer2) {
+ return (pointer1 != pointer2);
+}
+
+static unsigned long pointerHashFunction(const void *pointer) {
+ return ((unsigned long) pointer) >> 4;
+}
+
+static int isProbablePrime(long oddNumber) {
+ long i;
+ for (i = 3; i < 51; i += 2)
+ {
+ if (oddNumber == i)
+ {
+ return 1;
+ }
+ else if (oddNumber%i == 0)
+ {
+ return 0;
+ }
+ }
+ return 1; /* maybe */
+}
+
+static long calculateIdealNumOfBuckets(HashTable *hashTable) {
+ long idealNumOfBuckets = (long)(hashTable->numOfElements / hashTable->idealRatio);
+ if (idealNumOfBuckets < 5)
+ {
+ idealNumOfBuckets = 5;
+ }
+ else
+ {
+ idealNumOfBuckets |= 0x01; /* make it an odd number */
+ }
+ while (!isProbablePrime(idealNumOfBuckets))
+ {
+ idealNumOfBuckets += 2;
+ }
+ return idealNumOfBuckets;
+}
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/hashtable.h b/Software/Visual_Studio/Embroidery/libembroidery/hashtable.h
new file mode 100644
index 000000000..b87bac0e3
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/hashtable.h
@@ -0,0 +1,437 @@
+/*--------------------------------------------------------------------------*\
+ * -----===== HashTable =====-----
+ *
+ * Author: Keith Pomakis (pomakis@pobox.com)
+ * Date: August, 1998
+ * Released to the public domain.
+ *
+ *--------------------------------------------------------------------------
+ * $Id: hashtable.h,v 1.2 2000/08/02 19:01:25 pomakis Exp pomakis $
+\*--------------------------------------------------------------------------*/
+
+#ifndef _HASHTABLE_H
+#define _HASHTABLE_H
+
+/* These structs should not be accessed directly from user code.
+ * All access should be via the public functions declared below. */
+
+typedef struct KeyValuePair_struct {
+ const void *key;
+ void *value;
+ struct KeyValuePair_struct *next;
+} KeyValuePair;
+
+typedef struct {
+ long numOfBuckets;
+ long numOfElements;
+ KeyValuePair **bucketArray;
+ float idealRatio, lowerRehashThreshold, upperRehashThreshold;
+ int (*keycmp)(const void *key1, const void *key2);
+ int (*valuecmp)(const void *value1, const void *value2);
+ unsigned long (*hashFunction)(const void *key);
+ void (*keyDeallocator)(void *key);
+ void (*valueDeallocator)(void *value);
+} HashTable;
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableCreate() - creates a new HashTable
+ * DESCRIPTION:
+ * Creates a new HashTable. When finished with this HashTable, it
+ * should be explicitly destroyed by calling the HashTableDestroy()
+ * function.
+ * EFFICIENCY:
+ * O(1)
+ * ARGUMENTS:
+ * numOfBuckets - the number of buckets to start the HashTable out with.
+ * Must be greater than zero, and should be prime.
+ * Ideally, the number of buckets should between 1/5
+ * and 1 times the expected number of elements in the
+ * HashTable. Values much more or less than this will
+ * result in wasted memory or decreased performance
+ * respectively. The number of buckets in a HashTable
+ * can be re-calculated to an appropriate number by
+ * calling the HashTableRehash() function once the
+ * HashTable has been populated. The number of buckets
+ * in a HashTable may also be re-calculated
+ * automatically if the ratio of elements to buckets
+ * passes the thresholds set by HashTableSetIdealRatio().
+ * RETURNS:
+ * HashTable - a new Hashtable, or NULL on error
+\*--------------------------------------------------------------------------*/
+
+HashTable *HashTableCreate(long numOfBuckets);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableDestroy() - destroys an existing HashTable
+ * DESCRIPTION:
+ * Destroys an existing HashTable.
+ * EFFICIENCY:
+ * O(n)
+ * ARGUMENTS:
+ * hashTable - the HashTable to destroy
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void HashTableDestroy(HashTable *hashTable);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableContainsKey() - checks the existence of a key in a HashTable
+ * DESCRIPTION:
+ * Determines whether or not the specified HashTable contains the
+ * specified key. Uses the comparison function specified by
+ * HashTableSetKeyComparisonFunction().
+ * EFFICIENCY:
+ * O(1), assuming a good hash function and element-to-bucket ratio
+ * ARGUMENTS:
+ * hashTable - the HashTable to search
+ * key - the key to search for
+ * RETURNS:
+ * bool - whether or not the specified HashTable contains the
+ * specified key.
+\*--------------------------------------------------------------------------*/
+
+int HashTableContainsKey(const HashTable *hashTable, const void *key);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableContainsValue()
+ * - checks the existence of a value in a HashTable
+ * DESCRIPTION:
+ * Determines whether or not the specified HashTable contains the
+ * specified value. Unlike HashTableContainsKey(), this function is
+ * not very efficient, since it has to scan linearly looking for a
+ * match. Uses the comparison function specified by
+ * HashTableSetValueComparisonFunction().
+ * EFFICIENCY:
+ * O(n)
+ * ARGUMENTS:
+ * hashTable - the HashTable to search
+ * value - the value to search for
+ * RETURNS:
+ * bool - whether or not the specified HashTable contains the
+ * specified value.
+\*--------------------------------------------------------------------------*/
+
+int HashTableContainsValue(const HashTable *hashTable, const void *value);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTablePut() - adds a key/value pair to a HashTable
+ * DESCRIPTION:
+ * Adds the specified key/value pair to the specified HashTable. If
+ * the key already exists in the HashTable (determined by the comparison
+ * function specified by HashTableSetKeyComparisonFunction()), its value
+ * is replaced by the new value. May trigger an auto-rehash (see
+ * HashTableSetIdealRatio()). It is illegal to specify NULL as the
+ * key or value.
+ * EFFICIENCY:
+ * O(1), assuming a good hash function and element-to-bucket ratio
+ * ARGUMENTS:
+ * hashTable - the HashTable to add to
+ * key - the key to add or whose value to replace
+ * value - the value associated with the key
+ * RETURNS:
+ * err - 0 if successful, -1 if an error was encountered
+\*--------------------------------------------------------------------------*/
+
+int HashTablePut(HashTable *hashTable, const void *key, void *value);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableGet() - retrieves the value of a key in a HashTable
+ * DESCRIPTION:
+ * Retrieves the value of the specified key in the specified HashTable.
+ * Uses the comparison function specified by
+ * HashTableSetKeyComparisonFunction().
+ * EFFICIENCY:
+ * O(1), assuming a good hash function and element-to-bucket ratio
+ * ARGUMENTS:
+ * hashTable - the HashTable to search
+ * key - the key whose value is desired
+ * RETURNS:
+ * void * - the value of the specified key, or NULL if the key
+ * doesn't exist in the HashTable
+\*--------------------------------------------------------------------------*/
+
+void *HashTableGet(const HashTable *hashTable, const void *key);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableRemove() - removes a key/value pair from a HashTable
+ * DESCRIPTION:
+ * Removes the key/value pair identified by the specified key from the
+ * specified HashTable if the key exists in the HashTable. May trigger
+ * an auto-rehash (see HashTableSetIdealRatio()).
+ * EFFICIENCY:
+ * O(1), assuming a good hash function and element-to-bucket ratio
+ * ARGUMENTS:
+ * hashTable - the HashTable to remove the key/value pair from
+ * key - the key specifying the key/value pair to be removed
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void HashTableRemove(HashTable *hashTable, const void *key);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableRemoveAll() - removes all key/value pairs from a HashTable
+ * DESCRIPTION:
+ * Removes all key/value pairs from the specified HashTable. May trigger
+ * an auto-rehash (see HashTableSetIdealRatio()).
+ * EFFICIENCY:
+ * O(n)
+ * ARGUMENTS:
+ * hashTable - the HashTable to remove all key/value pairs from
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void HashTableRemoveAll(HashTable *hashTable);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableIsEmpty() - determines if a HashTable is empty
+ * DESCRIPTION:
+ * Determines whether or not the specified HashTable contains any
+ * key/value pairs.
+ * EFFICIENCY:
+ * O(1)
+ * ARGUMENTS:
+ * hashTable - the HashTable to check
+ * RETURNS:
+ * bool - whether or not the specified HashTable contains any
+ * key/value pairs
+\*--------------------------------------------------------------------------*/
+
+int HashTableIsEmpty(const HashTable *hashTable);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableSize() - returns the number of elements in a HashTable
+ * DESCRIPTION:
+ * Returns the number of key/value pairs that are present in the
+ * specified HashTable.
+ * EFFICIENCY:
+ * O(1)
+ * ARGUMENTS:
+ * hashTable - the HashTable whose size is requested
+ * RETURNS:
+ * long - the number of key/value pairs that are present in
+ * the specified HashTable
+\*--------------------------------------------------------------------------*/
+
+long HashTableSize(const HashTable *hashTable);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableGetNumBuckets() - returns the number of buckets in a HashTable
+ * DESCRIPTION:
+ * Returns the number of buckets that are in the specified HashTable.
+ * This may change dynamically throughout the life of a HashTable if
+ * automatic or manual rehashing is performed.
+ * EFFICIENCY:
+ * O(1)
+ * ARGUMENTS:
+ * hashTable - the HashTable whose number of buckets is requested
+ * RETURNS:
+ * long - the number of buckets that are in the specified
+ * HashTable
+\*--------------------------------------------------------------------------*/
+
+long HashTableGetNumBuckets(const HashTable *hashTable);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableSetKeyComparisonFunction()
+ * - specifies the function used to compare keys in a HashTable
+ * DESCRIPTION:
+ * Specifies the function used to compare keys in the specified
+ * HashTable. The specified function should return zero if the two
+ * keys are considered equal, and non-zero otherwise. The default
+ * function is one that simply compares pointers.
+ * ARGUMENTS:
+ * hashTable - the HashTable whose key comparison function is being
+ * specified
+ * keycmp - a function which returns zero if the two arguments
+ * passed to it are considered "equal" keys and non-zero
+ * otherwise
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void HashTableSetKeyComparisonFunction(HashTable *hashTable,
+ int (*keycmp)(const void *key1, const void *key2));
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableSetValueComparisonFunction()
+ * - specifies the function used to compare values in a HashTable
+ * DESCRIPTION:
+ * Specifies the function used to compare values in the specified
+ * HashTable. The specified function should return zero if the two
+ * values are considered equal, and non-zero otherwise. The default
+ * function is one that simply compares pointers.
+ * ARGUMENTS:
+ * hashTable - the HashTable whose value comparison function is being
+ * specified
+ * valuecmp - a function which returns zero if the two arguments
+ * passed to it are considered "equal" values and non-zero
+ * otherwise
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void HashTableSetValueComparisonFunction(HashTable *hashTable,
+ int (*valuecmp)(const void *value1, const void *value2));
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableSetHashFunction()
+ * - specifies the hash function used by a HashTable
+ * DESCRIPTION:
+ * Specifies the function used to determine the hash value for a key
+ * in the specified HashTable (before modulation). An ideal hash
+ * function is one which is easy to compute and approximates a
+ * "random" function. The default function is one that works
+ * relatively well for pointers. If the HashTable keys are to be
+ * strings (which is probably the case), then this default function
+ * will not suffice, in which case consider using the provided
+ * HashTableStringHashFunction() function.
+ * ARGUMENTS:
+ * hashTable - the HashTable whose hash function is being specified
+ * hashFunction - a function which returns an appropriate hash code
+ * for a given key
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void HashTableSetHashFunction(HashTable *hashTable,
+ unsigned long (*hashFunction)(const void *key));
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableRehash() - reorganizes a HashTable to be more efficient
+ * DESCRIPTION:
+ * Reorganizes a HashTable to be more efficient. If a number of
+ * buckets is specified, the HashTable is rehashed to that number of
+ * buckets. If 0 is specified, the HashTable is rehashed to a number
+ * of buckets which is automatically calculated to be a prime number
+ * that achieves (as closely as possible) the ideal element-to-bucket
+ * ratio specified by the HashTableSetIdealRatio() function.
+ * EFFICIENCY:
+ * O(n)
+ * ARGUMENTS:
+ * hashTable - the HashTable to be reorganized
+ * numOfBuckets - the number of buckets to rehash the HashTable to.
+ * Should be prime. Ideally, the number of buckets
+ * should be between 1/5 and 1 times the expected
+ * number of elements in the HashTable. Values much
+ * more or less than this will result in wasted memory
+ * or decreased performance respectively. If 0 is
+ * specified, an appropriate number of buckets is
+ * automatically calculated.
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void HashTableRehash(HashTable *hashTable, long numOfBuckets);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableSetIdealRatio()
+ * - sets the ideal element-to-bucket ratio of a HashTable
+ * DESCRIPTION:
+ * Sets the ideal element-to-bucket ratio, as well as the lower and
+ * upper auto-rehash thresholds, of the specified HashTable. Note
+ * that this function doesn't actually perform a rehash.
+ *
+ * The default values for these properties are 3.0, 0.0 and 15.0
+ * respectively. This is likely fine for most situations, so there
+ * is probably no need to call this function.
+ * ARGUMENTS:
+ * hashTable - a HashTable
+ * idealRatio - the ideal element-to-bucket ratio. When a rehash
+ * occurs (either manually via a call to the
+ * HashTableRehash() function or automatically due the
+ * the triggering of one of the thresholds below), the
+ * number of buckets in the HashTable will be
+ * recalculated to be a prime number that achieves (as
+ * closely as possible) this ideal ratio. Must be a
+ * positive number.
+ * lowerRehashThreshold
+ * - the element-to-bucket ratio that is considered
+ * unacceptably low (i.e., too few elements per bucket).
+ * If the actual ratio falls below this number, a
+ * rehash will automatically be performed. Must be
+ * lower than the value of idealRatio. If no ratio
+ * is considered unacceptably low, a value of 0.0 can
+ * be specified.
+ * upperRehashThreshold
+ * - the element-to-bucket ratio that is considered
+ * unacceptably high (i.e., too many elements per bucket).
+ * If the actual ratio rises above this number, a
+ * rehash will automatically be performed. Must be
+ * higher than idealRatio. However, if no ratio
+ * is considered unacceptably high, a value of 0.0 can
+ * be specified.
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void HashTableSetIdealRatio(HashTable *hashTable, float idealRatio,
+ float lowerRehashThreshold,
+ float upperRehashThreshold);
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableSetDeallocationFunctions()
+ * - sets the key and value deallocation functions of a HashTable
+ * DESCRIPTION:
+ * Sets the key and value deallocation functions of the specified
+ * HashTable. This determines what happens to a key or a value when it
+ * is removed from the HashTable. If the deallocation function is NULL
+ * (the default if this function is never called), its reference is
+ * simply dropped and it is up to the calling program to perform the
+ * proper memory management. If the deallocation function is non-NULL,
+ * it is called to free the memory used by the object. E.g., for simple
+ * objects, an appropriate deallocation function may be free().
+ *
+ * This affects the behaviour of the HashTableDestroy(), HashTablePut(),
+ * HashTableRemove() and HashTableRemoveAll() functions.
+ * ARGUMENTS:
+ * hashTable - a HashTable
+ * keyDeallocator
+ * - if non-NULL, the function to be called when a key is
+ * removed from the HashTable.
+ * valueDeallocator
+ * - if non-NULL, the function to be called when a value is
+ * removed from the HashTable.
+ * RETURNS:
+ * <nothing>
+\*--------------------------------------------------------------------------*/
+
+void HashTableSetDeallocationFunctions(HashTable *hashTable,
+ void (*keyDeallocator)(void *key),
+ void (*valueDeallocator)(void *value));
+
+/*--------------------------------------------------------------------------*\
+ * NAME:
+ * HashTableStringHashFunction() - a good hash function for strings
+ * DESCRIPTION:
+ * A hash function that is appropriate for hashing strings. Note that
+ * this is not the default hash function. To make it the default hash
+ * function, call HashTableSetHashFunction(HashTableStringHashFunction).
+ * ARGUMENTS:
+ * key - the key to be hashed
+ * RETURNS:
+ * long - the unmodulated hash value of the key
+\*--------------------------------------------------------------------------*/
+
+unsigned long HashTableStringHashFunction(const void *key);
+
+#endif /* _HASHTABLE_H */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/helpers-binary.c b/Software/Visual_Studio/Embroidery/libembroidery/helpers-binary.c
new file mode 100644
index 000000000..a6fe49158
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/helpers-binary.c
@@ -0,0 +1,203 @@
+#include "helpers-binary.h"
+
+char binaryReadByte(EmbFile* file)
+{
+ return (char)embFile_getc(file);
+}
+
+int binaryReadBytes(EmbFile* file, unsigned char* destination, int count)
+{
+ return (int) embFile_read((char*) destination, 1, count, file);
+}
+
+short binaryReadInt16(EmbFile* file)
+{
+ int x = embFile_getc(file);
+ x = x | embFile_getc(file) << 8;
+ return (short)x;
+}
+
+int binaryReadInt32(EmbFile* file)
+{
+ int x = embFile_getc(file);
+ x = x | embFile_getc(file) << 8;
+ x = x | embFile_getc(file) << 16;
+ x = x | embFile_getc(file) << 24;
+ return x;
+}
+
+unsigned char binaryReadUInt8(EmbFile* file)
+{
+ return (unsigned char)embFile_getc(file);
+}
+
+unsigned short binaryReadUInt16(EmbFile* file)
+{
+ return (unsigned short)(embFile_getc(file) | embFile_getc(file) << 8);
+}
+
+unsigned int binaryReadUInt32(EmbFile* file)
+{
+ unsigned int x = embFile_getc(file);
+ x = x | embFile_getc(file) << 8;
+ x = x | embFile_getc(file) << 16;
+ x = x | embFile_getc(file) << 24;
+ return x;
+}
+
+/* Big endian version */
+short binaryReadInt16BE(EmbFile* file)
+{
+ short returnValue = (short)(embFile_getc(file) << 8);
+ returnValue |= embFile_getc(file);
+ return returnValue;
+}
+
+/* Big endian version */
+unsigned short binaryReadUInt16BE(EmbFile* file)
+{
+ unsigned short returnValue = (unsigned short)(embFile_getc(file) << 8);
+ returnValue |= embFile_getc(file);
+ return returnValue;
+}
+
+/* Big endian version */
+int binaryReadInt32BE(EmbFile* file)
+{
+ int returnValue = embFile_getc(file) << 24;
+ returnValue |= embFile_getc(file) << 16;
+ returnValue |= embFile_getc(file) << 8;
+ returnValue |= embFile_getc(file);
+ return (returnValue);
+}
+
+/* Big endian version */
+unsigned int binaryReadUInt32BE(EmbFile* file)
+{
+ unsigned int returnValue = embFile_getc(file) << 24;
+ returnValue |= embFile_getc(file) << 16;
+ returnValue |= embFile_getc(file) << 8;
+ returnValue |= embFile_getc(file);
+ return returnValue;
+}
+
+void binaryReadString(EmbFile* file, char* buffer, int maxLength)
+{
+ int i = 0;
+ while(i < maxLength)
+ {
+ buffer[i] = (char)embFile_getc(file);
+ if(buffer[i] == '\0') break;
+ i++;
+ }
+}
+
+void binaryReadUnicodeString(EmbFile* file, char *buffer, const int stringLength)
+{
+ int i = 0;
+ for(i = 0; i < stringLength * 2; i++)
+ {
+ char input = (char)embFile_getc(file);
+ if(input != 0)
+ {
+ buffer[i] = input;
+ }
+ }
+}
+
+float binaryReadFloat(EmbFile* file)
+{
+ union
+ {
+ float f32;
+ unsigned int u32;
+ } float_int_u;
+ float_int_u.u32 = embFile_getc(file);
+ float_int_u.u32 |= embFile_getc(file) << 8;
+ float_int_u.u32 |= embFile_getc(file) << 16;
+ float_int_u.u32 |= embFile_getc(file) << 24;
+ return float_int_u.f32;
+}
+
+void binaryWriteByte(EmbFile* file, unsigned char data)
+{
+ embFile_putc(data, file);
+}
+
+void binaryWriteBytes(EmbFile* file, const char* data, int size)
+{
+ embFile_write((char*)data, 1, size, file);
+}
+
+void binaryWriteShort(EmbFile* file, short data)
+{
+ embFile_putc(data & 0xFF, file);
+ embFile_putc((data >> 8) & 0xFF, file);
+}
+
+void binaryWriteShortBE(EmbFile* file, short data)
+{
+ embFile_putc((data >> 8) & 0xFF, file);
+ embFile_putc(data & 0xFF, file);
+}
+
+void binaryWriteUShort(EmbFile* file, unsigned short data)
+{
+ embFile_putc(data & 0xFF, file);
+ embFile_putc((data >> 8) & 0xFF, file);
+}
+
+void binaryWriteUShortBE(EmbFile* file, unsigned short data)
+{
+ embFile_putc((data >> 8) & 0xFF, file);
+ embFile_putc(data & 0xFF, file);
+}
+
+void binaryWriteInt(EmbFile* file, int data)
+{
+ embFile_putc(data & 0xFF, file);
+ embFile_putc((data >> 8) & 0xFF, file);
+ embFile_putc((data >> 16) & 0xFF, file);
+ embFile_putc((data >> 24) & 0xFF, file);
+}
+
+void binaryWriteIntBE(EmbFile* file, int data)
+{
+ embFile_putc((data >> 24) & 0xFF, file);
+ embFile_putc((data >> 16) & 0xFF, file);
+ embFile_putc((data >> 8) & 0xFF, file);
+ embFile_putc(data & 0xFF, file);
+}
+
+void binaryWriteUInt(EmbFile* file, unsigned int data)
+{
+ embFile_putc(data & 0xFF, file);
+ embFile_putc((data >> 8) & 0xFF, file);
+ embFile_putc((data >> 16) & 0xFF, file);
+ embFile_putc((data >> 24) & 0xFF, file);
+}
+
+void binaryWriteUIntBE(EmbFile* file, unsigned int data)
+{
+ embFile_putc((data >> 24) & 0xFF, file);
+ embFile_putc((data >> 16) & 0xFF, file);
+ embFile_putc((data >> 8) & 0xFF, file);
+ embFile_putc(data & 0xFF, file);
+}
+
+void binaryWriteFloat(EmbFile* file, float data)
+{
+ union
+ {
+ float f32;
+ unsigned int u32;
+ } float_int_u;
+ float_int_u.f32 = data;
+
+ embFile_putc(float_int_u.u32 & 0xFF, file);
+ embFile_putc((float_int_u.u32 >> 8) & 0xFF, file);
+ embFile_putc((float_int_u.u32 >> 16) & 0xFF, file);
+ embFile_putc((float_int_u.u32 >> 24) & 0xFF, file);
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/helpers-binary.h b/Software/Visual_Studio/Embroidery/libembroidery/helpers-binary.h
new file mode 100644
index 000000000..6631efa36
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/helpers-binary.h
@@ -0,0 +1,44 @@
+/*! @file helpers-binary.h */
+#ifndef HELPERS_BINARY_H
+#define HELPERS_BINARY_H
+
+#include "emb-file.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+char binaryReadByte(EmbFile* file);
+int binaryReadBytes(EmbFile* file, unsigned char* destination, int count);
+short binaryReadInt16(EmbFile* file);
+int binaryReadInt32(EmbFile* file);
+unsigned char binaryReadUInt8(EmbFile* file);
+unsigned short binaryReadUInt16(EmbFile* file);
+unsigned int binaryReadUInt32(EmbFile* file);
+short binaryReadInt16BE(EmbFile* file); /* Big endian version */
+unsigned short binaryReadUInt16BE(EmbFile* file); /* Big endian version */
+int binaryReadInt32BE(EmbFile* file); /* Big endian version */
+unsigned int binaryReadUInt32BE(EmbFile* file);
+float binaryReadFloat(EmbFile* file);
+void binaryReadString(EmbFile* file, char *buffer, int maxLength);
+void binaryReadUnicodeString(EmbFile* file, char *buffer, const int stringLength);
+
+void binaryWriteByte(EmbFile* file, unsigned char data);
+void binaryWriteBytes(EmbFile* file, const char* data, int size);
+void binaryWriteShort(EmbFile* file, short data);
+void binaryWriteShortBE(EmbFile* file, short data);
+void binaryWriteUShort(EmbFile* file, unsigned short data);
+void binaryWriteUShortBE(EmbFile* file, unsigned short data);
+void binaryWriteInt(EmbFile* file, int data);
+void binaryWriteIntBE(EmbFile* file, int data);
+void binaryWriteUInt(EmbFile* file, unsigned int data);
+void binaryWriteUIntBE(EmbFile* file, unsigned int data);
+void binaryWriteFloat(EmbFile* file, float data);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* HELPERS_BINARY_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/helpers-misc.c b/Software/Visual_Studio/Embroidery/libembroidery/helpers-misc.c
new file mode 100644
index 000000000..0e1e16616
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/helpers-misc.c
@@ -0,0 +1,131 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+#include "helpers-misc.h"
+#include "emb-logging.h"
+
+/*! Rounds a double (\a src) and returns it as an \c int. */
+int roundDouble(double src)
+{
+ if(src < 0.0)
+ return (int) ceil(src - 0.5);
+ return (int)floor(src+0.5);
+}
+
+/*! Returns \c true if string (\a str) begins with substring (\a pre), otherwise returns \c false. */
+char startsWith(const char* pre, const char* str)
+{
+ char result = 0;
+ size_t lenpre;
+ size_t lenstr;
+ if(!pre) { embLog_error("helpers-misc.c startsWith(), pre argument is null\n"); return 0; }
+ if(!str) { embLog_error("helpers-misc.c startsWith(), str argument is null\n"); return 0; }
+ lenpre = strlen(pre);
+ lenstr = strlen(str);
+ if(lenstr < lenpre)
+ return 0;
+ result = (char)strncmp(pre, str, lenpre);
+ if(result == 0)
+ return 1;
+ return 0;
+}
+
+/*! Removes all characters from the right end of the string (\a str) that match (\a junk), moving left until a mismatch occurs. */
+char* rTrim(char* const str, char junk)
+{
+ char* original = str + strlen(str);
+ while(*--original == junk);
+ *(original + 1) = '\0';
+ return str;
+}
+
+/*! Removes all characters from the left end of the string (\a str) that match (\a junk), moving right until a mismatch occurs. */
+char* lTrim(char* const str, char junk)
+{
+ char* original = str;
+ char* p = original;
+ int trimmed = 0;
+ do
+ {
+ if(*original != junk || trimmed)
+ {
+ trimmed = 1;
+ *p++ = *original;
+ }
+ }
+ while(*original++ != '\0');
+ return str;
+}
+
+/* TODO: trimming function should handle any character, not just whitespace */
+static char const WHITESPACE[] = " \t\n\r";
+
+/* TODO: description */
+static void get_trim_bounds(char const *s,
+ char const **firstWord,
+ char const **trailingSpace)
+{
+ char const* lastWord = 0;
+ *firstWord = lastWord = s + strspn(s, WHITESPACE);
+ do
+ {
+ *trailingSpace = lastWord + strcspn(lastWord, WHITESPACE);
+ lastWord = *trailingSpace + strspn(*trailingSpace, WHITESPACE);
+ }
+ while (*lastWord != '\0');
+}
+
+/* TODO: description */
+char* copy_trim(char const *s)
+{
+ char const *firstWord = 0, *trailingSpace = 0;
+ char* result = 0;
+ size_t newLength;
+
+ get_trim_bounds(s, &firstWord, &trailingSpace);
+ newLength = trailingSpace - firstWord;
+
+ result = (char*)malloc(newLength + 1);
+ memcpy(result, firstWord, newLength);
+ result[newLength] = '\0';
+ return result;
+}
+
+/* TODO: description */
+void inplace_trim(char* s)
+{
+ char const *firstWord = 0, *trailingSpace = 0;
+ size_t newLength;
+
+ get_trim_bounds(s, &firstWord, &trailingSpace);
+ newLength = trailingSpace - firstWord;
+
+ memmove(s, firstWord, newLength);
+ s[newLength] = '\0';
+}
+
+/*! Optimizes the number (\a num) for output to a text file and returns it as a string (\a str). */
+char* emb_optOut(double num, char* str)
+{
+ /* Convert the number to a string */
+ sprintf(str, "%.10f", num);
+ /* Remove trailing zeroes */
+ rTrim(str, '0');
+ /* Remove the decimal point if it happens to be an integer */
+ rTrim(str, '.');
+ return str;
+}
+
+/*! Duplicates the string (\a src) and returns it. It is created on the heap. The caller is responsible for freeing the allocated memory. */
+char* emb_strdup(const char* src)
+{
+ char* dest = 0;
+ if(!src) { embLog_error("helpers-misc.c emb_strdup(), src argument is null\n"); return 0; }
+ dest = (char*)malloc(strlen(src) + 1);
+ if(!dest) { embLog_error("helpers-misc.c emb_strdup(), cannot allocate memory\n"); }
+ else { strcpy(dest, src); }
+ return dest;
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/helpers-misc.h b/Software/Visual_Studio/Embroidery/libembroidery/helpers-misc.h
new file mode 100644
index 000000000..1ea44b070
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/helpers-misc.h
@@ -0,0 +1,37 @@
+/*! @file helpers-misc.h */
+#ifndef HELPERS_MISC_H
+#define HELPERS_MISC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PI 3.1415926535
+
+#ifndef MINMAX
+#define MINMAX
+ #ifndef max
+ #define max(a,b) (((a) > (b)) ? (a) : (b))
+ #endif
+ #ifndef min
+ #define min(a,b) (((a) < (b)) ? (a) : (b))
+ #endif
+#endif
+
+int roundDouble(double src);
+char startsWith(const char* pre, const char* str);
+
+char* rTrim(char* const str, char junk);
+char* lTrim(char* const str, char junk);
+char *copy_trim(char const *s);
+void inplace_trim(char *s);
+char* emb_optOut(double num, char* str);
+char* emb_strdup(const char* src);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* HELPERS_MISC_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/helpers-unused.h b/Software/Visual_Studio/Embroidery/libembroidery/helpers-unused.h
new file mode 100644
index 000000000..587acf6dc
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/helpers-unused.h
@@ -0,0 +1,13 @@
+/*! @file helpers-unused.h */
+#ifndef HELPERS_UNUSED_H
+#define HELPERS_UNUSED_H
+
+/*! \def emb_unused(expr)
+ * Supresses compiler warnings for unused variables.
+ * This should only be used on variables that truely are unused.
+ * <b>It should not be used in place of properly fixing compiler warnings.</b> */
+#define emb_unused(expr) do { (void)(expr); } while (0)
+
+#endif /* HELPERS_UNUSED_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/keywords.txt b/Software/Visual_Studio/Embroidery/libembroidery/keywords.txt
new file mode 100644
index 000000000..9f225af4b
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/keywords.txt
@@ -0,0 +1,445 @@
+#######################################
+# Syntax Coloring Map for libEmbroidery
+#######################################
+
+####################
+# emb-arc.h
+####################
+
+# Datatypes
+EmbArc KEYWORD1
+EmbArcObject KEYWORD1
+EmbArcObjectList KEYWORD1
+
+# Functions #TODO: review arc header
+embArcObject_make KEYWORD2
+embArcObject_create KEYWORD2
+
+embArcObjectList_add KEYWORD2
+embArcObjectList_count KEYWORD2
+embArcObjectList_empty KEYWORD2
+
+####################
+# emb-circle.h
+####################
+
+# Datatypes
+EmbCircle KEYWORD1
+EmbCircleObject KEYWORD1
+EmbCircleObjectList KEYWORD1
+
+embCircle_centerX KEYWORD2
+embCircle_centerY KEYWORD2
+embCircle_radius KEYWORD2
+
+embCircleObject_make KEYWORD2
+embCircleObject_create KEYWORD2
+
+embCircleObjectList_add KEYWORD2
+embCircleObjectList_count KEYWORD2
+embCircleObjectList_empty KEYWORD2
+
+####################
+# emb-color.h
+####################
+
+# Datatypes
+EmbColor KEYWORD1
+
+# Functions
+embColor_fromHexStr KEYWORD2
+
+####################
+# emb-ellipse.h
+####################
+
+# Datatypes
+EmbEllipse KEYWORD1
+EmbEllipseObject KEYWORD1
+EmbEllipseObjectList KEYWORD1
+
+# Functions #TODO: review ellipse header
+embEllipse_centerX KEYWORD2
+embEllipse_centerY KEYWORD2
+embEllipse_radiusX KEYWORD2
+embEllipse_radiusY KEYWORD2
+embEllipse_diameterX KEYWORD2
+embEllipse_diameterY KEYWORD2
+embEllipse_width KEYWORD2
+embEllipse_height KEYWORD2
+
+embEllipseObject_make KEYWORD2
+embEllipseObject_create KEYWORD2
+
+embEllipseObjectList_add KEYWORD2
+embEllipseObjectList_count KEYWORD2
+embEllipseObjectList_empty KEYWORD2
+
+####################
+# emb-format.h
+####################
+embFormatList_create KEYWORD2
+embFormatList_add KEYWORD2
+embFormatList_count KEYWORD2
+embFormatList_empty KEYWORD2
+embFormatList_free KEYWORD2
+embFormat_info KEYWORD2
+
+####################
+# emb-line.h
+####################
+
+# Datatypes
+EmbLine KEYWORD1
+EmbLineObject KEYWORD1
+EmbLineObjectList KEYWORD1
+
+# Functions #TODO: review line header
+embLine_x1 KEYWORD2
+embLine_y1 KEYWORD2
+embLine_x2 KEYWORD2
+embLine_y2 KEYWORD2
+
+embLineObject_make KEYWORD2
+embLineObject_create KEYWORD2
+
+embLineObjectList_add KEYWORD2
+embLineObjectList_count KEYWORD2
+embLineObjectList_empty KEYWORD2
+
+####################
+# emb-pattern.h
+####################
+
+# Datatypes
+EmbPattern KEYWORD1
+
+# Functions #TODO: review pattern header
+embPattern_create KEYWORD2
+embPattern_hideStitchesOverLength KEYWORD2
+embPattern_fixColorCount KEYWORD2
+embPattern_addThread KEYWORD2
+embPattern_addStitchAbs KEYWORD2
+embPattern_addStitchRel KEYWORD2
+embPattern_addArcAbs KEYWORD2
+embPattern_changeColor KEYWORD2
+embPattern_free KEYWORD2
+embPattern_read KEYWORD2
+embPattern_write KEYWORD2
+embPattern_scale KEYWORD2
+embPattern_calcBoundingBox KEYWORD2
+embPattern_flipVertical KEYWORD2
+embPattern_correctForMaxStitchLength KEYWORD2
+embPattern_center KEYWORD2
+embPattern_loadExternalColorFile KEYWORD2
+
+####################
+# emb-point.h
+####################
+
+# Datatypes
+EmbPoint KEYWORD1
+EmbPointList KEYWORD1
+EmbPointObject KEYWORD1
+EmbPointObjectList KEYWORD1
+
+# Functions #TODO: review point header
+embPoint_x KEYWORD2
+embPoint_y KEYWORD2
+embPoint_make KEYWORD2
+
+embPointList_create KEYWORD2
+embPointList_add KEYWORD2
+embPointList_free KEYWORD2
+
+embPointObject_make KEYWORD2
+embPointObject_create KEYWORD2
+
+embPointObjectList_add KEYWORD2
+embPointObjectList_count KEYWORD2
+embPointObjectList_empty KEYWORD2
+embPointObjectList_free KEYWORD2
+
+####################
+# emb-polygon.h
+####################
+
+# Datatypes
+EmbPolygonObject KEYWORD1
+EmbPolygonObjectList KEYWORD1
+
+# Functions #TODO: review polygon header
+embPolygonObjectList_count KEYWORD2
+embPolygonObjectList_empty KEYWORD2
+
+####################
+# emb-polyline.h
+####################
+
+# Constants #TODO: review polyline header
+LINETO LITERAL1
+MOVETO LITERAL1
+CUBICTOCONTROL1 LITERAL1
+CUBICTOCONTROL2 LITERAL1
+CUBICTOEND LITERAL1
+QUADTOCONTROL LITERAL1
+QUADTOEND LITERAL1
+
+# Datatypes
+EmbPolylineObject KEYWORD1
+EmbPolylineObjectList KEYWORD1
+
+# Functions #TODO: review polyline header
+embPolylineObjectList_create KEYWORD2
+embPolylineObjectList_add KEYWORD2
+embPolylineObjectList_count KEYWORD2
+embPolylineObjectList_empty KEYWORD2
+
+####################
+# emb-reader-writer.h
+####################
+
+# Datatypes
+EmbReaderWriter KEYWORD1
+
+# Functions
+embReaderWriter_getByFileName KEYWORD2
+
+####################
+# emb-rect.h
+####################
+
+# Datatypes
+EmbRect KEYWORD1
+EmbRectObject KEYWORD1
+EmbRectObjectList KEYWORD1
+
+# Functions #TODO: review rect header
+embRect_x KEYWORD2
+embRect_y KEYWORD2
+embRect_width KEYWORD2
+embRect_height KEYWORD2
+
+embRect_setX KEYWORD2
+embRect_setY KEYWORD2
+embRect_setWidth KEYWORD2
+embRect_setHeight KEYWORD2
+
+embRect_setCoords KEYWORD2
+embRect_setRect KEYWORD2
+
+embRectObject_make KEYWORD2
+embRectObject_create KEYWORD2
+
+embRectObjectList_add KEYWORD2
+embRectObjectList_count KEYWORD2
+embRectObjectList_empty KEYWORD2
+
+####################
+# emb-spline.h
+####################
+
+# Datatypes
+EmbBezier KEYWORD1
+EmbSplineObject KEYWORD1
+EmbSplineObjectList KEYWORD1
+
+# Functions #TODO: review spline header
+embSplineObjectList_count KEYWORD2
+embSplineObjectList_empty KEYWORD2
+
+####################
+# emb-stitch.h
+####################
+
+# Constants
+NORMAL LITERAL1
+JUMP LITERAL1
+TRIM LITERAL1
+STOP LITERAL1
+END LITERAL1
+
+# Datatypes
+EmbStitch KEYWORD1
+EmbStitchList KEYWORD1
+
+# Functions
+embStitchList_add KEYWORD2
+embStitchList_getAt KEYWORD2
+embStitchList_count KEYWORD2
+embStitchList_empty KEYWORD2
+
+####################
+# emb-thread.h
+####################
+
+# Datatypes
+EmbThread KEYWORD1
+EmbThreadList KEYWORD1
+
+# Functions
+embThread_findNearestColor KEYWORD2
+embThread_findNearestColorInArray KEYWORD2
+embThread_getRandom KEYWORD2
+embThreadList_add KEYWORD2
+embThreadList_count KEYWORD2
+embThreadList_empty KEYWORD2
+embThreadList_free KEYWORD2
+embThreadList_getAt KEYWORD2
+
+####################
+# emb-time.h
+####################
+
+# Datatypes
+EmbTime KEYWORD1
+
+# Functions
+embTime_initNow KEYWORD2
+
+####################
+# formats
+####################
+
+ read10o KEYWORD2
+write10o KEYWORD2
+ read100 KEYWORD2
+write100 KEYWORD2
+ readArt KEYWORD2
+writeArt KEYWORD2
+ readBmc KEYWORD2
+writeBmc KEYWORD2
+ readBro KEYWORD2
+writeBro KEYWORD2
+ readCnd KEYWORD2
+writeCnd KEYWORD2
+ readCol KEYWORD2
+writeCol KEYWORD2
+ readCsd KEYWORD2
+writeCsd KEYWORD2
+ readCsv KEYWORD2
+writeCsv KEYWORD2
+ readDat KEYWORD2
+writeDat KEYWORD2
+ readDem KEYWORD2
+writeDem KEYWORD2
+ readDsb KEYWORD2
+writeDsb KEYWORD2
+ readDst KEYWORD2
+writeDst KEYWORD2
+ readDsz KEYWORD2
+writeDsz KEYWORD2
+ readDxf KEYWORD2
+writeDxf KEYWORD2
+ readEdr KEYWORD2
+writeEdr KEYWORD2
+ readEmd KEYWORD2
+writeEmd KEYWORD2
+ readExp KEYWORD2
+writeExp KEYWORD2
+ readExy KEYWORD2
+writeExy KEYWORD2
+ readEys KEYWORD2
+writeEys KEYWORD2
+ readFxy KEYWORD2
+writeFxy KEYWORD2
+ readGnc KEYWORD2
+writeGnc KEYWORD2
+ readGt KEYWORD2
+ writeGt KEYWORD2
+ readHus KEYWORD2
+writeHus KEYWORD2
+ readInb KEYWORD2
+writeInb KEYWORD2
+ readJef KEYWORD2
+writeJef KEYWORD2
+ readKsm KEYWORD2
+writeKsm KEYWORD2
+ readPcd KEYWORD2
+writePcd KEYWORD2
+ readPcm KEYWORD2
+writePcm KEYWORD2
+ readPcq KEYWORD2
+writePcq KEYWORD2
+ readPcs KEYWORD2
+writePcs KEYWORD2
+ readPec KEYWORD2
+writePec KEYWORD2
+ readPel KEYWORD2
+writePel KEYWORD2
+ readPem KEYWORD2
+writePem KEYWORD2
+ readPes KEYWORD2
+writePes KEYWORD2
+ readPhb KEYWORD2
+writePhb KEYWORD2
+ readPhc KEYWORD2
+writePhc KEYWORD2
+ readRgb KEYWORD2
+writeRgb KEYWORD2
+ readSew KEYWORD2
+writeSew KEYWORD2
+ readShv KEYWORD2
+writeShv KEYWORD2
+ readSst KEYWORD2
+writeSst KEYWORD2
+ readStx KEYWORD2
+writeStx KEYWORD2
+ readSvg KEYWORD2
+writeSvg KEYWORD2
+ readT09 KEYWORD2
+writeT09 KEYWORD2
+ readTap KEYWORD2
+writeTap KEYWORD2
+ readThr KEYWORD2
+writeThr KEYWORD2
+ readTxt KEYWORD2
+writeTxt KEYWORD2
+ readU00 KEYWORD2
+writeU00 KEYWORD2
+ readU01 KEYWORD2
+writeU01 KEYWORD2
+ readVip KEYWORD2
+writeVip KEYWORD2
+ readVp3 KEYWORD2
+writeVp3 KEYWORD2
+ readXxx KEYWORD2
+writeXxx KEYWORD2
+ readZsk KEYWORD2
+writeZsk KEYWORD2
+
+####################
+# helpers-binary.h
+####################
+
+# Functions
+binaryReadByte KEYWORD2
+binaryReadBytes KEYWORD2
+binaryReadInt16 KEYWORD2
+binaryReadInt32 KEYWORD2
+binaryReadUInt8 KEYWORD2
+binaryReadUInt16 KEYWORD2
+binaryReadUInt32 KEYWORD2
+binaryReadInt16BE KEYWORD2
+binaryReadInt32BE KEYWORD2
+binaryReadFloat KEYWORD2
+binaryWriteByte KEYWORD2
+binaryWriteBytes KEYWORD2
+binaryWriteShort KEYWORD2
+binaryWriteUShort KEYWORD2
+binaryWriteInt KEYWORD2
+binaryWriteUInt KEYWORD2
+binaryWriteFloat KEYWORD2
+
+####################
+# helpers-misc.h
+####################
+
+# Constants
+PI LITERAL1
+
+# Functions
+roundDouble KEYWORD2
+rTrim KEYWORD2
+lTrim KEYWORD2
+
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/libembroidery-generate-todo b/Software/Visual_Studio/Embroidery/libembroidery/libembroidery-generate-todo
new file mode 100644
index 000000000..34117835e
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/libembroidery-generate-todo
@@ -0,0 +1,49 @@
+#!/bin/sh
+
+OUTPUTFILE="TODO"
+#include the line number in output
+#do not search temporary, object, and moc files
+GREPCMD="grep --line-number --recursive --exclude=*.*~ --exclude=*.o --exclude=moc*.cpp --exclude=*Makefile* --exclude=*TODO* --exclude=*generate-todo* --exclude=*_memleak*"
+DIRECTORY="./"
+TODOSTRING="TODO"
+BUGSTRING="BUG"
+HACKSTRING="HACK"
+WARNSTRING="WARNING"
+NOTESTRING="NOTE"
+
+rm -f ${OUTPUTFILE}
+echo "==================================================" >> ${OUTPUTFILE}
+echo "This list was generated on:" >> ${OUTPUTFILE}
+date >> ${OUTPUTFILE}
+echo "==================================================" >> ${OUTPUTFILE}
+echo "" >> ${OUTPUTFILE}
+
+echo "==================================================" >> ${OUTPUTFILE}
+echo "TODO" >> ${OUTPUTFILE}
+echo "==================================================" >> ${OUTPUTFILE}
+${GREPCMD} ${TODOSTRING} ${DIRECTORY} >> ${OUTPUTFILE}
+echo "" >> ${OUTPUTFILE}
+
+echo "==================================================" >> ${OUTPUTFILE}
+echo "BUG" >> ${OUTPUTFILE}
+echo "==================================================" >> ${OUTPUTFILE}
+${GREPCMD} ${BUGSTRING} ${DIRECTORY} >> ${OUTPUTFILE}
+echo "" >> ${OUTPUTFILE}
+
+echo "==================================================" >> ${OUTPUTFILE}
+echo "HACK" >> ${OUTPUTFILE}
+echo "==================================================" >> ${OUTPUTFILE}
+${GREPCMD} ${HACKSTRING} ${DIRECTORY} >> ${OUTPUTFILE}
+echo "" >> ${OUTPUTFILE}
+
+echo "==================================================" >> ${OUTPUTFILE}
+echo "WARNING" >> ${OUTPUTFILE}
+echo "==================================================" >> ${OUTPUTFILE}
+${GREPCMD} ${WARNSTRING} ${DIRECTORY} >> ${OUTPUTFILE}
+echo "" >> ${OUTPUTFILE}
+
+echo "==================================================" >> ${OUTPUTFILE}
+echo "NOTE" >> ${OUTPUTFILE}
+echo "==================================================" >> ${OUTPUTFILE}
+${GREPCMD} ${NOTESTRING} ${DIRECTORY} >> ${OUTPUTFILE}
+echo "" >> ${OUTPUTFILE} \ No newline at end of file
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/libembroidery-shared.pro b/Software/Visual_Studio/Embroidery/libembroidery/libembroidery-shared.pro
new file mode 100644
index 000000000..3fdbb8a48
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/libembroidery-shared.pro
@@ -0,0 +1,36 @@
+TEMPLATE = lib
+DESTDIR = lib
+CONFIG += shared warn_on
+CONFIG -= qt debug_and_release
+CONFIG += release
+CONFIG -= debug
+
+include( ../libembroidery/libembroidery.pri )
+
+TARGET = embroidery
+
+OBJECTS_DIR = .obj
+
+DEFINES += LIBEMBROIDERY_SHARED
+
+!msvc {
+ !macx { #TODO: better clang support
+ #QMAKE_LFLAGS += -static-libgcc #TODO: Only static link when targeting Windows and building with MinGW (natively or cross-compile)
+ }
+}
+
+win32 {
+ TARGET = lib$$qtLibraryTarget($$TARGET) #force name to be libembroidery.dll
+
+ #Find out if we are cross-compiling from a Linux machine
+ UNAME = $$system(uname -s)
+ contains( UNAME, [lL]inux ) {
+ QMAKE_POST_LINK = "mv -f lib/liblibembroidery.a lib/libembroidery.dll.a" # rename the stub, the Linux way
+ } else {
+ QMAKE_POST_LINK = "MOVE /Y lib\liblibembroidery.a lib\libembroidery.dll.a >nul 2>&1" # rename the stub, the Windows way
+ }
+} else {
+ VERSION = 1.9.0 #TODO: update this to 2.0.0 for proper release. Better yet, grep a file with the version number
+}
+
+QMAKE_DISTCLEAN += lib/*embroidery.dll* object_script.*
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/libembroidery-static.pro b/Software/Visual_Studio/Embroidery/libembroidery/libembroidery-static.pro
new file mode 100644
index 000000000..c73d38ba0
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/libembroidery-static.pro
@@ -0,0 +1,34 @@
+TEMPLATE = lib
+DESTDIR = lib
+CONFIG += static warn_on create_prl
+CONFIG -= qt debug_and_release
+CONFIG += release
+CONFIG -= debug
+
+include( ../libembroidery/libembroidery.pri )
+
+TARGET = embroidery
+
+OBJECTS_DIR = .obj
+
+DEFINES += LIBEMBROIDERY_STATIC
+
+!msvc {
+ !macx { #TODO: better clang support
+ #QMAKE_LFLAGS += -static-libgcc #TODO: Only static link when targeting Windows and building with MinGW (natively or cross-compile)
+ }
+}
+
+win32 {
+ #Find out if we are cross-compiling from a Linux machine
+ UNAME = $$system(uname -s)
+ contains( UNAME, [lL]inux ) {
+ QMAKE_POST_LINK = "mv -f lib/embroidery.prl lib/libembroidery.prl" # rename the prl file, the Linux way
+ } else {
+ QMAKE_POST_LINK = "MOVE /Y lib\embroidery.prl lib\libembroidery.prl >nul 2>&1" # rename the prl file, the Windows way
+ }
+} else {
+ VERSION = 1.9.0 #TODO: update this to 2.0.0 for proper release. Better yet, grep a file with the version number
+}
+
+QMAKE_DISTCLEAN += lib/*embroidery.prl lib/*embroidery.a object_script.*
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/libembroidery-undocumented.doxyfile b/Software/Visual_Studio/Embroidery/libembroidery/libembroidery-undocumented.doxyfile
new file mode 100644
index 000000000..b3948a358
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/libembroidery-undocumented.doxyfile
@@ -0,0 +1,1890 @@
+# Doxyfile 1.8.4
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed
+# in front of the TAG it is preceding .
+# All text after a hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or sequence of words) that should
+# identify the project. Note that if you do not use Doxywizard you need
+# to put quotes around the project name if it contains spaces.
+
+PROJECT_NAME = "libembroidery"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER =
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer
+# a quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF =
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is
+# included in the documentation. The maximum height of the logo should not
+# exceed 55 pixels and the maximum width should not exceed 200 pixels.
+# Doxygen will copy the logo to the output directory.
+
+PROJECT_LOGO =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY =
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian,
+# Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic,
+# Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip. Note that you specify absolute paths here, but also
+# relative paths, which will be relative from the directory where doxygen is
+# started.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful if your file system
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding
+# "class=itcl::class" will allow you to use the command class in the
+# itcl::class meaning.
+
+TCL_SUBST =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension,
+# and language is one of the parsers supported by doxygen: IDL, Java,
+# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C,
+# C++. For instance to make doxygen treat .inc files as Fortran files (default
+# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note
+# that for custom extensions you also need to set FILE_PATTERNS otherwise the
+# files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all
+# comments according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you
+# can mix doxygen, HTML, and XML commands with Markdown formatting.
+# Disable only in case of backward compatibilities issues.
+
+MARKDOWN_SUPPORT = YES
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by by putting a % sign in front of the word
+# or globally by setting AUTOLINK_SUPPORT to NO.
+
+AUTOLINK_SUPPORT = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also makes the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES (the
+# default) will make doxygen replace the get and set methods by a property in
+# the documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
+# unions are shown inside the group in which they are included (e.g. using
+# @ingroup) instead of on a separate page (for HTML and Man pages) or
+# section (for LaTeX and RTF).
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
+# unions with only public data fields or simple typedef fields will be shown
+# inline in the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO (the default), structs, classes, and unions are shown on a separate
+# page (for HTML and Man pages) or section (for LaTeX and RTF).
+
+INLINE_SIMPLE_STRUCTS = NO
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can
+# be an expensive process and often the same symbol appear multiple times in
+# the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too
+# small doxygen will become slower. If the cache is too large, memory is wasted.
+# The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid
+# range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536
+# symbols.
+
+LOOKUP_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
+
+EXTRACT_PACKAGE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespaces are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
+# will list include files with double quotes in the documentation
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
+# will sort the (brief and detailed) documentation of class members so that
+# constructors and destructors are listed first. If set to NO (the default)
+# the constructors will appear in the respective orders defined by
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
+# do proper type resolution of all parameters of a function it will reject a
+# match between the prototype and the implementation of a member function even
+# if there is only one candidate or it is obvious which candidate to choose
+# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
+# will still accept a match between prototype and implementation in such cases.
+
+STRICT_PROTO_MATCHING = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = NO
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = NO
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = NO
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if section-label ... \endif
+# and \cond section-label ... \endcond blocks.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or macro consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and macros in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page.
+# This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option.
+# You can optionally specify a file name after the option, if omitted
+# DoxygenLayout.xml will be used as the name of the layout file.
+
+LAYOUT_FILE =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files
+# containing the references data. This must be a list of .bib files. The
+# .bib extension is automatically appended if omitted. Using this command
+# requires the bibtex tool to be installed. See also
+# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
+# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
+# feature you need bibtex and perl available in the search path. Do not use
+# file names with spaces, bibtex cannot handle them.
+
+CITE_BIB_FILES =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# The WARN_NO_PARAMDOC option can be enabled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT =
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
+# *.f90 *.f *.for *.vhd *.vhdl
+
+FILE_PATTERNS =
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+# If FILTER_PATTERNS is specified, this tag will be ignored.
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.
+# Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.
+# The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty or if
+# non of the patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
+# and it is also possible to disable source filtering for a specific pattern
+# using *.ext= (so without naming a filter). This option only has effect when
+# FILTER_SOURCE_FILES is enabled.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE =
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C, C++ and Fortran comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.
+# Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = doxygen
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header. Note that when using a custom header you are responsible
+# for the proper inclusion of any scripts and style sheets that doxygen
+# needs, which is dependent on the configuration options used.
+# It is advised to generate a default header using "doxygen -w html
+# header.html footer.html stylesheet.css YourConfigFile" and then modify
+# that header. Note that the header is subject to change so you typically
+# have to redo this when upgrading to a newer version of doxygen or when
+# changing the value of configuration settings such as GENERATE_TREEVIEW!
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If left blank doxygen will
+# generate a default style sheet. Note that it is recommended to use
+# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this
+# tag will in the future become obsolete.
+
+HTML_STYLESHEET =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional
+# user-defined cascading style sheet that is included after the standard
+# style sheets created by doxygen. Using this option one can overrule
+# certain style aspects. This is preferred over using HTML_STYLESHEET
+# since it does not replace the standard style sheet and is therefor more
+# robust against future updates. Doxygen will copy the style sheet file to
+# the output directory.
+
+HTML_EXTRA_STYLESHEET =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that
+# the files will be copied as-is; there are no commands or markers available.
+
+HTML_EXTRA_FILES =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
+# Doxygen will adjust the colors in the style sheet and background images
+# according to this color. Hue is specified as an angle on a colorwheel,
+# see http://en.wikipedia.org/wiki/Hue for more information.
+# For instance the value 0 represents red, 60 is yellow, 120 is green,
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
+# The allowed range is 0 to 359.
+
+HTML_COLORSTYLE_HUE = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
+# the colors in the HTML output. For a value of 0 the output will use
+# grayscales only. A value of 255 will produce the most vivid colors.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
+# the luminance component of the colors in the HTML output. Values below
+# 100 gradually make the output lighter, whereas values above 100 make
+# the output darker. The value divided by 100 is the actual gamma applied,
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
+# and 100 does not change the gamma.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of
+# entries shown in the various tree structured indices initially; the user
+# can expand and collapse entries dynamically later on. Doxygen will expand
+# the tree to such a level that at most the specified number of entries are
+# visible (unless a fully collapsed tree already exceeds this amount).
+# So setting the number of entries 1 will produce a full collapsed tree by
+# default. 0 is a special value representing an infinite number of entries
+# and will result in a full expanded tree by default.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely
+# identify the documentation publisher. This should be a reverse domain-name
+# style string, e.g. com.mycompany.MyDocSet.documentation.
+
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
+
+DOCSET_PUBLISHER_NAME = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
+# that can be used as input for Qt's qhelpgenerator to generate a
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
+# add. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
+# will be generated, which together with the HTML files, form an Eclipse help
+# plugin. To install this plugin and make it available under the help contents
+# menu in Eclipse, the contents of the directory containing the HTML and XML
+# files needs to be copied into the plugins directory of eclipse. The name of
+# the directory within the plugins directory should be the same as
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
+# the help appears.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have
+# this name.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs)
+# at top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it. Since the tabs have the same information as the
+# navigation tree you can set this option to NO if you already set
+# GENERATE_TREEVIEW to YES.
+
+DISABLE_INDEX = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+# Since the tree basically has the same information as the tab index you
+# could consider to set DISABLE_INDEX to NO when enabling this option.
+
+GENERATE_TREEVIEW = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
+# (range [0,1..20]) that doxygen will group on one line in the generated HTML
+# documentation. Note that a value of 0 will completely suppress the enum
+# values from appearing in the overview section.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
+# links to external symbols imported via tag files in a separate window.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are
+# not supported properly for IE 6.0, but are supported on all modern browsers.
+# Note that when changing this option you need to delete any form_*.png files
+# in the HTML output before the changes have effect.
+
+FORMULA_TRANSPARENT = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
+# (see http://www.mathjax.org) which uses client side Javascript for the
+# rendering instead of using prerendered bitmaps. Use this if you do not
+# have LaTeX installed or if you want to formulas look prettier in the HTML
+# output. When enabled you may also need to install MathJax separately and
+# configure the path to it using the MATHJAX_RELPATH option.
+
+USE_MATHJAX = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and
+# SVG. The default value is HTML-CSS, which is slower, but has the best
+# compatibility.
+
+MATHJAX_FORMAT = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the
+# HTML output directory using the MATHJAX_RELPATH option. The destination
+# directory should contain the MathJax.js script. For instance, if the mathjax
+# directory is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to
+# the MathJax Content Delivery Network so you can quickly see the result without
+# installing MathJax.
+# However, it is strongly recommended to install a local
+# copy of MathJax from http://www.mathjax.org before deployment.
+
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
+# names that should be enabled during MathJax rendering.
+
+MATHJAX_EXTENSIONS =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript
+# pieces of code that will be used on startup of the MathJax code.
+
+MATHJAX_CODEFILE =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box
+# for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
+# (GENERATE_DOCSET) there is already a search function so this one should
+# typically be disabled. For large projects the javascript based search engine
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript.
+# There are two flavours of web server based search depending on the
+# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
+# searching and an index file used by the script. When EXTERNAL_SEARCH is
+# enabled the indexing and searching needs to be provided by external tools.
+# See the manual for details.
+
+SERVER_BASED_SEARCH = NO
+
+# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain
+# the search results. Doxygen ships with an example indexer (doxyindexer) and
+# search engine (doxysearch.cgi) which are based on the open source search
+# engine library Xapian. See the manual for configuration details.
+
+EXTERNAL_SEARCH = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will returned the search results when EXTERNAL_SEARCH is enabled.
+# Doxygen ships with an example search engine (doxysearch) which is based on
+# the open source search engine library Xapian. See the manual for configuration
+# details.
+
+SEARCHENGINE_URL =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+
+SEARCHDATA_FILE = searchdata.xml
+
+# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+
+EXTERNAL_SEARCH_ID =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id
+# of to a relative location where the documentation can be found.
+# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ...
+
+EXTRA_SEARCH_MAPPINGS =
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+# Note that when enabling USE_PDFLATEX this option is only used for
+# generating bitmaps for formulas in the HTML output, but not in the
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, letter, legal and
+# executive. If left blank a4 will be used.
+
+PAPER_TYPE = a4
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for
+# the generated latex document. The footer should contain everything after
+# the last chapter. If it is left blank doxygen will generate a
+# standard footer. Notice: only use this tag if you know what you are doing!
+
+LATEX_FOOTER =
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images
+# or other source files which should be copied to the LaTeX output directory.
+# Note that the files will be copied as-is; there are no commands or markers
+# available.
+
+LATEX_EXTRA_FILES =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include
+# source code with syntax highlighting in the LaTeX output.
+# Note that which sources are shown also depends on other settings
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
+# http://en.wikipedia.org/wiki/BibTeX for more info.
+
+LATEX_BIB_STYLE = plain
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load style sheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES Doxygen will generate DOCBOOK files
+# that can be used to generate PDF.
+
+GENERATE_DOCBOOK = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it. If left blank docbook will be used as the default path.
+
+DOCBOOK_OUTPUT = docbook
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.
+# This is useful
+# if you want to understand what is going on.
+# On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# pointed to by INCLUDE_PATH will be searched when a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition that
+# overrules the definition found in the source code.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all references to function-like macros
+# that are alone on a line, have an all uppercase name, and do not end with a
+# semicolon, because these will confuse the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. For each
+# tag file the location of the external documentation should be added. The
+# format of a tag file without this location is as follows:
+#
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths
+# or URLs. Note that each tag file must have a unique name (where the name does
+# NOT include the path). If a tag file is not located in the directory in which
+# doxygen is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed
+# in the related pages index. If set to NO, only the current project's
+# pages will be listed.
+
+EXTERNAL_PAGES = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option also works with HAVE_DOT disabled, but it is recommended to
+# install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
+# allowed to run in parallel. When set to 0 (the default) doxygen will
+# base this on the number of processors available in the system. You can set it
+# explicitly to a value larger than 0 to get control over the balance
+# between CPU load and processing speed.
+
+DOT_NUM_THREADS = 0
+
+# By default doxygen will use the Helvetica font for all dot files that
+# doxygen generates. When you want a differently looking font you can specify
+# the font name using DOT_FONTNAME. You need to make sure dot is able to find
+# the font, which can be done by putting it in a standard location or by setting
+# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
+# directory containing the font.
+
+DOT_FONTNAME = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the Helvetica font.
+# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
+# set the path where dot can find it.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside
+# the class node. If there are many fields or methods and many nodes the
+# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
+# threshold limits the number of items for each type to make the size more
+# manageable. Set this to 0 for no limit. Note that the threshold may be
+# exceeded by 50% before the limit is enforced.
+
+UML_LIMIT_NUM_FIELDS = 10
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will generate a graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are svg, png, jpg, or gif.
+# If left blank png will be used. If you choose svg you need to set
+# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible in IE 9+ (other browsers do not have this requirement).
+
+DOT_IMAGE_FORMAT = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+# Note that this requires a modern browser other than Internet Explorer.
+# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
+# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible. Older versions of IE do not have SVG support.
+
+INTERACTIVE_SVG = NO
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the
+# \mscfile command).
+
+MSCFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = YES
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/libembroidery.dox b/Software/Visual_Studio/Embroidery/libembroidery/libembroidery.dox
new file mode 100644
index 000000000..1c4775d53
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/libembroidery.dox
@@ -0,0 +1,7 @@
+/*! @mainpage
+ * For developers wanting to use libembroidery in another
+ * project, refer to the thumbnailer-kde4 or libembroidery-convert
+ * application source code first and refer back to here as neccessary.
+ * They serve as small examples on proper usage without going too
+ * deep into the internals of libembroidery.
+ */ \ No newline at end of file
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/libembroidery.doxyfile b/Software/Visual_Studio/Embroidery/libembroidery/libembroidery.doxyfile
new file mode 100644
index 000000000..7e1be1819
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/libembroidery.doxyfile
@@ -0,0 +1,1890 @@
+# Doxyfile 1.8.4
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed
+# in front of the TAG it is preceding .
+# All text after a hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or sequence of words) that should
+# identify the project. Note that if you do not use Doxywizard you need
+# to put quotes around the project name if it contains spaces.
+
+PROJECT_NAME = "libembroidery"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER =
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer
+# a quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF =
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is
+# included in the documentation. The maximum height of the logo should not
+# exceed 55 pixels and the maximum width should not exceed 200 pixels.
+# Doxygen will copy the logo to the output directory.
+
+PROJECT_LOGO =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY =
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Latvian, Lithuanian, Norwegian, Macedonian,
+# Persian, Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic,
+# Slovak, Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip. Note that you specify absolute paths here, but also
+# relative paths, which will be relative from the directory where doxygen is
+# started.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful if your file system
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 4
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding
+# "class=itcl::class" will allow you to use the command class in the
+# itcl::class meaning.
+
+TCL_SUBST =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension,
+# and language is one of the parsers supported by doxygen: IDL, Java,
+# Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C,
+# C++. For instance to make doxygen treat .inc files as Fortran files (default
+# is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note
+# that for custom extensions you also need to set FILE_PATTERNS otherwise the
+# files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all
+# comments according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you
+# can mix doxygen, HTML, and XML commands with Markdown formatting.
+# Disable only in case of backward compatibilities issues.
+
+MARKDOWN_SUPPORT = YES
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by by putting a % sign in front of the word
+# or globally by setting AUTOLINK_SUPPORT to NO.
+
+AUTOLINK_SUPPORT = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also makes the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES (the
+# default) will make doxygen replace the get and set methods by a property in
+# the documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
+# unions are shown inside the group in which they are included (e.g. using
+# @ingroup) instead of on a separate page (for HTML and Man pages) or
+# section (for LaTeX and RTF).
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
+# unions with only public data fields or simple typedef fields will be shown
+# inline in the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO (the default), structs, classes, and unions are shown on a separate
+# page (for HTML and Man pages) or section (for LaTeX and RTF).
+
+INLINE_SIMPLE_STRUCTS = NO
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can
+# be an expensive process and often the same symbol appear multiple times in
+# the code, doxygen keeps a cache of pre-resolved symbols. If the cache is too
+# small doxygen will become slower. If the cache is too large, memory is wasted.
+# The cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid
+# range is 0..9, the default is 0, corresponding to a cache size of 2^16 = 65536
+# symbols.
+
+LOOKUP_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
+
+EXTRACT_PACKAGE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = NO
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespaces are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = YES
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = YES
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
+# will list include files with double quotes in the documentation
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
+# will sort the (brief and detailed) documentation of class members so that
+# constructors and destructors are listed first. If set to NO (the default)
+# the constructors will appear in the respective orders defined by
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
+# do proper type resolution of all parameters of a function it will reject a
+# match between the prototype and the implementation of a member function even
+# if there is only one candidate or it is obvious which candidate to choose
+# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
+# will still accept a match between prototype and implementation in such cases.
+
+STRICT_PROTO_MATCHING = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = NO
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = NO
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = NO
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if section-label ... \endif
+# and \cond section-label ... \endcond blocks.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or macro consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and macros in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page.
+# This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option.
+# You can optionally specify a file name after the option, if omitted
+# DoxygenLayout.xml will be used as the name of the layout file.
+
+LAYOUT_FILE =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files
+# containing the references data. This must be a list of .bib files. The
+# .bib extension is automatically appended if omitted. Using this command
+# requires the bibtex tool to be installed. See also
+# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
+# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this
+# feature you need bibtex and perl available in the search path. Do not use
+# file names with spaces, bibtex cannot handle them.
+
+CITE_BIB_FILES =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# The WARN_NO_PARAMDOC option can be enabled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT =
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
+# *.f90 *.f *.for *.vhd *.vhdl
+
+FILE_PATTERNS =
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+# If FILTER_PATTERNS is specified, this tag will be ignored.
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.
+# Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.
+# The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty or if
+# non of the patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
+# and it is also possible to disable source filtering for a specific pattern
+# using *.ext= (so without naming a filter). This option only has effect when
+# FILTER_SOURCE_FILES is enabled.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE =
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C, C++ and Fortran comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.
+# Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = doxygen
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header. Note that when using a custom header you are responsible
+# for the proper inclusion of any scripts and style sheets that doxygen
+# needs, which is dependent on the configuration options used.
+# It is advised to generate a default header using "doxygen -w html
+# header.html footer.html stylesheet.css YourConfigFile" and then modify
+# that header. Note that the header is subject to change so you typically
+# have to redo this when upgrading to a newer version of doxygen or when
+# changing the value of configuration settings such as GENERATE_TREEVIEW!
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If left blank doxygen will
+# generate a default style sheet. Note that it is recommended to use
+# HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this
+# tag will in the future become obsolete.
+
+HTML_STYLESHEET =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional
+# user-defined cascading style sheet that is included after the standard
+# style sheets created by doxygen. Using this option one can overrule
+# certain style aspects. This is preferred over using HTML_STYLESHEET
+# since it does not replace the standard style sheet and is therefor more
+# robust against future updates. Doxygen will copy the style sheet file to
+# the output directory.
+
+HTML_EXTRA_STYLESHEET =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that
+# the files will be copied as-is; there are no commands or markers available.
+
+HTML_EXTRA_FILES =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
+# Doxygen will adjust the colors in the style sheet and background images
+# according to this color. Hue is specified as an angle on a colorwheel,
+# see http://en.wikipedia.org/wiki/Hue for more information.
+# For instance the value 0 represents red, 60 is yellow, 120 is green,
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
+# The allowed range is 0 to 359.
+
+HTML_COLORSTYLE_HUE = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
+# the colors in the HTML output. For a value of 0 the output will use
+# grayscales only. A value of 255 will produce the most vivid colors.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
+# the luminance component of the colors in the HTML output. Values below
+# 100 gradually make the output lighter, whereas values above 100 make
+# the output darker. The value divided by 100 is the actual gamma applied,
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
+# and 100 does not change the gamma.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of
+# entries shown in the various tree structured indices initially; the user
+# can expand and collapse entries dynamically later on. Doxygen will expand
+# the tree to such a level that at most the specified number of entries are
+# visible (unless a fully collapsed tree already exceeds this amount).
+# So setting the number of entries 1 will produce a full collapsed tree by
+# default. 0 is a special value representing an infinite number of entries
+# and will result in a full expanded tree by default.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely
+# identify the documentation publisher. This should be a reverse domain-name
+# style string, e.g. com.mycompany.MyDocSet.documentation.
+
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
+
+DOCSET_PUBLISHER_NAME = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
+# that can be used as input for Qt's qhelpgenerator to generate a
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
+# add. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
+# will be generated, which together with the HTML files, form an Eclipse help
+# plugin. To install this plugin and make it available under the help contents
+# menu in Eclipse, the contents of the directory containing the HTML and XML
+# files needs to be copied into the plugins directory of eclipse. The name of
+# the directory within the plugins directory should be the same as
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
+# the help appears.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have
+# this name.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs)
+# at top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it. Since the tabs have the same information as the
+# navigation tree you can set this option to NO if you already set
+# GENERATE_TREEVIEW to YES.
+
+DISABLE_INDEX = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+# Since the tree basically has the same information as the tab index you
+# could consider to set DISABLE_INDEX to NO when enabling this option.
+
+GENERATE_TREEVIEW = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
+# (range [0,1..20]) that doxygen will group on one line in the generated HTML
+# documentation. Note that a value of 0 will completely suppress the enum
+# values from appearing in the overview section.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
+# links to external symbols imported via tag files in a separate window.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are
+# not supported properly for IE 6.0, but are supported on all modern browsers.
+# Note that when changing this option you need to delete any form_*.png files
+# in the HTML output before the changes have effect.
+
+FORMULA_TRANSPARENT = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
+# (see http://www.mathjax.org) which uses client side Javascript for the
+# rendering instead of using prerendered bitmaps. Use this if you do not
+# have LaTeX installed or if you want to formulas look prettier in the HTML
+# output. When enabled you may also need to install MathJax separately and
+# configure the path to it using the MATHJAX_RELPATH option.
+
+USE_MATHJAX = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and
+# SVG. The default value is HTML-CSS, which is slower, but has the best
+# compatibility.
+
+MATHJAX_FORMAT = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the
+# HTML output directory using the MATHJAX_RELPATH option. The destination
+# directory should contain the MathJax.js script. For instance, if the mathjax
+# directory is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to
+# the MathJax Content Delivery Network so you can quickly see the result without
+# installing MathJax.
+# However, it is strongly recommended to install a local
+# copy of MathJax from http://www.mathjax.org before deployment.
+
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
+# names that should be enabled during MathJax rendering.
+
+MATHJAX_EXTENSIONS =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript
+# pieces of code that will be used on startup of the MathJax code.
+
+MATHJAX_CODEFILE =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box
+# for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
+# (GENERATE_DOCSET) there is already a search function so this one should
+# typically be disabled. For large projects the javascript based search engine
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript.
+# There are two flavours of web server based search depending on the
+# EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for
+# searching and an index file used by the script. When EXTERNAL_SEARCH is
+# enabled the indexing and searching needs to be provided by external tools.
+# See the manual for details.
+
+SERVER_BASED_SEARCH = NO
+
+# When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain
+# the search results. Doxygen ships with an example indexer (doxyindexer) and
+# search engine (doxysearch.cgi) which are based on the open source search
+# engine library Xapian. See the manual for configuration details.
+
+EXTERNAL_SEARCH = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will returned the search results when EXTERNAL_SEARCH is enabled.
+# Doxygen ships with an example search engine (doxysearch) which is based on
+# the open source search engine library Xapian. See the manual for configuration
+# details.
+
+SEARCHENGINE_URL =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+
+SEARCHDATA_FILE = searchdata.xml
+
+# When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+
+EXTERNAL_SEARCH_ID =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id
+# of to a relative location where the documentation can be found.
+# The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ...
+
+EXTRA_SEARCH_MAPPINGS =
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+# Note that when enabling USE_PDFLATEX this option is only used for
+# generating bitmaps for formulas in the HTML output, but not in the
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, letter, legal and
+# executive. If left blank a4 will be used.
+
+PAPER_TYPE = a4
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for
+# the generated latex document. The footer should contain everything after
+# the last chapter. If it is left blank doxygen will generate a
+# standard footer. Notice: only use this tag if you know what you are doing!
+
+LATEX_FOOTER =
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images
+# or other source files which should be copied to the LaTeX output directory.
+# Note that the files will be copied as-is; there are no commands or markers
+# available.
+
+LATEX_EXTRA_FILES =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include
+# source code with syntax highlighting in the LaTeX output.
+# Note that which sources are shown also depends on other settings
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
+# http://en.wikipedia.org/wiki/BibTeX for more info.
+
+LATEX_BIB_STYLE = plain
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load style sheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES Doxygen will generate DOCBOOK files
+# that can be used to generate PDF.
+
+GENERATE_DOCBOOK = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the DOCBOOK pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it. If left blank docbook will be used as the default path.
+
+DOCBOOK_OUTPUT = docbook
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.
+# This is useful
+# if you want to understand what is going on.
+# On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# pointed to by INCLUDE_PATH will be searched when a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition that
+# overrules the definition found in the source code.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all references to function-like macros
+# that are alone on a line, have an all uppercase name, and do not end with a
+# semicolon, because these will confuse the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. For each
+# tag file the location of the external documentation should be added. The
+# format of a tag file without this location is as follows:
+#
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths
+# or URLs. Note that each tag file must have a unique name (where the name does
+# NOT include the path). If a tag file is not located in the directory in which
+# doxygen is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed
+# in the related pages index. If set to NO, only the current project's
+# pages will be listed.
+
+EXTERNAL_PAGES = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option also works with HAVE_DOT disabled, but it is recommended to
+# install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
+# allowed to run in parallel. When set to 0 (the default) doxygen will
+# base this on the number of processors available in the system. You can set it
+# explicitly to a value larger than 0 to get control over the balance
+# between CPU load and processing speed.
+
+DOT_NUM_THREADS = 0
+
+# By default doxygen will use the Helvetica font for all dot files that
+# doxygen generates. When you want a differently looking font you can specify
+# the font name using DOT_FONTNAME. You need to make sure dot is able to find
+# the font, which can be done by putting it in a standard location or by setting
+# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
+# directory containing the font.
+
+DOT_FONTNAME = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the Helvetica font.
+# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
+# set the path where dot can find it.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside
+# the class node. If there are many fields or methods and many nodes the
+# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
+# threshold limits the number of items for each type to make the size more
+# manageable. Set this to 0 for no limit. Note that the threshold may be
+# exceeded by 50% before the limit is enforced.
+
+UML_LIMIT_NUM_FIELDS = 10
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will generate a graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are svg, png, jpg, or gif.
+# If left blank png will be used. If you choose svg you need to set
+# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible in IE 9+ (other browsers do not have this requirement).
+
+DOT_IMAGE_FORMAT = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+# Note that this requires a modern browser other than Internet Explorer.
+# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
+# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
+# visible. Older versions of IE do not have SVG support.
+
+INTERACTIVE_SVG = NO
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the
+# \mscfile command).
+
+MSCFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = YES
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/libembroidery.pri b/Software/Visual_Studio/Embroidery/libembroidery/libembroidery.pri
new file mode 100644
index 000000000..0379a74a8
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/libembroidery.pri
@@ -0,0 +1,234 @@
+INCLUDEPATH += ../libembroidery
+
+msvc {
+QMAKE_CFLAGS += /Za #equivalent of -pedantic-errors
+}
+
+!msvc {
+#Ensure anything that does not strictly adhere to C89 is treated as an error
+QMAKE_CFLAGS += -std=c89 -pedantic-errors
+QMAKE_CFLAGS += -fvisibility=hidden #Check exported symbols using: nm -C -D libembroidery.so | grep ' T '
+
+#Ensure all implicit function declarations are errors rather than warnings
+QMAKE_CFLAGS_WARN_ON += -Werror=implicit-function-declaration
+}
+
+#Uncomment line below to consider all warnings as errors
+#QMAKE_CFLAGS_WARN_ON += -Werror
+
+#Uncomment lines below to hide various warnings
+#QMAKE_CFLAGS_WARN_ON += -Wno-unused-parameter
+#QMAKE_CFLAGS_WARN_ON += -Wno-unused-but-set-variable
+#QMAKE_CFLAGS_WARN_ON += -Wno-unused-variable
+
+SOURCES += \
+../libembroidery/compound-file.c \
+../libembroidery/compound-file-difat.c \
+../libembroidery/compound-file-directory.c \
+../libembroidery/compound-file-fat.c \
+../libembroidery/compound-file-header.c \
+../libembroidery/emb-arc.c \
+../libembroidery/emb-circle.c \
+../libembroidery/emb-compress.c \
+../libembroidery/emb-color.c \
+../libembroidery/emb-ellipse.c \
+../libembroidery/emb-file.c \
+../libembroidery/emb-flag.c \
+../libembroidery/emb-format.c \
+../libembroidery/emb-hash.c \
+../libembroidery/emb-hoop.c \
+../libembroidery/emb-layer.c \
+../libembroidery/emb-line.c \
+../libembroidery/emb-logging.c \
+../libembroidery/emb-path.c \
+../libembroidery/emb-pattern.c \
+../libembroidery/emb-point.c \
+../libembroidery/emb-polygon.c \
+../libembroidery/emb-polyline.c \
+../libembroidery/emb-reader-writer.c \
+../libembroidery/emb-rect.c \
+../libembroidery/emb-satin-line.c \
+../libembroidery/emb-settings.c \
+../libembroidery/emb-spline.c \
+../libembroidery/emb-stitch.c \
+../libembroidery/emb-thread.c \
+../libembroidery/emb-time.c \
+../libembroidery/emb-vector.c \
+../libembroidery/hashtable.c \
+../libembroidery/helpers-binary.c \
+../libembroidery/helpers-misc.c \
+../libembroidery/thread-color.c \
+../libembroidery/format-10o.c \
+../libembroidery/format-100.c \
+../libembroidery/format-art.c \
+../libembroidery/format-bmc.c \
+../libembroidery/format-bro.c \
+../libembroidery/format-cnd.c \
+../libembroidery/format-col.c \
+../libembroidery/format-csd.c \
+../libembroidery/format-csv.c \
+../libembroidery/format-dat.c \
+../libembroidery/format-dem.c \
+../libembroidery/format-dsb.c \
+../libembroidery/format-dst.c \
+../libembroidery/format-dsz.c \
+../libembroidery/format-dxf.c \
+../libembroidery/format-edr.c \
+../libembroidery/format-emd.c \
+../libembroidery/format-exp.c \
+../libembroidery/format-exy.c \
+../libembroidery/format-eys.c \
+../libembroidery/format-fxy.c \
+../libembroidery/format-gc.c \
+../libembroidery/format-gnc.c \
+../libembroidery/format-gt.c \
+../libembroidery/format-hus.c \
+../libembroidery/format-inb.c \
+../libembroidery/format-inf.c \
+../libembroidery/format-jef.c \
+../libembroidery/format-ksm.c \
+../libembroidery/format-max.c \
+../libembroidery/format-mit.c \
+../libembroidery/format-new.c \
+../libembroidery/format-ofm.c \
+../libembroidery/format-pcd.c \
+../libembroidery/format-pcm.c \
+../libembroidery/format-pcq.c \
+../libembroidery/format-pcs.c \
+../libembroidery/format-pec.c \
+../libembroidery/format-pel.c \
+../libembroidery/format-pem.c \
+../libembroidery/format-pes.c \
+../libembroidery/format-phb.c \
+../libembroidery/format-phc.c \
+../libembroidery/format-plt.c \
+../libembroidery/format-rgb.c \
+../libembroidery/format-sew.c \
+../libembroidery/format-shv.c \
+../libembroidery/format-sst.c \
+../libembroidery/format-stx.c \
+../libembroidery/format-svg.c \
+../libembroidery/format-t01.c \
+../libembroidery/format-t09.c \
+../libembroidery/format-tap.c \
+../libembroidery/format-thr.c \
+../libembroidery/format-txt.c \
+../libembroidery/format-u00.c \
+../libembroidery/format-u01.c \
+../libembroidery/format-vip.c \
+../libembroidery/format-vp3.c \
+../libembroidery/format-xxx.c \
+../libembroidery/format-zsk.c \
+
+HEADERS += \
+../libembroidery/api-start.h \
+../libembroidery/api-stop.h \
+../libembroidery/compound-file.h \
+../libembroidery/compound-file-common.h \
+../libembroidery/compound-file-difat.h \
+../libembroidery/compound-file-directory.h \
+../libembroidery/compound-file-fat.h \
+../libembroidery/compound-file-header.h \
+../libembroidery/emb-arc.h \
+../libembroidery/emb-circle.h \
+../libembroidery/emb-compress.h \
+../libembroidery/emb-color.h \
+../libembroidery/emb-ellipse.h \
+../libembroidery/emb-file.h \
+../libembroidery/emb-flag.h \
+../libembroidery/emb-format.h \
+../libembroidery/emb-hash.h \
+../libembroidery/emb-hoop.h \
+../libembroidery/emb-layer.h \
+../libembroidery/emb-line.h \
+../libembroidery/emb-logging.h \
+../libembroidery/emb-path.h \
+../libembroidery/emb-pattern.h \
+../libembroidery/emb-point.h \
+../libembroidery/emb-polygon.h \
+../libembroidery/emb-polyline.h \
+../libembroidery/emb-reader-writer.h \
+../libembroidery/emb-rect.h \
+../libembroidery/emb-satin-line.h \
+../libembroidery/emb-settings.h \
+../libembroidery/emb-spline.h \
+../libembroidery/emb-stitch.h \
+../libembroidery/emb-thread.h \
+../libembroidery/emb-time.h \
+../libembroidery/emb-vector.h \
+../libembroidery/hashtable.h \
+../libembroidery/helpers-binary.h \
+../libembroidery/helpers-misc.h \
+../libembroidery/helpers-unused.h \
+../libembroidery/thread-color.h \
+../libembroidery/formats.h \
+../libembroidery/format-10o.h \
+../libembroidery/format-100.h \
+../libembroidery/format-art.h \
+../libembroidery/format-bmc.h \
+../libembroidery/format-bro.h \
+../libembroidery/format-cnd.h \
+../libembroidery/format-col.h \
+../libembroidery/format-csd.h \
+../libembroidery/format-csv.h \
+../libembroidery/format-dat.h \
+../libembroidery/format-dem.h \
+../libembroidery/format-dsb.h \
+../libembroidery/format-dst.h \
+../libembroidery/format-dsz.h \
+../libembroidery/format-dxf.h \
+../libembroidery/format-edr.h \
+../libembroidery/format-emd.h \
+../libembroidery/format-exp.h \
+../libembroidery/format-exy.h \
+../libembroidery/format-eys.h \
+../libembroidery/format-fxy.h \
+../libembroidery/format-gc.h \
+../libembroidery/format-gnc.h \
+../libembroidery/format-gt.h \
+../libembroidery/format-hus.h \
+../libembroidery/format-inb.h \
+../libembroidery/format-inf.h \
+../libembroidery/format-jef.h \
+../libembroidery/format-ksm.h \
+../libembroidery/format-max.h \
+../libembroidery/format-mit.h \
+../libembroidery/format-new.h \
+../libembroidery/format-ofm.h \
+../libembroidery/format-pcd.h \
+../libembroidery/format-pcm.h \
+../libembroidery/format-pcq.h \
+../libembroidery/format-pcs.h \
+../libembroidery/format-pec.h \
+../libembroidery/format-pel.h \
+../libembroidery/format-pem.h \
+../libembroidery/format-pes.h \
+../libembroidery/format-phb.h \
+../libembroidery/format-phc.h \
+../libembroidery/format-plt.h \
+../libembroidery/format-rgb.h \
+../libembroidery/format-sew.h \
+../libembroidery/format-shv.h \
+../libembroidery/format-sst.h \
+../libembroidery/format-stx.h \
+../libembroidery/format-svg.h \
+../libembroidery/format-t01.h \
+../libembroidery/format-t09.h \
+../libembroidery/format-tap.h \
+../libembroidery/format-thr.h \
+../libembroidery/format-txt.h \
+../libembroidery/format-u00.h \
+../libembroidery/format-u01.h \
+../libembroidery/format-vip.h \
+../libembroidery/format-vp3.h \
+../libembroidery/format-xxx.h \
+../libembroidery/format-zsk.h \
+
+# TODO: merge the computational geometry code into libembroidery structs
+SOURCES += \
+../libembroidery/geom-arc.c \
+../libembroidery/geom-line.c \
+
+HEADERS += \
+../libembroidery/geom-arc.h \
+../libembroidery/geom-line.h \
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/libembroidery.pro b/Software/Visual_Studio/Embroidery/libembroidery/libembroidery.pro
new file mode 100644
index 000000000..5b538645c
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/libembroidery.pro
@@ -0,0 +1,8 @@
+TEMPLATE = subdirs
+CONFIG += ordered
+
+SUBDIRS = \
+libembroidery-shared.pro \
+libembroidery-static.pro \
+
+QMAKE_DISTCLEAN += object_script.*
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/thread-color.c b/Software/Visual_Studio/Embroidery/libembroidery/thread-color.c
new file mode 100644
index 000000000..06ace343f
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/thread-color.c
@@ -0,0 +1,5096 @@
+#include "thread-color.h"
+
+#ifdef ARDUINO /* ARDUINO TODO: remove this line when thread-color.c is arduino compatible. This is a temporary arduino build fix. */
+#else /* ARDUINO TODO: remove this line when thread-color.c is arduino compatible. This is a temporary arduino build fix. */
+
+int getNum_Arc_Polyester(unsigned int color) { return -1; } /*TODO: finish */
+const char* getName_Arc_Polyester(unsigned int color) { return ""; } /*TODO: finish */
+
+int getNum_Arc_Rayon(unsigned int color) { return -1; } /*TODO: finish */
+const char* getName_Arc_Rayon(unsigned int color) { return ""; } /*TODO: finish */
+
+int getNum_CoatsAndClark_Rayon(unsigned int color) { return -1; } /*TODO: finish */
+const char* getName_CoatsAndClark_Rayon(unsigned int color) { return ""; } /*TODO: finish */
+
+int getNum_Exquisite_Polyester(unsigned int color) { return -1; } /*TODO: finish */
+const char* getName_Exquisite_Polyester(unsigned int color) { return ""; } /*TODO: finish */
+
+int getNum_Fufu_Polyester(unsigned int color) { return -1; } /*TODO: finish */
+const char* getName_Fufu_Polyester(unsigned int color) { return ""; } /*TODO: finish */
+
+int getNum_Fufu_Rayon(unsigned int color) { return -1; } /*TODO: finish */
+const char* getName_Fufu_Rayon(unsigned int color) { return ""; } /*TODO: finish */
+
+int getNum_Hemingworth_Polyester(unsigned int color)
+{
+ switch(color)
+ {
+ case 0xFFFFFFFF: return 1001;
+ case 0xFFDDE00F: return 1271;
+ case 0xFFC9DD03: return 1272;
+ case 0xFF60DD49: return 1273;
+ case 0xFFFFCC1E: return 1274;
+ case 0xFFFFED38: return 1275;
+ case 0xFFFFA952: return 1276;
+ case 0xFFFF9338: return 1277;
+ case 0xFFFF585F: return 1278;
+ case 0xFFF28CA3: return 1279;
+ case 0xFFFE8A9E: return 1280;
+ case 0xFFFC074F: return 1281;
+ case 0xFFCFC3C3: return 1067;
+ case 0xFFC9CAC8: return 1068;
+ case 0xFFB2B4B3: return 1069;
+ case 0xFFC6C6BC: return 1070;
+ case 0xFF616365: return 1244;
+ case 0xFF4D4F53: return 1245;
+ case 0xFF8E908F: return 1072;
+ case 0xFF747678: return 1077;
+ case 0xFF6C6F70: return 1073;
+ case 0xFF191D1F: return 1079;
+ case 0xFF1B242A: return 1087;
+ case 0xFF000000: return 1000;
+ case 0xFFD5D2CA: return 1118;
+ case 0xFFDAE3EA: return 1119;
+ case 0xFFA6BCC6: return 1076;
+ case 0xFF818A8F: return 1074;
+ case 0xFF595A5C: return 1078;
+ case 0xFFB9C9D0: return 1239;
+ case 0xFF7D9AAA: return 1240;
+ case 0xFF5E6A71: return 1085;
+ case 0xFF003C69: return 1241;
+ case 0xFF003946: return 1242;
+ case 0xFF004250: return 1081;
+ case 0xFF37424A: return 1086;
+ case 0xFF005B82: return 1192;
+ case 0xFF5E9CAE: return 1193;
+ case 0xFF6AADE4: return 1188;
+ case 0xFF4B92DB: return 1187;
+ case 0xFF8FCAE7: return 1186;
+ case 0xFFC2DEEA: return 1185;
+ case 0xFFA0CFEB: return 1256;
+ case 0xFF0098DB: return 1255;
+ case 0xFF3D7EDB: return 1202;
+ case 0xFF0039A6: return 1203;
+ case 0xFF00338D: return 1204;
+ case 0xFF0B2265: return 1205;
+ case 0xFF98C6EA: return 1189;
+ case 0xFFAACAE6: return 1190;
+ case 0xFF8EBAE5: return 1191;
+ case 0xFF0073CF: return 1198;
+ case 0xFF004165: return 1201;
+ case 0xFF004153: return 1200;
+ case 0xFF002244: return 1199;
+ case 0xFF002C5F: return 1265;
+ case 0xFF002857: return 1264;
+ case 0xFF003591: return 1263;
+ case 0xFF002C77: return 1261;
+ case 0xFF6F9AD3: return 1262;
+ case 0xFF65CFE9: return 1197;
+ case 0xFF0075B0: return 1195;
+ case 0xFF0066A1: return 1196;
+ case 0xFF006983: return 1194;
+ case 0xFF003D4C: return 1258;
+ case 0xFF0098C3: return 1259;
+ case 0xFF00B0CA: return 1260;
+ case 0xFF6FD4E4: return 1257;
+ case 0xFFBBE7E6: return 1178;
+ case 0xFFC1E2E5: return 1172;
+ case 0xFF8FDFE2: return 1173;
+ case 0xFF00AFD8: return 1174;
+ case 0xFF006778: return 1181;
+ case 0xFF007C92: return 1180;
+ case 0xFF009AA6: return 1176;
+ case 0xFF7CA295: return 1175;
+ case 0xFF63CECA: return 1177;
+ case 0xFF00877C: return 1179;
+ case 0xFF007B69: return 1182;
+ case 0xFF024E43: return 1183;
+ case 0xFF004953: return 1184;
+ case 0xFF156570: return 1082;
+ case 0xFF00505C: return 1113;
+ case 0xFF44697D: return 1084;
+ case 0xFF496C60: return 1114;
+ case 0xFF949D9E: return 1115;
+ case 0xFF91BAA3: return 1243;
+ case 0xFFB9CCC3: return 1100;
+ case 0xFFA6E6BC: return 1088;
+ case 0xFF00B588: return 1094;
+ case 0xFF00985F: return 1106;
+ case 0xFF009B74: return 1107;
+ case 0xFF007D57: return 1105;
+ case 0xFF006A4D: return 1104;
+ case 0xFF00685B: return 1254;
+ case 0xFF0D776E: return 1253;
+ case 0xFFC3E76F: return 1099;
+ case 0xFFCCDC00: return 1247;
+ case 0xFF69BE28: return 1097;
+ case 0xFF92D400: return 1091;
+ case 0xFF7AB800: return 1092;
+ case 0xFF3F9C35: return 1093;
+ case 0xFF00AF3F: return 1248;
+ case 0xFF007934: return 1095;
+ case 0xFF008542: return 1108;
+ case 0xFF00693C: return 1109;
+ case 0xFF1C453B: return 1250;
+ case 0xFF175E54: return 1249;
+ case 0xFFC8E59A: return 1096;
+ case 0xFF69923A: return 1251;
+ case 0xFF557630: return 1252;
+ case 0xFF739600: return 1089;
+ case 0xFF53682B: return 1090;
+ case 0xFF035642: return 1103;
+ case 0xFF284E36: return 1110;
+ case 0xFF004438: return 1111;
+ case 0xFF004D46: return 1112;
+ case 0xFF57584F: return 1121;
+ case 0xFF404A29: return 1123;
+ case 0xFF83847A: return 1120;
+ case 0xFF827C34: return 1058;
+ case 0xFFB19B00: return 1061;
+ case 0xFFB5A300: return 1059;
+ case 0xFFF8E498: return 1060;
+ case 0xFFD7D3C7: return 1229;
+ case 0xFFD5C833: return 1098;
+ case 0xFF6A7029: return 1101;
+ case 0xFF898F4B: return 1102;
+ case 0xFF65551C: return 1246;
+ case 0xFF4B452C: return 1117;
+ case 0xFF4B471A: return 1116;
+ case 0xFF718674: return 1083;
+ case 0xFF4F4C25: return 1125;
+ case 0xFF5D4F4B: return 1131;
+ case 0xFF452325: return 1126;
+ case 0xFF4E2E2D: return 1128;
+ case 0xFF6E3219: return 1130;
+ case 0xFF60351D: return 1134;
+ case 0xFF6C4D23: return 1140;
+ case 0xFF766A65: return 1237;
+ case 0xFF5B491F: return 1137;
+ case 0xFF6E5A2A: return 1135;
+ case 0xFFAB8422: return 1136;
+ case 0xFF856822: return 1122;
+ case 0xFF675C53: return 1236;
+ case 0xFF9A996E: return 1124;
+ case 0xFFC2B2B5: return 1149;
+ case 0xFFA5ACAF: return 1146;
+ case 0xFFAE7D5B: return 1145;
+ case 0xFFA76F3E: return 1133;
+ case 0xFFA25022: return 1064;
+ case 0xFF86431E: return 1238;
+ case 0xFFB2541A: return 1163;
+ case 0xFF833820: return 1164;
+ case 0xFF9A3B26: return 1144;
+ case 0xFF825C26: return 1142;
+ case 0xFFC59217: return 1063;
+ case 0xFFDDB99A: return 1062;
+ case 0xFFD2C295: return 1057;
+ case 0xFFC2C2A0: return 1056;
+ case 0xFFB3B38C: return 1055;
+ case 0xFFC7B37F: return 1054;
+ case 0xFFBD9271: return 1171;
+ case 0xFFB3995D: return 1138;
+ case 0xFFCEA98C: return 1235;
+ case 0xFFE39B6C: return 1139;
+ case 0xFFBA6F2E: return 1132;
+ case 0xFFBB650E: return 1141;
+ case 0xFFEBE8B1: return 1042;
+ case 0xFFEEEC83: return 1043;
+ case 0xFFF3EC7A: return 1045;
+ case 0xFFF5EC5A: return 1225;
+ case 0xFFFAE700: return 1226;
+ case 0xFFF2EE72: return 1044;
+ case 0xFFFCD900: return 1227;
+ case 0xFFFADC41: return 1046;
+ case 0xFFFED100: return 1047;
+ case 0xFFF3CF45: return 1048;
+ case 0xFFEFBD47: return 1050;
+ case 0xFFEAAB00: return 1051;
+ case 0xFFDCD6B2: return 1037;
+ case 0xFFC6BC89: return 1038;
+ /* case 0xFFF8E498: return 1039; TODO: duplicate case value */
+ case 0xFFF8DE6E: return 1040;
+ case 0xFFFADA63: return 1049;
+ case 0xFFFFCB4F: return 1053;
+ case 0xFFFFA100: return 1232;
+ case 0xFFFFB612: return 1231;
+ case 0xFFFFB652: return 1230;
+ case 0xFFFFBC3D: return 1041;
+ case 0xFFCE8E00: return 1052;
+ case 0xFF9D5324: return 1143;
+ case 0xFFE98300: return 1024;
+ case 0xFFFF7000: return 1025;
+ case 0xFFE37222: return 1027;
+ case 0xFFFB4F14: return 1028;
+ case 0xFFDD4814: return 1029;
+ case 0xFFCD202C: return 1030;
+ case 0xFFC30014: return 1270;
+ case 0xFFA70232: return 1032;
+ case 0xFF882332: return 1031;
+ case 0xFFA51100: return 1002;
+ case 0xFF9E3039: return 1234;
+ case 0xFF783014: return 1233;
+ case 0xFFD55C19: return 1065;
+ case 0xFFAA272F: return 1066;
+ case 0xFF5F3327: return 1129;
+ case 0xFF5D3526: return 1127;
+ case 0xFF592C35: return 1160;
+ case 0xFF6A1A41: return 1159;
+ case 0xFF6E2714: return 1158;
+ case 0xFF662046: return 1157;
+ case 0xFF85003C: return 1156;
+ case 0xFF641F14: return 1155;
+ case 0xFFFF818D: return 1166;
+ case 0xFFFFA48A: return 1015;
+ case 0xFFFFB0B7: return 1011;
+ case 0xFFF3789B: return 1012;
+ case 0xFFDB4D69: return 1014;
+ case 0xFF91004B: return 1013;
+ case 0xFF82240C: return 1224;
+ case 0xFFF54359: return 1018;
+ case 0xFFF4587A: return 1017;
+ case 0xFFFF8B7C: return 1016;
+ case 0xFFFFC19C: return 1022;
+ case 0xFFFF8F70: return 1020;
+ case 0xFFFF6D42: return 1026;
+ case 0xFFFFA02F: return 1023;
+ case 0xFFECC182: return 1168;
+ case 0xFFFBCE92: return 1021;
+ case 0xFFFDC480: return 1228;
+ case 0xFFFFC2A2: return 1167;
+ case 0xFFEFC5CE: return 1169;
+ case 0xFFEFBE9C: return 1170;
+ case 0xFF774A39: return 1162;
+ case 0xFFB26F7E: return 1151;
+ case 0xFFD490A8: return 1165;
+ case 0xFFF6A3BB: return 1161;
+ case 0xFFFFB7AE: return 1019;
+ case 0xFFEFD6DB: return 1150;
+ case 0xFF920075: return 1036;
+ case 0xFFF375C6: return 1004;
+ case 0xFFF3BBCE: return 1003;
+ case 0xFFF1DBDF: return 1005;
+ case 0xFFF3C9D3: return 1006;
+ case 0xFFF4B2C1: return 1007;
+ case 0xFFF39EBC: return 1008;
+ case 0xFFF77AB4: return 1009;
+ case 0xFFD71F85: return 1010;
+ case 0xFF772059: return 1035;
+ case 0xFFC50084: return 1034;
+ case 0xFFA1006B: return 1033;
+ case 0xFFD1D4D3: return 1148;
+ case 0xFFCAD1E7: return 1147;
+ case 0xFF9DABE2: return 1207;
+ case 0xFF8884D5: return 1206;
+ case 0xFF1A2155: return 1209;
+ case 0xFF6459C4: return 1211;
+ case 0xFF212492: return 1208;
+ case 0xFF411244: return 1210;
+ case 0xFF3B0083: return 1223;
+ case 0xFF151C54: return 1267;
+ case 0xFF490E6F: return 1269;
+ case 0xFF57068C: return 1268;
+ case 0xFFDCC7DF: return 1217;
+ case 0xFFC2ACBE: return 1219;
+ case 0xFFDC9DDD: return 1218;
+ case 0xFFB382C7: return 1213;
+ case 0xFF9C5FB5: return 1214;
+ case 0xFF4B08A1: return 1266;
+ case 0xFFC1AFE5: return 1221;
+ case 0xFFC5B9E3: return 1222;
+ case 0xFF6E2C6B: return 1215;
+ case 0xFF7D0063: return 1216;
+ case 0xFF752864: return 1220;
+ case 0xFF55517B: return 1080;
+ case 0xFF5C7F92: return 1075;
+ case 0xFFAFADC3: return 1071;
+ case 0xFFD8AAB3: return 1152;
+ case 0xFF89687C: return 1153;
+ case 0xFF644459: return 1154;
+ case 0xFF4B306A: return 1212;
+ }
+
+ return -1;
+}
+const char* getName_Hemingworth_Polyester(unsigned int color)
+{
+ switch(color)
+ {
+ case 0xFFFFFFFF: return "Pure White";
+ case 0xFFDDE00F: return "Lemon Ice";
+ case 0xFFC9DD03: return "Neon Green";
+ case 0xFF60DD49: return "Brilliant Lime";
+ case 0xFFFFCC1E: return "Mango";
+ case 0xFFFFED38: return "Neon Yellow";
+ case 0xFFFFA952: return "Tropical Orange";
+ case 0xFFFF9338: return "Neon Orange";
+ case 0xFFFF585F: return "Rebel Peach";
+ case 0xFFF28CA3: return "Shy Flamingo";
+ case 0xFFFE8A9E: return "Neon Pink";
+ case 0xFFFC074F: return "Neon Peach";
+ case 0xFFCFC3C3: return "Dove Gray";
+ case 0xFFC9CAC8: return "Silver Lining";
+ case 0xFFB2B4B3: return "Storm Cloud";
+ case 0xFFC6C6BC: return "Platinum";
+ case 0xFF616365: return "Graphite";
+ case 0xFF4D4F53: return "Light Charcoal";
+ case 0xFF8E908F: return "Chrome";
+ case 0xFF747678: return "Antique Silver";
+ case 0xFF6C6F70: return "Pewter Gray";
+ case 0xFF191D1F: return "Black Stallion";
+ case 0xFF1B242A: return "Charcoal";
+ case 0xFF000000: return "Classic Black";
+ case 0xFFD5D2CA: return "Marshmallow";
+ case 0xFFDAE3EA: return "Ice Blue";
+ case 0xFFA6BCC6: return "Nautical Blue";
+ case 0xFF818A8F: return "Sea Storm";
+ case 0xFF595A5C: return "Bronzed Steel";
+ case 0xFFB9C9D0: return "Silvery Gray";
+ case 0xFF7D9AAA: return "Granite";
+ case 0xFF5E6A71: return "Shadow";
+ case 0xFF003C69: return "Dark Slate Blue";
+ case 0xFF003946: return "Deep Slate Blue";
+ case 0xFF004250: return "Pacific Waters";
+ case 0xFF37424A: return "Dark Slate";
+ case 0xFF005B82: return "Smoky Blue";
+ case 0xFF5E9CAE: return "Light Slate Blue";
+ case 0xFF6AADE4: return "Hyacinth";
+ case 0xFF4B92DB: return "Bluebird";
+ case 0xFF8FCAE7: return "Misty Blue";
+ case 0xFFC2DEEA: return "Cornflower Blue";
+ case 0xFFA0CFEB: return "Pale Blue";
+ case 0xFF0098DB: return "Country Blue";
+ case 0xFF3D7EDB: return "Azure";
+ case 0xFF0039A6: return "Royal Blue";
+ case 0xFF00338D: return "Brilliant Blue";
+ case 0xFF0B2265: return "Deep Blue";
+ case 0xFF98C6EA: return "Winter Blue";
+ case 0xFFAACAE6: return "Winter Sky";
+ case 0xFF8EBAE5: return "Sky Blue";
+ case 0xFF0073CF: return "China Blue";
+ case 0xFF004165: return "Dark Blueberry";
+ case 0xFF004153: return "Salem Blue";
+ case 0xFF002244: return "Navy";
+ case 0xFF002C5F: return "Sailor Blue";
+ case 0xFF002857: return "Dark Blue ";
+ case 0xFF003591: return "Berry Blue";
+ case 0xFF002C77: return "True Blue";
+ case 0xFF6F9AD3: return "Periwinkle";
+ case 0xFF65CFE9: return "Iceberg Blue";
+ case 0xFF0075B0: return "Medium Aquamarine";
+ case 0xFF0066A1: return "Dark Aquamarine";
+ case 0xFF006983: return "Peacock Blue";
+ case 0xFF003D4C: return "Dark Turquoise";
+ case 0xFF0098C3: return "Turquoise";
+ case 0xFF00B0CA: return "Caribbean Blue";
+ case 0xFF6FD4E4: return "Summer Sky";
+ case 0xFFBBE7E6: return "Crystal Lake";
+ case 0xFFC1E2E5: return "Icicle Blue";
+ case 0xFF8FDFE2: return "Frosty Blue";
+ case 0xFF00AFD8: return "Blue Lagoon";
+ case 0xFF006778: return "Blue Satin";
+ case 0xFF007C92: return "Teal Blue";
+ case 0xFF009AA6: return "Light Teal Blue";
+ case 0xFF7CA295: return "Wintergreen";
+ case 0xFF63CECA: return "Mint Green";
+ case 0xFF00877C: return "Navajo Turquoise";
+ case 0xFF007B69: return "Peacock Green";
+ case 0xFF024E43: return "Forest Glen";
+ case 0xFF004953: return "Deep Teal";
+ case 0xFF156570: return "Deep Sea";
+ case 0xFF00505C: return "Dragonfly";
+ case 0xFF44697D: return "Blue Steel";
+ case 0xFF496C60: return "Dark Sage";
+ case 0xFF949D9E: return "Silver Green";
+ case 0xFF91BAA3: return "Antique Gray";
+ case 0xFFB9CCC3: return "Ocean Spray";
+ case 0xFFA6E6BC: return "Sea Foam";
+ case 0xFF00B588: return "Cucumber Melon";
+ case 0xFF00985F: return "Light Jade";
+ case 0xFF009B74: return "Jade";
+ case 0xFF007D57: return "Dark Jade";
+ case 0xFF006A4D: return "Caribbean";
+ case 0xFF00685B: return "Dark Teal";
+ case 0xFF0D776E: return "Minty Teal";
+ case 0xFFC3E76F: return "Lemony Lime";
+ case 0xFFCCDC00: return "Kiwi Lime";
+ case 0xFF69BE28: return "Electric Green";
+ case 0xFF92D400: return "Green Apple";
+ case 0xFF7AB800: return "Key Lime";
+ case 0xFF3F9C35: return "Kelly Green";
+ case 0xFF00AF3F: return "Meadow";
+ case 0xFF007934: return "Grassy Green";
+ case 0xFF008542: return "Dark Kelly Green";
+ case 0xFF00693C: return "Christmas Green";
+ case 0xFF1C453B: return "Winter Pine ";
+ case 0xFF175E54: return "Holly Leaf";
+ case 0xFFC8E59A: return "Pistachio Nut";
+ case 0xFF69923A: return "Dusty Green";
+ case 0xFF557630: return "Bush Ivy ";
+ case 0xFF739600: return "Leafy Green";
+ case 0xFF53682B: return "Kentucky Grass";
+ case 0xFF035642: return "Ivy";
+ case 0xFF284E36: return "Evergreen";
+ case 0xFF004438: return "Mountain Meadow";
+ case 0xFF004D46: return "Forest Green";
+ case 0xFF57584F: return "Oregano";
+ case 0xFF404A29: return "Jungle Green";
+ case 0xFF83847A: return "Thyme";
+ case 0xFF827C34: return "Light Avocado";
+ case 0xFFB19B00: return "Split Pea";
+ case 0xFFB5A300: return "Spring Leaf";
+ case 0xFFF8E498: return "Almond Cream";
+ case 0xFFD7D3C7: return "Eggshell";
+ case 0xFFD5C833: return "Cornsilk Green";
+ case 0xFF6A7029: return "Avocado";
+ case 0xFF898F4B: return "Seaweed";
+ case 0xFF65551C: return "Olive Green";
+ case 0xFF4B452C: return "Coconut Shell";
+ case 0xFF4B471A: return "Parsley";
+ case 0xFF718674: return "Dried Sage";
+ case 0xFF4F4C25: return "Mocha";
+ case 0xFF5D4F4B: return "Warm Earth";
+ case 0xFF452325: return "Dark Chocolate";
+ case 0xFF4E2E2D: return "Deep Walnut";
+ case 0xFF6E3219: return "Teddybear Brown";
+ case 0xFF60351D: return "Light Chestnut";
+ case 0xFF6C4D23: return "Pecan Pie";
+ case 0xFF766A65: return "Dark Alder";
+ case 0xFF5B491F: return "Army Green";
+ case 0xFF6E5A2A: return "Pharaoh Gold";
+ case 0xFFAB8422: return "Autumn Haystack";
+ case 0xFF856822: return "Sahara";
+ case 0xFF675C53: return "Weathered Wood";
+ case 0xFF9A996E: return "Soft Beige";
+ case 0xFFC2B2B5: return "Mercury";
+ case 0xFFA5ACAF: return "Old Lace";
+ case 0xFFAE7D5B: return "Caramel Cappuccino";
+ case 0xFFA76F3E: return "Brown Sugar";
+ case 0xFFA25022: return "Light Cinnamon";
+ case 0xFF86431E: return "Cinnamon";
+ case 0xFFB2541A: return "Apple Cider";
+ case 0xFF833820: return "Rust";
+ case 0xFF9A3B26: return "Indian Paintbrush";
+ case 0xFF825C26: return "Toasted Almond";
+ case 0xFFC59217: return "Pale Caramel";
+ case 0xFFDDB99A: return "Honey Butter";
+ case 0xFFD2C295: return "Sandy Shore";
+ case 0xFFC2C2A0: return "Ecru";
+ case 0xFFB3B38C: return "Malt";
+ case 0xFFC7B37F: return "Antique Lace";
+ case 0xFFBD9271: return "Champagne";
+ case 0xFFB3995D: return "Butter Taffy";
+ case 0xFFCEA98C: return "Cream Soda";
+ case 0xFFE39B6C: return "Conch Shell";
+ case 0xFFBA6F2E: return "New Penny";
+ case 0xFFBB650E: return "Pumpkin Spice";
+ case 0xFFEBE8B1: return "Soft Sunlight";
+ case 0xFFEEEC83: return "Lemon Drop";
+ case 0xFFF3EC7A: return "Daffodil";
+ case 0xFFF5EC5A: return "Lemon Citrus";
+ case 0xFFFAE700: return "Sunshine Yellow";
+ case 0xFFF2EE72: return "Canary Yellow";
+ case 0xFFFCD900: return "Sunflower";
+ case 0xFFFADC41: return "Sun";
+ case 0xFFFED100: return "Dandelion";
+ case 0xFFF3CF45: return "Buttercup";
+ case 0xFFEFBD47: return "Ginger Root";
+ case 0xFFEAAB00: return "Goldenrod";
+ case 0xFFDCD6B2: return "Cornsilk";
+ case 0xFFC6BC89: return "Macadamia";
+ /* case 0xFFF8E498: return "Yellow Plumeria"; TODO: duplicate case value */
+ case 0xFFF8DE6E: return "Maize";
+ case 0xFFFADA63: return "Dried Banana";
+ case 0xFFFFCB4F: return "Butternut";
+ case 0xFFFFA100: return "Orange Meringue";
+ case 0xFFFFB612: return "September Sunset";
+ case 0xFFFFB652: return "Orange Cream";
+ case 0xFFFFBC3D: return "Cantaloupe";
+ case 0xFFCE8E00: return "Old Gold";
+ case 0xFF9D5324: return "Auburn";
+ case 0xFFE98300: return "Citrus Burst";
+ case 0xFFFF7000: return "Orange Slice";
+ case 0xFFE37222: return "Fiery Sunset";
+ case 0xFFFB4F14: return "Hunter Orange";
+ case 0xFFDD4814: return "Fall Harvest";
+ case 0xFFCD202C: return "Candy Apple";
+ case 0xFFC30014: return "Christmas Red";
+ case 0xFFA70232: return "Pomegranate";
+ case 0xFF882332: return "Rummy Raisin";
+ case 0xFFA51100: return "Cardinal Red";
+ case 0xFF9E3039: return "Rusty Red";
+ case 0xFF783014: return "Redwood";
+ case 0xFFD55C19: return "Carrot";
+ case 0xFFAA272F: return "Paprika";
+ case 0xFF5F3327: return "Cherrywood";
+ case 0xFF5D3526: return "Burnt Sienna";
+ case 0xFF592C35: return "Merlot";
+ case 0xFF6A1A41: return "Loganberry";
+ case 0xFF6E2714: return "Cranberry";
+ case 0xFF662046: return "Mulberry";
+ case 0xFF85003C: return "Magenta";
+ case 0xFF641F14: return "Raspberry";
+ case 0xFFFF818D: return "Salmon";
+ case 0xFFFFA48A: return "Georgia Peach";
+ case 0xFFFFB0B7: return "Rose Sunset";
+ case 0xFFF3789B: return "Bubblegum Pink";
+ case 0xFFDB4D69: return "Carnation";
+ case 0xFF91004B: return "Very Berry";
+ case 0xFF82240C: return "Raspberry Red";
+ case 0xFFF54359: return "Dark Salmon";
+ case 0xFFF4587A: return "Apricot Dream";
+ case 0xFFFF8B7C: return "Coral Reef";
+ case 0xFFFFC19C: return "Frosted Peach";
+ case 0xFFFF8F70: return "Tangerine";
+ case 0xFFFF6D42: return "Dark Mango";
+ case 0xFFFFA02F: return "Marigold";
+ case 0xFFECC182: return "Spun Silk";
+ case 0xFFFBCE92: return "Whipped Papaya";
+ case 0xFFFDC480: return "Baby Peach";
+ case 0xFFFFC2A2: return "Pink Pearl";
+ case 0xFFEFC5CE: return "Peaches 'n Cream";
+ case 0xFFEFBE9C: return "Peach Pastel";
+ case 0xFF774A39: return "Old Penny";
+ case 0xFFB26F7E: return "Dusty Rose";
+ case 0xFFD490A8: return "Winter Rose";
+ case 0xFFF6A3BB: return "Valentine Pink";
+ case 0xFFFFB7AE: return "Petal Peach";
+ case 0xFFEFD6DB: return "Soft Petal";
+ case 0xFF920075: return "Fuchsia";
+ case 0xFFF375C6: return "Pink Kiss";
+ case 0xFFF3BBCE: return "Baby Pink";
+ case 0xFFF1DBDF: return "Whisper Pink";
+ case 0xFFF3C9D3: return "Gentle Blush";
+ case 0xFFF4B2C1: return "English Rose";
+ case 0xFFF39EBC: return "Sweet Pea";
+ case 0xFFF77AB4: return "Rosy Blush";
+ case 0xFFD71F85: return "Passion Pink";
+ case 0xFF772059: return "Mulled Wine";
+ case 0xFFC50084: return "Primrose";
+ case 0xFFA1006B: return "Azalea";
+ case 0xFFD1D4D3: return "Snowflake";
+ case 0xFFCAD1E7: return "Moonlight";
+ case 0xFF9DABE2: return "Tulip";
+ case 0xFF8884D5: return "Purple Iris";
+ case 0xFF1A2155: return "Grape";
+ case 0xFF6459C4: return "Moon Shadow";
+ case 0xFF212492: return "Electric Purple";
+ case 0xFF411244: return "Indigo";
+ case 0xFF3B0083: return "Royal Purple";
+ case 0xFF151C54: return "Eggplant";
+ case 0xFF490E6F: return "Dark Purple";
+ case 0xFF57068C: return "Pure Purple";
+ case 0xFFDCC7DF: return "Pale Orchid";
+ case 0xFFC2ACBE: return "Dusty Mauve";
+ case 0xFFDC9DDD: return "Orchid";
+ case 0xFFB382C7: return "Heather";
+ case 0xFF9C5FB5: return "Lavender";
+ case 0xFF4B08A1: return "Soft Grape";
+ case 0xFFC1AFE5: return "Freesia";
+ case 0xFFC5B9E3: return "Lilac";
+ case 0xFF6E2C6B: return "Peony";
+ case 0xFF7D0063: return "Dark Fuschia";
+ case 0xFF752864: return "Grape Jelly";
+ case 0xFF55517B: return "Deep Orchid";
+ case 0xFF5C7F92: return "Misty Blue Gray";
+ case 0xFFAFADC3: return "Iron Ore";
+ case 0xFFD8AAB3: return "Light Mauve";
+ case 0xFF89687C: return "Dark Mauve";
+ case 0xFF644459: return "Wild Plum";
+ case 0xFF4B306A: return "Huckleberry";
+ }
+
+ return "";
+}
+
+int getNum_Isacord_Polyester(unsigned int color)
+{
+ switch(color)
+ {
+ case 0xFFFFFFFF: return 10;
+ /* case 0xFFFFFFFF: return 15; TODO: duplicate case value */
+ /* case 0xFFFFFFFF: return 17; TODO: duplicate case value */
+ case 0xFF000000: return 20;
+ case 0xFFFFFDED: return 101;
+ /* case 0xFF7D7D7D: break; NOTE: N/A COLOR */
+ /* case 0xFF515B61: break; NOTE: N/A COLOR */
+ case 0xFF6D757B: return 108;
+ /* case 0xFFACACAC: break; NOTE: N/A COLOR */
+ case 0xFF515B61: return 111;
+ case 0xFF5D5D5D: return 112;
+ case 0xFFCFCFCF: return 124;
+ case 0xFFA1A9B4: return 131;
+ case 0xFF192024: return 132;
+ /* case 0xFF6D757B: break; NOTE: N/A COLOR */
+ case 0xFF9EA5AA: return 142;
+ case 0xFFCFD1D5: return 145;
+ case 0xFFC6BDB4: return 150;
+ case 0xFFD5C4B3: return 151;
+ case 0xFF7C8283: return 152;
+ /* case 0xFF898F94: break; NOTE: N/A COLOR */
+ case 0xFFFEF5F0: return 180;
+ case 0xFFE9D7D9: return 182;
+ case 0xFFEBE3DD: return 184;
+ case 0xFFE0DA5F: return 221;
+ case 0xFFBFBA28: return 232;
+ /* case 0xFFECE9C1: break; NOTE: N/A COLOR */
+ case 0xFFFAF6CC: return 250;
+ /* case 0xFFECE7A5: break; NOTE: N/A COLOR */
+ /* case 0xFFECEADB: break; NOTE: N/A COLOR */
+ case 0xFFF9F8E8: return 270;
+ case 0xFFFDF76C: return 310;
+ case 0xFFF5D300: return 311;
+ case 0xFF797E24: return 345;
+ case 0xFFB0AA76: return 352;
+ case 0xFF898F2B: return 442;
+ case 0xFF98996D: return 453;
+ /* case 0xFF6E772E: break; NOTE: N/A COLOR */
+ case 0xFF6B7E6F: return 463;
+ case 0xFF3E4F34: return 465;
+ case 0xFFEDEF05: return 501;
+ /* case 0xFFFAF6CC: break; NOTE: N/A COLOR */
+ /* case 0xFFF5D300: return 506; TODO: duplicate case value */
+ /* case 0xFFFFFBD1: break; NOTE: N/A COLOR */
+ case 0xFFFDE896: return 520;
+ case 0xFFD7CE8A: return 532;
+ case 0xFFB18B00: return 542;
+ /* case 0xFFAA8D00: break; NOTE: N/A COLOR */
+ case 0xFFB28F11: return 546;
+ /* case 0xFFAC9436: break; NOTE: N/A COLOR */
+ case 0xFFB69F56: return 552;
+ /* case 0xFFF4EE8C: break; NOTE: N/A COLOR */
+ /* case 0xFFF1EB35: break; NOTE: N/A COLOR */
+ case 0xFFF8D73E: return 600;
+ /* case 0xFFF8D73E: return 605; TODO: duplicate case value */
+ case 0xFFF7DC00: return 608;
+ /* case 0xFFF7CB47: break; NOTE: N/A COLOR */
+ /* case 0xFFF7E400: break; NOTE: N/A COLOR */
+ /* case 0xFFFDE896: break; NOTE: N/A COLOR */
+ /* case 0xFFEEDB00: break; NOTE: N/A COLOR */
+ case 0xFFFEF09A: return 630;
+ /* case 0xFFFDE1AF: break; NOTE: N/A COLOR */
+ /* case 0xFFFDE896: return 640; TODO: duplicate case value */
+ case 0xFFF5D2A6: return 651;
+ case 0xFFFEF9EA: return 660;
+ case 0xFFFAF6E7: return 670;
+ case 0xFFBEBEA8: return 672;
+ case 0xFFF7C35F: return 700;
+ case 0xFFF5CA00: return 702;
+ case 0xFFDFA200: return 704;
+ case 0xFFFCF538: return 706;
+ case 0xFFFADC59: return 713;
+ case 0xFF8C7E6A: return 722;
+ /* case 0xFF827000: break; NOTE: N/A COLOR */
+ /* case 0xFF636254: break; NOTE: N/A COLOR */
+ case 0xFF594900: return 747;
+ case 0xFFD6BF94: return 761;
+ case 0xFF656452: return 776;
+ case 0xFFF1AF00: return 800;
+ /* case 0xFFF3C200: break; NOTE: N/A COLOR */
+ case 0xFFF5BA5D: return 811;
+ case 0xFFE1A23E: return 821;
+ case 0xFFCCAB3F: return 822;
+ /* case 0xFFDFA200: return 824; TODO: duplicate case value */
+ /* case 0xFFF3B044: break; NOTE: N/A COLOR */
+ case 0xFFD0A44F: return 832;
+ case 0xFFCD944A: return 842;
+ case 0xFFE3BC61: return 851;
+ case 0xFF947C4A: return 853;
+ case 0xFFCBBFA2: return 861;
+ case 0xFFA5866A: return 862;
+ /* case 0xFF001F48: break; NOTE: N/A COLOR */
+ case 0xFFEBE7DD: return 870;
+ case 0xFF9FA086: return 873;
+ case 0xFF9A897B: return 874;
+ /* case 0xFFEE9C00: break; NOTE: N/A COLOR */
+ case 0xFFF3B259: return 904;
+ case 0xFFCA832C: return 922;
+ case 0xFFC07314: return 931;
+ case 0xFFAC6613: return 932;
+ case 0xFF744808: return 933;
+ case 0xFFBD9565: return 934;
+ /* case 0xFF806800: break; NOTE: N/A COLOR */
+ case 0xFFC98300: return 940;
+ case 0xFFAF7D3E: return 941;
+ case 0xFF483928: return 945;
+ /* case 0xFFFEECD9: break; NOTE: N/A COLOR */
+ case 0xFFFEFEED: return 970;
+ /* case 0xFFDD973A: break; NOTE: N/A COLOR */
+ case 0xFF6A4129: return 1055;
+ case 0xFFFDE2C1: return 1060;
+ case 0xFFA68A68: return 1061;
+ /* case 0xFFD76814: break; NOTE: N/A COLOR */
+ /* case 0xFFED873F: break; NOTE: N/A COLOR */
+ /* case 0xFFEC870E: break; NOTE: N/A COLOR */
+ case 0xFFED9206: return 1102;
+ case 0xFFEE9C00: return 1106;
+ /* case 0xFFC45331: break; NOTE: N/A COLOR */
+ case 0xFFEE8751: return 1114;
+ case 0xFFA35214: return 1115;
+ case 0xFFF8C000: return 1120;
+ case 0xFFB7976B: return 1123;
+ case 0xFF9D5A21: return 1134;
+ case 0xFFF3D8A8: return 1140;
+ case 0xFFFACFAE: return 1141;
+ case 0xFF7A4427: return 1154;
+ case 0xFFDFC8AB: return 1172;
+ case 0xFFE89763: return 1211;
+ case 0xFFF1A236: return 1220;
+ /* case 0xFF3D2723: break; NOTE: N/A COLOR */
+ case 0xFFE5571D: return 1300;
+ case 0xFFD9674C: return 1301;
+ /* case 0xFFE8643C: break; NOTE: N/A COLOR */
+ case 0xFFE4501E: return 1304;
+ case 0xFFEA7134: return 1305;
+ case 0xFFE12A23: return 1306;
+ case 0xFFC14817: return 1311;
+ case 0xFFC45331: return 1312;
+ /* case 0xFFD7623E: break; NOTE: N/A COLOR */
+ /* case 0xFFED7C56: break; NOTE: N/A COLOR */
+ /* case 0xFF92291B: break; NOTE: N/A COLOR */
+ case 0xFFD5815E: return 1332;
+ case 0xFFBB3D2E: return 1334;
+ case 0xFFBE2D1A: return 1335;
+ case 0xFF5F1B23: return 1342;
+ case 0xFF7A3441: return 1346;
+ /* case 0xFF84291D: break; NOTE: N/A COLOR */
+ case 0xFFFBBF95: return 1351;
+ case 0xFFF4A773: return 1352;
+ case 0xFF693920: return 1355;
+ /* case 0xFFF9C6A1: break; NOTE: N/A COLOR */
+ case 0xFFF9C598: return 1362;
+ case 0xFF432731: return 1366;
+ case 0xFF464537: return 1375;
+ /* case 0xFF4D2E18: break; NOTE: N/A COLOR */
+ /* case 0xFFD64F42: break; NOTE: N/A COLOR */
+ case 0xFFF4A782: return 1430;
+ case 0xFFE22D2A: return 1501;
+ case 0xFFA93121: return 1514;
+ case 0xFFEC7168: return 1521;
+ case 0xFFF6B08E: return 1532;
+ case 0xFFF9C5B9: return 1551;
+ case 0xFF806A61: return 1565;
+ /* case 0xFF464537: break; NOTE: N/A COLOR */
+ case 0xFFE36C63: return 1600;
+ /* case 0xFFF9C7B9: break; NOTE: N/A COLOR */
+ case 0xFFE44733: return 1701;
+ case 0xFFDF0032: return 1703;
+ case 0xFFE0003D: return 1704;
+ /* case 0xFFE44733: break; NOTE: N/A COLOR */
+ case 0xFFCF0040: return 1725;
+ /* case 0xFFDB686B: break; NOTE: N/A COLOR */
+ case 0xFFF1CDCE: return 1755;
+ case 0xFFE9C9BD: return 1760;
+ case 0xFFE8C0B8: return 1761;
+ case 0xFFE00046: return 1800;
+ /* case 0xFFE43449: break; NOTE: N/A COLOR */
+ case 0xFFD6445D: return 1805;
+ case 0xFFF49E95: return 1840;
+ /* case 0xFFB76663: break; NOTE: N/A COLOR */
+ /* case 0xFFE36C63: break; NOTE: N/A COLOR */
+ /* case 0xFFF0887D: break; NOTE: N/A COLOR */
+ /* case 0xFFFAC7C1: break; NOTE: N/A COLOR */
+ case 0xFFFCDAD5: return 1860;
+ /* case 0xFFFDE3D3: break; NOTE: N/A COLOR */
+ case 0xFF636254: return 1874;
+ case 0xFF394535: return 1876;
+ case 0xFFE10057: return 1900;
+ case 0xFFBD0041: return 1902;
+ case 0xFFC00343: return 1903;
+ case 0xFFA9023A: return 1904;
+ /* case 0xFF960018: break; NOTE: N/A COLOR */
+ case 0xFFBE004F: return 1906;
+ case 0xFF910230: return 1911;
+ case 0xFF86023E: return 1912;
+ case 0xFF9A0C3B: return 1913;
+ /* case 0xFFA41F39: break; NOTE: N/A COLOR */
+ case 0xFFA33050: return 1921;
+ case 0xFFF28DA6: return 1940;
+ case 0xFFCE427A: return 1950;
+ /* case 0xFFF2B9BE: break; NOTE: N/A COLOR */
+ case 0xFF959595: return 1972;
+ case 0xFFA33145: return 2011;
+ case 0xFF9F454C: return 2022;
+ case 0xFFC7979B: return 2051;
+ /* case 0xFFD18D89: break; NOTE: N/A COLOR */
+ /* case 0xFF970038: break; NOTE: N/A COLOR */
+ case 0xFF9F003F: return 2101;
+ case 0xFF78093F: return 2113;
+ case 0xFF6D0627: return 2115;
+ case 0xFF432732: return 2123;
+ case 0xFFE6778B: return 2152;
+ case 0xFFDF8390: return 2153;
+ case 0xFFF9BFC0: return 2155;
+ case 0xFFFBD1D6: return 2160;
+ /* case 0xFFFDE3DB: break; NOTE: N/A COLOR */
+ case 0xFFD8D5D0: return 2166;
+ /* case 0xFFFEEDE2: break; NOTE: N/A COLOR */
+ case 0xFFF7DED6: return 2170;
+ case 0xFFF7DEDE: return 2171;
+ /* case 0xFFFCD9C4: break; NOTE: N/A COLOR */
+ case 0xFFE8418C: return 2220;
+ case 0xFF8C0C4A: return 2222;
+ case 0xFF883A40: return 2224;
+ case 0xFFEE71A1: return 2230;
+ case 0xFFA95A68: return 2241;
+ case 0xFFFAC8D3: return 2250;
+ case 0xFFD3007E: return 2300;
+ /* case 0xFFBF006A: break; NOTE: N/A COLOR */
+ case 0xFFD20067: return 2320;
+ /* case 0xFF780C38: break; NOTE: N/A COLOR */
+ case 0xFF651533: return 2333;
+ case 0xFF3A212B: return 2336;
+ /* case 0xFFF2E0DC: break; NOTE: N/A COLOR */
+ case 0xFFFDE5EC: return 2363;
+ case 0xFF970059: return 2500;
+ /* case 0xFF8B1771: break; NOTE: N/A COLOR */
+ case 0xFFAA4381: return 2504;
+ /* case 0xFFB40073: break; NOTE: N/A COLOR */
+ case 0xFF820052: return 2506;
+ /* case 0xFFD63C81: break; NOTE: N/A COLOR */
+ case 0xFFE20078: return 2520;
+ case 0xFFBF006A: return 2521;
+ /* case 0xFFEE71A1: break; NOTE: N/A COLOR */
+ case 0xFFF189AF: return 2550;
+ /* case 0xFFF7B4CA: break; NOTE: N/A COLOR */
+ case 0xFFF7B4CA: return 2560;
+ case 0xFF494949: return 2576;
+ /* case 0xFF394248: break; NOTE: N/A COLOR */
+ case 0xFF893480: return 2600;
+ case 0xFF6C0051: return 2611;
+ /* case 0xFFCD73A6: break; NOTE: N/A COLOR */
+ case 0xFFD994B9: return 2640;
+ /* case 0xFFDDBDD5: break; NOTE: N/A COLOR */
+ case 0xFFE6B7CF: return 2650;
+ case 0xFFECD2DE: return 2655;
+ case 0xFF606D8C: return 2674;
+ /* case 0xFF646A6E: break; NOTE: N/A COLOR */
+ case 0xFF610051: return 2711;
+ /* case 0xFF704191: break; NOTE: N/A COLOR */
+ case 0xFF490251: return 2715;
+ case 0xFF89347F: return 2720;
+ /* case 0xFF2F206F: break; NOTE: N/A COLOR */
+ case 0xFFC690A1: return 2764;
+ case 0xFF6F067B: return 2810;
+ /* case 0xFFAD85B1: break; NOTE: N/A COLOR */
+ case 0xFFA974AB: return 2830;
+ case 0xFF4C0F7B: return 2900;
+ case 0xFF664090: return 2905;
+ case 0xFF83589D: return 2910;
+ case 0xFF8C6DAA: return 2920;
+ case 0xFFC9B5D4: return 3040;
+ case 0xFFC790BA: return 3045;
+ case 0xFF707070: return 3062;
+ case 0xFF2A377E: return 3102;
+ /* case 0xFF3C1F81: break; NOTE: N/A COLOR */
+ case 0xFF35247A: return 3110;
+ case 0xFF260751: return 3114;
+ /* case 0xFF28135B: break; NOTE: N/A COLOR */
+ /* case 0xFF6E5DA3: break; NOTE: N/A COLOR */
+ case 0xFF353A90: return 3210;
+ case 0xFF524A90: return 3211;
+ /* case 0xFF785FA3: break; NOTE: N/A COLOR */
+ /* case 0xFF241757: break; NOTE: N/A COLOR */
+ case 0xFF7D77AF: return 3241;
+ case 0xFF9083A3: return 3251;
+ /* case 0xFFB2AABD: break; NOTE: N/A COLOR */
+ /* case 0xFF392D88: break; NOTE: N/A COLOR */
+ /* case 0xFF5661A8: break; NOTE: N/A COLOR */
+ /* case 0xFF323887: break; NOTE: N/A COLOR */
+ case 0xFF14214E: return 3323;
+ /* case 0xFF3A2885: break; NOTE: N/A COLOR */
+ case 0xFF7F8BC2: return 3331;
+ case 0xFF1B3C78: return 3333;
+ case 0xFF2E4B9B: return 3335;
+ /* case 0xFFB9BDD9: break; NOTE: N/A COLOR */
+ case 0xFF11263C: return 3344;
+ case 0xFF202A65: return 3353;
+ case 0xFF171B4A: return 3355;
+ /* case 0xFF959ACA: break; NOTE: N/A COLOR */
+ /* case 0xFF6A76B5: break; NOTE: N/A COLOR */
+ /* case 0xFF11263C: break; NOTE: N/A COLOR */
+ case 0xFF002232: return 3444;
+ case 0xFF2D4491: return 3522;
+ case 0xFF261257: return 3536;
+ /* case 0xFF53428A: break; NOTE: N/A COLOR */
+ case 0xFF3A2885: return 3541;
+ case 0xFF233B7D: return 3543;
+ case 0xFF273C82: return 3544;
+ case 0xFF272651: return 3554;
+ case 0xFF28438C: return 3600;
+ case 0xFF243A7D: return 3611;
+ case 0xFF4055A1: return 3612;
+ case 0xFF1A4C8D: return 3622;
+ /* case 0xFF1E569F: break; NOTE: N/A COLOR */
+ case 0xFF92B1DC: return 3640;
+ case 0xFF648DC7: return 3641;
+ case 0xFFD0DEEE: return 3650;
+ case 0xFFC8D6ED: return 3652;
+ /* case 0xFFEAF0F9: break; NOTE: N/A COLOR */
+ case 0xFF00507F: return 3732;
+ case 0xFF12253C: return 3743;
+ case 0xFFB7D1E3: return 3750;
+ /* case 0xFFD0DEEE: break; NOTE: N/A COLOR */
+ case 0xFFAFC9E5: return 3761;
+ case 0xFFCED2D1: return 3770;
+ case 0xFF3D6AA1: return 3810;
+ case 0xFF7BA2D3: return 3815;
+ case 0xFF91B9E2: return 3820;
+ /* case 0xFF00779E: break; NOTE: N/A COLOR */
+ case 0xFFB4CEEB: return 3840;
+ case 0xFF507193: return 3842;
+ /* case 0xFFD5E3F4: break; NOTE: N/A COLOR */
+ /* case 0xFF9AB8D3: break; NOTE: N/A COLOR */
+ case 0xFF007EBA: return 3900;
+ case 0xFF0082C4: return 3901;
+ case 0xFF006CA5: return 3902;
+ case 0xFF4ABDF0: return 3910;
+ case 0xFF86AACA: return 3951;
+ /* case 0xFF485E8A: break; NOTE: N/A COLOR */
+ case 0xFF697698: return 3953;
+ /* case 0xFFC5E1F3: break; NOTE: N/A COLOR */
+ case 0xFFA6D8F6: return 3962;
+ case 0xFFE1E1E1: return 3971;
+ case 0xFF0093B9: return 4010;
+ /* case 0xFF006587: break; NOTE: N/A COLOR */
+ /* case 0xFF87C7EA: break; NOTE: N/A COLOR */
+ case 0xFF507793: return 4032;
+ case 0xFF265674: return 4033;
+ /* case 0xFF9ED4E6: break; NOTE: N/A COLOR */
+ case 0xFFEAF0F9: return 4071;
+ case 0xFF838689: return 4073;
+ /* case 0xFF0096C1: break; NOTE: N/A COLOR */
+ case 0xFF2DB0CF: return 4101;
+ case 0xFF0095C6: return 4103;
+ /* case 0xFF0081AA: break; NOTE: N/A COLOR */
+ case 0xFF00A4D9: return 4111;
+ case 0xFF00A9C9: return 4113;
+ case 0xFF0082AD: return 4116;
+ /* case 0xFF5DBFD2: break; NOTE: N/A COLOR */
+ case 0xFF00405D: return 4133;
+ /* case 0xFF192024: return 4174; TODO: duplicate case value */
+ /* case 0xFF192024: break; NOTE: N/A COLOR */
+ case 0xFF4FB4CB: return 4220;
+ case 0xFF8DCEE4: return 4230;
+ /* case 0xFF2DB0CF: break; NOTE: N/A COLOR */
+ /* case 0xFF006587: break; NOTE: N/A COLOR */
+ case 0xFF8DCDDB: return 4240;
+ case 0xFFD5EBF2: return 4250;
+ /* case 0xFF007389: break; NOTE: N/A COLOR */
+ case 0xFF007B8D: return 4410;
+ /* case 0xFF00B2CA: break; NOTE: N/A COLOR */
+ case 0xFF0091A5: return 4421;
+ case 0xFF007D8C: return 4423;
+ case 0xFF007986: return 4425;
+ case 0xFF5FBFD1: return 4430;
+ /* case 0xFF004250: break; NOTE: N/A COLOR */
+ /* case 0xFF8DCEE4: break; NOTE: N/A COLOR */
+ case 0xFF006981: return 4442;
+ case 0xFF007F92: return 4452;
+ /* case 0xFF008192: break; NOTE: N/A COLOR */
+ /* case 0xFF007079: break; NOTE: N/A COLOR */
+ case 0xFF002F38: return 4515;
+ /* case 0xFF00646A: break; NOTE: N/A COLOR */
+ case 0xFF007389: return 4531;
+ /* case 0xFF007B8D: return 4610; TODO: duplicate case value */
+ case 0xFF00A3A0: return 4620;
+ case 0xFF0B7F85: return 4625;
+ case 0xFF005B63: return 4643;
+ case 0xFF234544: return 4644;
+ /* case 0xFF8CCDD3: break; NOTE: N/A COLOR */
+ /* case 0xFF006F73: break; NOTE: N/A COLOR */
+ /* case 0xFF005B63: return 5005; TODO: duplicate case value */
+ case 0xFF00A6AD: return 5010;
+ /* case 0xFF49BAC0: break; NOTE: N/A COLOR */
+ /* case 0xFFCFDDE0: break; NOTE: N/A COLOR */
+ case 0xFFB4DCD8: return 5050;
+ case 0xFF00876E: return 5100;
+ case 0xFF009084: return 5101;
+ /* case 0xFF00B1AE: break; NOTE: N/A COLOR */
+ case 0xFF48BAB7: return 5115;
+ case 0xFF00AF8C: return 5210;
+ case 0xFF8CCCC2: return 5220;
+ case 0xFF47B9AE: return 5230;
+ case 0xFF197E6D: return 5233;
+ /* case 0xFF8CCCC2: break; NOTE: N/A COLOR */
+ /* case 0xFF005B63: break; NOTE: N/A COLOR */
+ case 0xFF006E42: return 5324;
+ case 0xFF004D3D: return 5326;
+ /* case 0xFF002F38: return 5335; TODO: duplicate case value */
+ case 0xFF002D1F: return 5374;
+ /* case 0xFF002F38: break; NOTE: N/A COLOR */
+ case 0xFF008663: return 5411;
+ case 0xFF006B4E: return 5415;
+ /* case 0xFF008663: return 5422; TODO: duplicate case value */
+ /* case 0xFF006B56: break; NOTE: N/A COLOR */
+ /* case 0xFF008879: break; NOTE: N/A COLOR */
+ /* case 0xFFDBE9E5: break; NOTE: N/A COLOR */
+ /* case 0xFF6AC093: break; NOTE: N/A COLOR */
+ case 0xFF52BA84: return 5500;
+ case 0xFF14A363: return 5510;
+ case 0xFF007848: return 5513;
+ /* case 0xFF008663: return 5515; TODO: duplicate case value */
+ case 0xFF52A04F: return 5531;
+ /* case 0xFF6EA293: break; NOTE: N/A COLOR */
+ case 0xFF94ADA1: return 5552;
+ case 0xFF103828: return 5555;
+ /* case 0xFF63BE5F: break; NOTE: N/A COLOR */
+ case 0xFF85C875: return 5610;
+ /* case 0xFF2CB431: break; NOTE: N/A COLOR */
+ case 0xFF14B26D: return 5613;
+ /* case 0xFF40B780: break; NOTE: N/A COLOR */
+ case 0xFF1A781E: return 5633;
+ case 0xFF157436: return 5643;
+ case 0xFFC9E3C5: return 5650;
+ case 0xFF6B9181: return 5664;
+ /* case 0xFF3A6D57: break; NOTE: N/A COLOR */
+ /* case 0xFF103828: break; NOTE: N/A COLOR */
+ /* case 0xFF02140C: break; NOTE: N/A COLOR */
+ case 0xFFA5C278: return 5822;
+ /* case 0xFFB4D383: break; NOTE: N/A COLOR */
+ case 0xFF70953F: return 5833;
+ /* case 0xFFA2D289: break; NOTE: N/A COLOR */
+ case 0xFF273014: return 5866;
+ case 0xFF81C750: return 5912;
+ case 0xFF457021: return 5933;
+ case 0xFF506702: return 5934;
+ case 0xFFBBDB41: return 5940;
+ case 0xFF003518: return 5944;
+ case 0xFFE3EB00: return 6010;
+ case 0xFFBED782: return 6051;
+ /* case 0xFF2D3B01: break; NOTE: N/A COLOR */
+ /* case 0xFFDCDDD1: break; NOTE: N/A COLOR */
+ case 0xFF919600: return 6133;
+ case 0xFF484601: return 6156;
+ }
+
+ return -1;
+}
+
+const char* getName_Isacord_Polyester(unsigned int color) { return ""; } /*TODO: finish */
+
+int getNum_Isafil_Rayon(unsigned int color)
+{
+ switch(color)
+ {
+ case 0xFFFFFFFF: return 10;
+ /* case 0xFFFFFFFF: return 15; TODO: duplicate case value */
+ /* case 0xFFFFFFFF: return 17; TODO: duplicate case value */
+ case 0xFF000000: return 20;
+ case 0xFFFFFDED: return 101;
+ case 0xFF7D7D7D: return 104;
+ case 0xFF515B61: return 107;
+ case 0xFF6D757B: return 108;
+ case 0xFFACACAC: return 109;
+ /* case 0xFF515B61: return 111; TODO: duplicate case value */
+ case 0xFF5D5D5D: return 112;
+ case 0xFFCFCFCF: return 124;
+ case 0xFFA1A9B4: return 131;
+ /* case 0xFF192024: break; NOTE: N/A COLOR */
+ /* case 0xFF6D757B: return 141; TODO: duplicate case value */
+ case 0xFF9EA5AA: return 142;
+ case 0xFFCFD1D5: return 145;
+ case 0xFFC6BDB4: return 150;
+ case 0xFFD5C4B3: return 151;
+ case 0xFF7C8283: return 152;
+ case 0xFF898F94: return 156;
+ case 0xFFFEF5F0: return 180;
+ case 0xFFE9D7D9: return 182;
+ case 0xFFEBE3DD: return 184;
+ case 0xFFE0DA5F: return 221;
+ case 0xFFBFBA28: return 232;
+ case 0xFFECE9C1: return 241;
+ case 0xFFFAF6CC: return 250;
+ case 0xFFECE7A5: return 251;
+ case 0xFFECEADB: return 260;
+ case 0xFFF9F8E8: return 270;
+ case 0xFFFDF76C: return 310;
+ case 0xFFF5D300: return 311;
+ case 0xFF797E24: return 345;
+ case 0xFFB0AA76: return 352;
+ case 0xFF898F2B: return 442;
+ case 0xFF98996D: return 453;
+ case 0xFF6E772E: return 454;
+ case 0xFF6B7E6F: return 463;
+ case 0xFF3E4F34: return 465;
+ case 0xFFEDEF05: return 501;
+ /* case 0xFFFAF6CC: return 505; TODO: duplicate case value */
+ /* case 0xFFF5D300: return 506; TODO: duplicate case value */
+ case 0xFFFFFBD1: return 510;
+ case 0xFFFDE896: return 520;
+ case 0xFFD7CE8A: return 532;
+ case 0xFFB18B00: return 542;
+ case 0xFFAA8D00: return 545;
+ case 0xFFB28F11: return 546;
+ case 0xFFAC9436: return 551;
+ case 0xFFB69F56: return 552;
+ case 0xFFF4EE8C: return 580;
+ case 0xFFF1EB35: return 590;
+ case 0xFFF8D73E: return 600;
+ /* case 0xFFF8D73E: return 605; TODO: duplicate case value */
+ /* case 0xFFF7DC00: break; NOTE: N/A COLOR */
+ case 0xFFF7CB47: return 610;
+ case 0xFFF7E400: return 615;
+ /* case 0xFFFDE896: return 620; TODO: duplicate case value */
+ case 0xFFEEDB00: return 625;
+ case 0xFFFEF09A: return 630;
+ case 0xFFFDE1AF: return 635;
+ /* case 0xFFFDE896: return 640; TODO: duplicate case value */
+ case 0xFFF5D2A6: return 651;
+ case 0xFFFEF9EA: return 660;
+ case 0xFFFAF6E7: return 670;
+ case 0xFFBEBEA8: return 672;
+ case 0xFFF7C35F: return 700;
+ case 0xFFF5CA00: return 702;
+ case 0xFFDFA200: return 704;
+ case 0xFFFCF538: return 706;
+ case 0xFFFADC59: return 713;
+ case 0xFF8C7E6A: return 722;
+ case 0xFF827000: return 726;
+ case 0xFF636254: return 732;
+ case 0xFF594900: return 747;
+ case 0xFFD6BF94: return 761;
+ case 0xFF656452: return 776;
+ case 0xFFF1AF00: return 800;
+ case 0xFFF3C200: return 805;
+ case 0xFFF5BA5D: return 811;
+ case 0xFFE1A23E: return 821;
+ case 0xFFCCAB3F: return 822;
+ /* case 0xFFDFA200: return 824; TODO: duplicate case value */
+ case 0xFFF3B044: return 830;
+ case 0xFFD0A44F: return 832;
+ case 0xFFCD944A: return 842;
+ case 0xFFE3BC61: return 851;
+ case 0xFF947C4A: return 853;
+ /* case 0xFFCBBFA2: break; NOTE: N/A COLOR */
+ /* case 0xFFA5866A: break; NOTE: N/A COLOR */
+ case 0xFF001F48: return 866;
+ case 0xFFEBE7DD: return 870;
+ case 0xFF9FA086: return 873;
+ case 0xFF9A897B: return 874;
+ case 0xFFEE9C00: return 900;
+ case 0xFFF3B259: return 904;
+ case 0xFFCA832C: return 922;
+ case 0xFFC07314: return 931;
+ case 0xFFAC6613: return 932;
+ case 0xFF744808: return 933;
+ case 0xFFBD9565: return 934;
+ case 0xFF806800: return 936;
+ case 0xFFC98300: return 940;
+ case 0xFFAF7D3E: return 941;
+ case 0xFF483928: return 945;
+ case 0xFFFEECD9: return 961;
+ case 0xFFFEFEED: return 970;
+ case 0xFFDD973A: return 1041;
+ case 0xFF6A4129: return 1055;
+ case 0xFFFDE2C1: return 1060;
+ case 0xFFA68A68: return 1061;
+ case 0xFFD76814: return 1099;
+ case 0xFFED873F: return 1100;
+ case 0xFFEC870E: return 1101;
+ case 0xFFED9206: return 1102;
+ /* case 0xFFEE9C00: return 1106; TODO: duplicate case value */
+ case 0xFFC45331: return 1113;
+ case 0xFFEE8751: return 1114;
+ case 0xFFA35214: return 1115;
+ case 0xFFF8C000: return 1120;
+ case 0xFFB7976B: return 1123;
+ case 0xFF9D5A21: return 1134;
+ case 0xFFF3D8A8: return 1140;
+ case 0xFFFACFAE: return 1141;
+ /* case 0xFF7A4427: break; NOTE: N/A COLOR */
+ case 0xFFDFC8AB: return 1172;
+ case 0xFFE89763: return 1211;
+ case 0xFFF1A236: return 1220;
+ case 0xFF3D2723: return 1276;
+ case 0xFFE5571D: return 1300;
+ /* case 0xFFD9674C: break; NOTE: N/A COLOR */
+ case 0xFFE8643C: return 1302;
+ case 0xFFE4501E: return 1304;
+ case 0xFFEA7134: return 1305;
+ case 0xFFE12A23: return 1306;
+ case 0xFFC14817: return 1311;
+ /* case 0xFFC45331: return 1312; TODO: duplicate case value */
+ case 0xFFD7623E: return 1313;
+ case 0xFFED7C56: return 1320;
+ case 0xFF92291B: return 1324;
+ case 0xFFD5815E: return 1332;
+ case 0xFFBB3D2E: return 1334;
+ case 0xFFBE2D1A: return 1335;
+ case 0xFF5F1B23: return 1342;
+ case 0xFF7A3441: return 1346;
+ case 0xFF84291D: return 1348;
+ case 0xFFFBBF95: return 1351;
+ case 0xFFF4A773: return 1352;
+ case 0xFF693920: return 1355;
+ case 0xFFF9C6A1: return 1361;
+ case 0xFFF9C598: return 1362;
+ case 0xFF432731: return 1366;
+ case 0xFF464537: return 1375;
+ case 0xFF4D2E18: return 1376;
+ case 0xFFD64F42: return 1421;
+ case 0xFFF4A782: return 1430;
+ case 0xFFE22D2A: return 1501;
+ case 0xFFA93121: return 1514;
+ case 0xFFEC7168: return 1521;
+ case 0xFFF6B08E: return 1532;
+ case 0xFFF9C5B9: return 1551;
+ case 0xFF806A61: return 1565;
+ /* case 0xFF464537: return 1573; TODO: duplicate case value */
+ case 0xFFE36C63: return 1600;
+ case 0xFFF9C7B9: return 1630;
+ case 0xFFE44733: return 1701;
+ case 0xFFDF0032: return 1703;
+ /* case 0xFFE0003D: break; NOTE: N/A COLOR */
+ /* case 0xFFE44733: return 1705; TODO: duplicate case value */
+ case 0xFFCF0040: return 1725;
+ case 0xFFDB686B: return 1750;
+ case 0xFFF1CDCE: return 1755;
+ case 0xFFE9C9BD: return 1760;
+ case 0xFFE8C0B8: return 1761;
+ case 0xFFE00046: return 1800;
+ case 0xFFE43449: return 1802;
+ case 0xFFD6445D: return 1805;
+ case 0xFFF49E95: return 1840;
+ case 0xFFB76663: return 1842;
+ /* case 0xFFE36C63: return 1849; TODO: duplicate case value */
+ case 0xFFF0887D: return 1850;
+ case 0xFFFAC7C1: return 1855;
+ case 0xFFFCDAD5: return 1860;
+ case 0xFFFDE3D3: return 1870;
+ /* case 0xFF636254: return 1874; TODO: duplicate case value */
+ case 0xFF394535: return 1876;
+ case 0xFFE10057: return 1900;
+ case 0xFFBD0041: return 1902;
+ case 0xFFC00343: return 1903;
+ case 0xFFA9023A: return 1904;
+ case 0xFF960018: return 1905;
+ case 0xFFBE004F: return 1906;
+ case 0xFF910230: return 1911;
+ case 0xFF86023E: return 1912;
+ case 0xFF9A0C3B: return 1913;
+ case 0xFFA41F39: return 1914;
+ case 0xFFA33050: return 1921;
+ case 0xFFF28DA6: return 1940;
+ case 0xFFCE427A: return 1950;
+ case 0xFFF2B9BE: return 1960;
+ case 0xFF959595: return 1972;
+ case 0xFFA33145: return 2011;
+ case 0xFF9F454C: return 2022;
+ case 0xFFC7979B: return 2051;
+ case 0xFFD18D89: return 2053;
+ case 0xFF970038: return 2100;
+ case 0xFF9F003F: return 2101;
+ case 0xFF78093F: return 2113;
+ /* case 0xFF6D0627: break; NOTE: N/A COLOR */
+ case 0xFF432732: return 2123;
+ case 0xFFE6778B: return 2152;
+ case 0xFFDF8390: return 2153;
+ case 0xFFF9BFC0: return 2155;
+ case 0xFFFBD1D6: return 2160;
+ case 0xFFFDE3DB: return 2165;
+ case 0xFFD8D5D0: return 2166;
+ case 0xFFFEEDE2: return 2168;
+ case 0xFFF7DED6: return 2170;
+ case 0xFFF7DEDE: return 2171;
+ case 0xFFFCD9C4: return 2180;
+ case 0xFFE8418C: return 2220;
+ case 0xFF8C0C4A: return 2222;
+ case 0xFF883A40: return 2224;
+ case 0xFFEE71A1: return 2230;
+ case 0xFFA95A68: return 2241;
+ case 0xFFFAC8D3: return 2250;
+ case 0xFFD3007E: return 2300;
+ case 0xFFBF006A: return 2310;
+ case 0xFFD20067: return 2320;
+ case 0xFF780C38: return 2332;
+ case 0xFF651533: return 2333;
+ case 0xFF3A212B: return 2336;
+ case 0xFFF2E0DC: return 2360;
+ case 0xFFFDE5EC: return 2363;
+ case 0xFF970059: return 2500;
+ case 0xFF8B1771: return 2502;
+ case 0xFFAA4381: return 2504;
+ case 0xFFB40073: return 2505;
+ case 0xFF820052: return 2506;
+ case 0xFFD63C81: return 2513;
+ case 0xFFE20078: return 2520;
+ /* case 0xFFBF006A: return 2521; TODO: duplicate case value */
+ /* case 0xFFEE71A1: return 2524; TODO: duplicate case value */
+ case 0xFFF189AF: return 2550;
+ case 0xFFF7B4CA: return 2555;
+ /* case 0xFFF7B4CA: return 2560; TODO: duplicate case value */
+ case 0xFF494949: return 2576;
+ case 0xFF394248: return 2578;
+ case 0xFF893480: return 2600;
+ case 0xFF6C0051: return 2611;
+ case 0xFFCD73A6: return 2620;
+ case 0xFFD994B9: return 2640;
+ case 0xFFDDBDD5: return 2645;
+ case 0xFFE6B7CF: return 2650;
+ case 0xFFECD2DE: return 2655;
+ case 0xFF606D8C: return 2674;
+ case 0xFF646A6E: return 2675;
+ case 0xFF610051: return 2711;
+ case 0xFF704191: return 2712;
+ case 0xFF490251: return 2715;
+ /* case 0xFF89347F: break; NOTE: N/A COLOR */
+ case 0xFF2F206F: return 2743;
+ case 0xFFC690A1: return 2764;
+ case 0xFF6F067B: return 2810;
+ case 0xFFAD85B1: return 2820;
+ case 0xFFA974AB: return 2830;
+ case 0xFF4C0F7B: return 2900;
+ case 0xFF664090: return 2905;
+ case 0xFF83589D: return 2910;
+ case 0xFF8C6DAA: return 2920;
+ case 0xFFC9B5D4: return 3040;
+ case 0xFFC790BA: return 3045;
+ case 0xFF707070: return 3062;
+ case 0xFF2A377E: return 3102;
+ case 0xFF3C1F81: return 3103;
+ case 0xFF35247A: return 3110;
+ case 0xFF260751: return 3114;
+ case 0xFF28135B: return 3133;
+ case 0xFF6E5DA3: return 3200;
+ case 0xFF353A90: return 3210;
+ case 0xFF524A90: return 3211;
+ case 0xFF785FA3: return 3213;
+ case 0xFF241757: return 3222;
+ case 0xFF7D77AF: return 3241;
+ case 0xFF9083A3: return 3251;
+ case 0xFFB2AABD: return 3262;
+ case 0xFF392D88: return 3301;
+ case 0xFF5661A8: return 3321;
+ case 0xFF323887: return 3322;
+ case 0xFF14214E: return 3323;
+ case 0xFF3A2885: return 3330;
+ case 0xFF7F8BC2: return 3331;
+ case 0xFF1B3C78: return 3333;
+ /* case 0xFF2E4B9B: break; NOTE: N/A COLOR */
+ case 0xFFB9BDD9: return 3340;
+ case 0xFF11263C: return 3344;
+ case 0xFF202A65: return 3353;
+ case 0xFF171B4A: return 3355;
+ case 0xFF959ACA: return 3420;
+ case 0xFF6A76B5: return 3430;
+ /* case 0xFF11263C: return 3443; TODO: duplicate case value */
+ case 0xFF002232: return 3444;
+ case 0xFF2D4491: return 3522;
+ case 0xFF261257: return 3536;
+ case 0xFF53428A: return 3540;
+ /* case 0xFF3A2885: return 3541; TODO: duplicate case value */
+ case 0xFF233B7D: return 3543;
+ case 0xFF273C82: return 3544;
+ case 0xFF272651: return 3554;
+ case 0xFF28438C: return 3600;
+ case 0xFF243A7D: return 3611;
+ case 0xFF4055A1: return 3612;
+ case 0xFF1A4C8D: return 3622;
+ case 0xFF1E569F: return 3631;
+ case 0xFF92B1DC: return 3640;
+ case 0xFF648DC7: return 3641;
+ case 0xFFD0DEEE: return 3650;
+ /* case 0xFFC8D6ED: break; NOTE: N/A COLOR */
+ case 0xFFEAF0F9: return 3661;
+ case 0xFF00507F: return 3732;
+ case 0xFF12253C: return 3743;
+ case 0xFFB7D1E3: return 3750;
+ /* case 0xFFD0DEEE: return 3752; TODO: duplicate case value */
+ case 0xFFAFC9E5: return 3761;
+ case 0xFFCED2D1: return 3770;
+ case 0xFF3D6AA1: return 3810;
+ /* case 0xFF7BA2D3: break; NOTE: N/A COLOR */
+ case 0xFF91B9E2: return 3820;
+ case 0xFF00779E: return 3822;
+ case 0xFFB4CEEB: return 3840;
+ case 0xFF507193: return 3842;
+ case 0xFFD5E3F4: return 3845;
+ case 0xFF9AB8D3: return 3851;
+ case 0xFF007EBA: return 3900;
+ case 0xFF0082C4: return 3901;
+ case 0xFF006CA5: return 3902;
+ case 0xFF4ABDF0: return 3910;
+ case 0xFF86AACA: return 3951;
+ case 0xFF485E8A: return 3952;
+ case 0xFF697698: return 3953;
+ case 0xFFC5E1F3: return 3961;
+ case 0xFFA6D8F6: return 3962;
+ case 0xFFE1E1E1: return 3971;
+ case 0xFF0093B9: return 4010;
+ case 0xFF006587: return 4022;
+ case 0xFF87C7EA: return 4030;
+ case 0xFF507793: return 4032;
+ case 0xFF265674: return 4033;
+ case 0xFF9ED4E6: return 4040;
+ /* case 0xFFEAF0F9: return 4071; TODO: duplicate case value */
+ /* case 0xFF838689: break; NOTE: N/A COLOR */
+ case 0xFF0096C1: return 4100;
+ case 0xFF2DB0CF: return 4101;
+ case 0xFF0095C6: return 4103;
+ case 0xFF0081AA: return 4105;
+ case 0xFF00A4D9: return 4111;
+ case 0xFF00A9C9: return 4113;
+ /* case 0xFF0082AD: break; NOTE: N/A COLOR */
+ case 0xFF5DBFD2: return 4121;
+ case 0xFF00405D: return 4133;
+ /* case 0xFF192024: return 4174; TODO: duplicate case value */
+ /* case 0xFF192024: return 4175; TODO: duplicate case value */
+ case 0xFF4FB4CB: return 4220;
+ case 0xFF8DCEE4: return 4230;
+ /* case 0xFF2DB0CF: return 4231; TODO: duplicate case value */
+ /* case 0xFF006587: return 4232; TODO: duplicate case value */
+ case 0xFF8DCDDB: return 4240;
+ case 0xFFD5EBF2: return 4250;
+ case 0xFF007389: return 4400;
+ case 0xFF007B8D: return 4410;
+ case 0xFF00B2CA: return 4420;
+ case 0xFF0091A5: return 4421;
+ case 0xFF007D8C: return 4423;
+ case 0xFF007986: return 4425;
+ case 0xFF5FBFD1: return 4430;
+ case 0xFF004250: return 4432;
+ /* case 0xFF8DCEE4: return 4440; TODO: duplicate case value */
+ case 0xFF006981: return 4442;
+ case 0xFF007F92: return 4452;
+ case 0xFF008192: return 4500;
+ case 0xFF007079: return 4513;
+ case 0xFF002F38: return 4515;
+ case 0xFF00646A: return 4516;
+ /* case 0xFF007389: return 4531; TODO: duplicate case value */
+ /* case 0xFF007B8D: return 4610; TODO: duplicate case value */
+ case 0xFF00A3A0: return 4620;
+ case 0xFF0B7F85: return 4625;
+ case 0xFF005B63: return 4643;
+ case 0xFF234544: return 4644;
+ case 0xFF8CCDD3: return 4840;
+ case 0xFF006F73: return 5000;
+ /* case 0xFF005B63: return 5005; TODO: duplicate case value */
+ case 0xFF00A6AD: return 5010;
+ case 0xFF49BAC0: return 5020;
+ case 0xFFCFDDE0: return 5040;
+ case 0xFFB4DCD8: return 5050;
+ case 0xFF00876E: return 5100;
+ case 0xFF009084: return 5101;
+ case 0xFF00B1AE: return 5111;
+ case 0xFF48BAB7: return 5115;
+ case 0xFF00AF8C: return 5210;
+ case 0xFF8CCCC2: return 5220;
+ case 0xFF47B9AE: return 5230;
+ case 0xFF197E6D: return 5233;
+ /* case 0xFF8CCCC2: return 5240; TODO: duplicate case value */
+ /* case 0xFF005B63: return 5255; TODO: duplicate case value */
+ case 0xFF006E42: return 5324;
+ case 0xFF004D3D: return 5326;
+ /* case 0xFF002F38: return 5335; TODO: duplicate case value */
+ case 0xFF002D1F: return 5374;
+ /* case 0xFF002F38: return 5375; TODO: duplicate case value */
+ case 0xFF008663: return 5411;
+ case 0xFF006B4E: return 5415;
+ /* case 0xFF008663: return 5422; TODO: duplicate case value */
+ case 0xFF006B56: return 5425;
+ case 0xFF008879: return 5431;
+ case 0xFFDBE9E5: return 5460;
+ case 0xFF6AC093: return 5470;
+ case 0xFF52BA84: return 5500;
+ case 0xFF14A363: return 5510;
+ case 0xFF007848: return 5513;
+ /* case 0xFF008663: return 5515; TODO: duplicate case value */
+ case 0xFF52A04F: return 5531;
+ case 0xFF6EA293: return 5542;
+ case 0xFF94ADA1: return 5552;
+ case 0xFF103828: return 5555;
+ case 0xFF63BE5F: return 5600;
+ case 0xFF85C875: return 5610;
+ case 0xFF2CB431: return 5611;
+ case 0xFF14B26D: return 5613;
+ case 0xFF40B780: return 5620;
+ case 0xFF1A781E: return 5633;
+ case 0xFF157436: return 5643;
+ case 0xFFC9E3C5: return 5650;
+ case 0xFF6B9181: return 5664;
+ case 0xFF3A6D57: return 5765;
+ /* case 0xFF103828: return 5766; TODO: duplicate case value */
+ case 0xFF02140C: return 5776;
+ case 0xFFA5C278: return 5822;
+ case 0xFFB4D383: return 5832;
+ case 0xFF70953F: return 5833;
+ case 0xFFA2D289: return 5840;
+ case 0xFF273014: return 5866;
+ case 0xFF81C750: return 5912;
+ case 0xFF457021: return 5933;
+ case 0xFF506702: return 5934;
+ case 0xFFBBDB41: return 5940;
+ case 0xFF003518: return 5944;
+ case 0xFFE3EB00: return 6010;
+ case 0xFFBED782: return 6051;
+ case 0xFF2D3B01: return 6065;
+ case 0xFFDCDDD1: return 6071;
+ case 0xFF919600: return 6133;
+ case 0xFF484601: return 6156;
+ }
+
+ return -1;
+}
+
+const char* getName_Isafil_Rayon(unsigned int color) { return ""; } /*TODO: finish */
+
+int getNum_Marathon_Polyester(unsigned int color) { return -1; } /*TODO: finish */
+const char* getName_Marathon_Polyester(unsigned int color) { return ""; } /*TODO: finish */
+
+int getNum_Marathon_Rayon(unsigned int color) { return -1; } /*TODO: finish */
+const char* getName_Marathon_Rayon(unsigned int color) { return ""; } /*TODO: finish */
+
+int getNum_Madeira_Polyester(unsigned int color) { return -1; } /*TODO: finish */
+const char* getName_Madeira_Polyester(unsigned int color) { return ""; } /*TODO: finish */
+
+int getNum_Madeira_Rayon(unsigned int color) { return -1; } /*TODO: finish */
+const char* getName_Madeira_Rayon(unsigned int color) { return ""; } /*TODO: finish */
+
+int getNum_Metro_Polyester(unsigned int color) { return -1; } /*TODO: finish */
+const char* getName_Metro_Polyester(unsigned int color) { return ""; } /*TODO: finish */
+
+int getNum_Pantone(unsigned int color)
+{
+ switch(color)
+ {
+ /* case 0xFFF7E214: return "Process Yellow"; NOTE: N/A COLOR */
+ case 0xFFFFFF7D: return 100;
+ case 0xFFFFFF36: return 101;
+ case 0xFFFFFC0D: return 102;
+ /* case 0xFFFCE016: return "Pantone Yellow"; NOTE: N/A COLOR */
+ case 0xFFD1CB00: return 103;
+ case 0xFFB3AD00: return 104;
+ case 0xFF807C00: return 105;
+ case 0xFFFFFA4F: return 106;
+ case 0xFFFFF536: return 107;
+ case 0xFFFFF00D: return 108;
+ case 0xFFFFE600: return 109;
+ case 0xFFEDD100: return 110;
+ case 0xFFBAA600: return 111;
+ case 0xFF9E8E00: return 112;
+ case 0xFFFFED57: return 113;
+ case 0xFFFFEB45: return 114;
+ case 0xFFFFE833: return 115;
+ case 0xFFFFD600: return 116;
+ case 0xFFD9B200: return 117;
+ case 0xFFBA9900: return 118;
+ case 0xFF827200: return 119;
+ case 0xFFFFE86B: return 120;
+ case 0xFFFFF2B0: return 1205;
+ case 0xFFFFE34F: return 121;
+ case 0xFFFFE88C: return 1215;
+ case 0xFFFFD433: return 122;
+ case 0xFFFFD461: return 1225;
+ case 0xFFFFC20F: return 123;
+ case 0xFFFFB517: return 1235;
+ case 0xFFF0AD00: return 124;
+ case 0xFFD19700: return 1245;
+ case 0xFFBD8C00: return 125;
+ case 0xFFA87B00: return 1255;
+ case 0xFFA17800: return 126;
+ case 0xFF7D5B00: return 1265;
+ case 0xFFFFED80: return 127;
+ case 0xFFFFE359: return 128;
+ case 0xFFFFD63B: return 129;
+ case 0xFFFFB300: return 130;
+ case 0xFFE89E00: return 131;
+ case 0xFFB38100: return 132;
+ case 0xFF705A00: return 133;
+ case 0xFFFFE38C: return 134;
+ case 0xFFFFDB87: return 1345;
+ case 0xFFFFCF66: return 135;
+ case 0xFFFFCC70: return 1355;
+ case 0xFFFFBA3D: return 136;
+ case 0xFFFFB547: return 1365;
+ case 0xFFFFA61A: return 137;
+ case 0xFFFF991A: return 1375;
+ case 0xFFFC9200: return 138;
+ case 0xFFED8500: return 1385;
+ case 0xFFC47C00: return 139;
+ case 0xFFA15F00: return 1395;
+ case 0xFF755600: return 140;
+ case 0xFF5E3C00: return 1405;
+ case 0xFFFFCF7D: return 141;
+ case 0xFFFFB83D: return 142;
+ case 0xFFFFA626: return 143;
+ case 0xFFFF8500: return 144;
+ case 0xFFEB7C00: return 145;
+ case 0xFFAB6100: return 146;
+ case 0xFF705100: return 147;
+ case 0xFFFFD6A1: return 148;
+ case 0xFFFFBA75: return 1485;
+ case 0xFFFFC487: return 149;
+ case 0xFFFFAB54: return 1495;
+ case 0xFFFFA64D: return 150;
+ case 0xFFFF943B: return 1505;
+ /* case 0xFFEF6B00: return "Orange 021"; NOTE: N/A COLOR */
+ case 0xFFFF850D: return 151;
+ case 0xFFFC7C00: return 152;
+ case 0xFFE66000: return 1525;
+ case 0xFFD17100: return 153;
+ case 0xFF9E4A00: return 1535;
+ case 0xFFA85B00: return 154;
+ case 0xFF472200: return 1545;
+ case 0xFFFFE0B8: return 155;
+ case 0xFFFFC7A8: return 1555;
+ case 0xFFFFC794: return 156;
+ case 0xFFFFA882: return 1565;
+ case 0xFFFF914D: return 157;
+ case 0xFFFF8C47: return 1575;
+ case 0xFFFF6308: return 158;
+ case 0xFFFF701A: return 1585;
+ case 0xFFED5100: return 159;
+ case 0xFFF26300: return 1595;
+ case 0xFFAD4200: return 160;
+ case 0xFFB34F00: return 1605;
+ case 0xFF5C2C00: return 161;
+ case 0xFF914000: return 1615;
+ case 0xFFFFD9C7: return 162;
+ case 0xFFFFB0A1: return 1625;
+ case 0xFFFFB08F: return 163;
+ case 0xFFFF9C85: return 1635;
+ case 0xFFFF8A45: return 164;
+ case 0xFFFF8257: return 1645;
+ case 0xFFFF690A: return 165;
+ case 0xFFFF5E17: return 1655;
+ case 0xFFFF5C00: return 166;
+ case 0xFFFF5200: return 1665;
+ case 0xFFD45500: return 167;
+ case 0xFFB83D00: return 1675;
+ case 0xFF692D00: return 168;
+ case 0xFF8F2E00: return 1685;
+ case 0xFFFFCCCC: return 169;
+ case 0xFFFF998F: return 170;
+ case 0xFFFF7852: return 171;
+ case 0xFFFF571F: return 172;
+ case 0xFFF54C00: return 173;
+ case 0xFFA33100: return 174;
+ case 0xFF662400: return 175;
+ case 0xFFFFBFD1: return 176;
+ case 0xFFFF9EC9: return 1765;
+ case 0xFFFFBAE0: return 1767;
+ case 0xFFFF8C99: return 177;
+ case 0xFFFF87B5: return 1775;
+ case 0xFFFF6BA3: return 1777;
+ case 0xFFFF6970: return 178;
+ /* case 0xFFF93F26: return "Warm Red"; NOTE: N/A COLOR */
+ case 0xFFFF5480: return 1785;
+ case 0xFFFF3D66: return 1787;
+ /* case 0xFFEF2B2D: return "Red 032"; NOTE: N/A COLOR */
+ case 0xFFFF291F: return 1788;
+ case 0xFFFF3600: return 179;
+ case 0xFFFF0F00: return 1795;
+ case 0xFFF50002: return 1797;
+ case 0xFFE33000: return 180;
+ case 0xFFC41200: return 1805;
+ case 0xFFB80007: return 1807;
+ case 0xFF872300: return 181;
+ case 0xFF7D0C00: return 1815;
+ case 0xFF570900: return 1817;
+ case 0xFFFFBDE6: return 182;
+ case 0xFFFF8AC9: return 183;
+ case 0xFFFF5296: return 184;
+ case 0xFFFF173D: return 185;
+ case 0xFFF5002F: return 186;
+ case 0xFFCC002B: return 187;
+ case 0xFF800400: return 188;
+ case 0xFFFFA1E6: return 189;
+ case 0xFFFFB8ED: return 1895;
+ case 0xFFFF73C7: return 190;
+ case 0xFFFF96E8: return 1905;
+ case 0xFFFF3D9E: return 191;
+ case 0xFFFF4ACC: return 1915;
+ case 0xFFFF0052: return 192;
+ case 0xFFFF0073: return 1925;
+ case 0xFFDE004B: return 193;
+ case 0xFFF20068: return 1935;
+ case 0xFFAB003E: return 194;
+ case 0xFFCF005B: return 1945;
+ case 0xFF73002E: return 195;
+ case 0xFFA10040: return 1955;
+ case 0xFFFFBFF5: return 196;
+ case 0xFFFF8CE6: return 197;
+ case 0xFFFF38AB: return 198;
+ case 0xFFFF0061: return 199;
+ case 0xFFE00053: return 200;
+ case 0xFFB50043: return 201;
+ case 0xFF910039: return 202;
+ case 0xFFFFA8F7: return 203;
+ case 0xFFFF6BF7: return 204;
+ case 0xFFFF29E8: return 205;
+ case 0xFFF70099: return 206;
+ case 0xFFCF0076: return 207;
+ case 0xFFA10067: return 208;
+ case 0xFF78004F: return 209;
+ case 0xFFFF9CF0: return 210;
+ case 0xFFFF73EB: return 211;
+ case 0xFFFF47E3: return 212;
+ case 0xFFFF0DBA: return 213;
+ case 0xFFEB009B: return 214;
+ case 0xFFBA0079: return 215;
+ case 0xFF82074E: return 216;
+ case 0xFFFFB8FF: return 217;
+ case 0xFFFA63FF: return 218;
+ case 0xFFFC1FFF: return 219;
+ /* case 0xFFD10056: return "Rubine Red"; NOTE: N/A COLOR */
+ case 0xFFD400B8: return 220;
+ case 0xFFB30098: return 221;
+ case 0xFF69005E: return 222;
+ case 0xFFFF8AFF: return 223;
+ case 0xFFFC5EFF: return 224;
+ case 0xFFFC2BFF: return 225;
+ case 0xFFFF00FF: return 226;
+ case 0xFFCF00C0: return 227;
+ case 0xFF960090: return 228;
+ case 0xFF660057: return 229;
+ case 0xFFFFA8FF: return 230;
+ case 0xFFFC7AFF: return 231;
+ case 0xFFF754FF: return 232;
+ /* case 0xFFED0091: return "Rhodamine Red"; NOTE: N/A COLOR */
+ case 0xFFE300FF: return 233;
+ case 0xFFB100BD: return 234;
+ case 0xFF910099: return 235;
+ case 0xFFFCB3FF: return 236;
+ case 0xFFFABAFF: return 2365;
+ case 0xFFF782FF: return 237;
+ case 0xFFE66EFF: return 2375;
+ case 0xFFF05EFF: return 238;
+ case 0xFFCF36FF: return 2385;
+ case 0xFFE336FF: return 239;
+ case 0xFFBA0DFF: return 2395;
+ case 0xFFD10FFF: return 240;
+ case 0xFFA800FF: return 2405;
+ case 0xFFB600FA: return 241;
+ case 0xFF9D00EB: return 2415;
+ case 0xFF750082: return 242;
+ case 0xFF7700BD: return 2425;
+ case 0xFFF2B5FF: return 243;
+ case 0xFFE89EFF: return 244;
+ case 0xFFDB78FF: return 245;
+ case 0xFFB51AFF: return 246;
+ case 0xFFA300FF: return 247;
+ case 0xFF9600FA: return 248;
+ case 0xFF6E00B8: return 249;
+ case 0xFFF2D1FF: return 250;
+ case 0xFFDE9CFF: return 251;
+ case 0xFFC270FF: return 252;
+ /* case 0xFFBF30B5: return "Purple"; NOTE: N/A COLOR */
+ case 0xFF910DFF: return 253;
+ case 0xFF8000FF: return 254;
+ case 0xFF5E00BF: return 255;
+ case 0xFFEDCCFF: return 256;
+ case 0xFFCFA6FF: return 2562;
+ case 0xFFC7ABFF: return 2563;
+ case 0xFFB5A3FF: return 2567;
+ case 0xFFDBA8FF: return 257;
+ case 0xFFB387FF: return 2572;
+ case 0xFFB391FF: return 2573;
+ case 0xFF998CFF: return 2577;
+ case 0xFF913DFF: return 258;
+ case 0xFF8A47FF: return 2582;
+ case 0xFF8A5EFF: return 2583;
+ case 0xFF6957FF: return 2587;
+ case 0xFF5F00D9: return 259;
+ case 0xFF661AFF: return 2592;
+ case 0xFF631CFF: return 2593;
+ case 0xFF2600FF: return 2597;
+ case 0xFF5B00BD: return 260;
+ case 0xFF5C00F7: return 2602;
+ case 0xFF4D00FA: return 2603;
+ case 0xFF2D00ED: return 2607;
+ case 0xFF500099: return 261;
+ case 0xFF4F00DB: return 2612;
+ case 0xFF5000D9: return 2613;
+ case 0xFF2E00D9: return 2617;
+ case 0xFF3F0073: return 262;
+ case 0xFF3C008F: return 2622;
+ case 0xFF4700AD: return 2623;
+ case 0xFF2800B0: return 2627;
+ case 0xFFE6DBFF: return 263;
+ case 0xFFB8BAFF: return 2635;
+ case 0xFFBDB8FF: return 264;
+ case 0xFF99A3FF: return 2645;
+ case 0xFF7570FF: return 265;
+ case 0xFF7582FF: return 2655;
+ case 0xFF361AFF: return 266;
+ case 0xFF6166FF: return 2665;
+ /* case 0xFF6607A5: return "Violet"; NOTE: N/A COLOR */
+ case 0xFF1C00FF: return 267;
+ case 0xFF2800E0: return 268;
+ case 0xFF0900E6: return 2685;
+ case 0xFF2600AB: return 269;
+ case 0xFF0C0082: return 2695;
+ case 0xFFB0BAFF: return 270;
+ case 0xFF99B3FF: return 2705;
+ case 0xFFCFE8FF: return 2706;
+ case 0xFFD4F0FF: return 2707;
+ case 0xFFBDE6FF: return 2708;
+ case 0xFF91A1FF: return 271;
+ case 0xFF6E8CFF: return 2715;
+ case 0xFF8CB5FF: return 2716;
+ case 0xFFB5E0FF: return 2717;
+ case 0xFF5496FF: return 2718;
+ case 0xFF6B85FF: return 272;
+ case 0xFF3B52FF: return 2725;
+ case 0xFF3657FF: return 2726;
+ case 0xFF4A94FF: return 2727;
+ /* case 0xFF380096: return "Blue 072"; NOTE: N/A COLOR */
+ case 0xFF0A4FFF: return 2728;
+ case 0xFF0009EB: return 273;
+ case 0xFF000DFF: return 2735;
+ case 0xFF0017FF: return 2736;
+ case 0xFF0020FA: return 2738;
+ case 0xFF0000B8: return 274;
+ case 0xFF000BD9: return 2745;
+ case 0xFF0012E6: return 2746;
+ case 0xFF001ED9: return 2747;
+ case 0xFF001AD9: return 2748;
+ case 0xFF030091: return 275;
+ case 0xFF0005B3: return 2755;
+ case 0xFF000BB5: return 2756;
+ case 0xFF0020B3: return 2757;
+ case 0xFF0026BD: return 2758;
+ case 0xFF020073: return 276;
+ case 0xFF00048C: return 2765;
+ case 0xFF000887: return 2766;
+ case 0xFF001A75: return 2767;
+ case 0xFF001F8F: return 2768;
+ case 0xFFBAEDFF: return 277;
+ case 0xFF9CDBFF: return 278;
+ case 0xFF52A8FF: return 279;
+ /* case 0xFF0C1C8C: return "Reflex Blue"; NOTE: N/A COLOR */
+ case 0xFF003BD1: return 280;
+ case 0xFF0031AD: return 281;
+ case 0xFF002675: return 282;
+ case 0xFFA6E8FF: return 283;
+ case 0xFF73CFFF: return 284;
+ case 0xFF1C91FF: return 285;
+ case 0xFF0055FA: return 286;
+ case 0xFF0048E0: return 287;
+ case 0xFF0041C4: return 288;
+ case 0xFF00246B: return 289;
+ case 0xFFBFFAFF: return 290;
+ case 0xFF96FAFF: return 2905;
+ case 0xFFABF7FF: return 291;
+ case 0xFF69EDFF: return 2915;
+ case 0xFF82E3FF: return 292;
+ case 0xFF26C2FF: return 2925;
+ case 0xFF006BFA: return 293;
+ case 0xFF008AFF: return 2935;
+ case 0xFF0055C9: return 294;
+ case 0xFF0079DB: return 2945;
+ case 0xFF0045A1: return 295;
+ case 0xFF0058A1: return 2955;
+ case 0xFF00294D: return 296;
+ case 0xFF00395C: return 2965;
+ case 0xFF82FCFF: return 297;
+ case 0xFFB3FFF2: return 2975;
+ case 0xFF4FEDFF: return 298;
+ case 0xFF69FFF0: return 2985;
+ case 0xFF26CFFF: return 299;
+ case 0xFF1AE3FF: return 2995;
+ case 0xFF008FFF: return 300;
+ case 0xFF00A0FA: return 3005;
+ case 0xFF0073D1: return 301;
+ case 0xFF0089CC: return 3015;
+ case 0xFF006080: return 302;
+ case 0xFF00687D: return 3025;
+ case 0xFF003B42: return 303;
+ case 0xFF004744: return 3035;
+ case 0xFFB3FFEB: return 304;
+ case 0xFF7DFFE8: return 305;
+ case 0xFF40FFED: return 306;
+ /* case 0xFF0091C9: return "Process Blue"; NOTE: N/A COLOR */
+ case 0xFF009CBA: return 307;
+ case 0xFF008087: return 308;
+ case 0xFF004741: return 309;
+ case 0xFF91FFE6: return 310;
+ case 0xFF91FFE0: return 3105;
+ case 0xFF5EFFE0: return 311;
+ case 0xFF5EFFD1: return 3115;
+ case 0xFF0AFFE3: return 312;
+ case 0xFF2BFFC9: return 3125;
+ case 0xFF00DECC: return 313;
+ case 0xFF00E8C3: return 3135;
+ case 0xFF00B3A2: return 314;
+ case 0xFF00C49F: return 3145;
+ case 0xFF009180: return 315;
+ case 0xFF009E78: return 3155;
+ case 0xFF00523C: return 316;
+ case 0xFF005940: return 3165;
+ case 0xFFD1FFEB: return 317;
+ case 0xFF9EFFD9: return 318;
+ case 0xFF7AFFCF: return 319;
+ case 0xFF00EDA4: return 320;
+ case 0xFF00C487: return 321;
+ case 0xFF00A66F: return 322;
+ case 0xFF008754: return 323;
+ case 0xFFB8FFE0: return 324;
+ case 0xFFA1FFD1: return 3242;
+ case 0xFFA8FFCF: return 3245;
+ case 0xFF91FFC2: return 3248;
+ case 0xFF70FFBD: return 325;
+ case 0xFF87FFC2: return 3252;
+ case 0xFF82FFB8: return 3255;
+ case 0xFF69FFAB: return 3258;
+ case 0xFF21FF9E: return 326;
+ case 0xFF4AFFAB: return 3262;
+ case 0xFF4FFFA1: return 3265;
+ case 0xFF1AFF82: return 3268;
+ case 0xFF00D477: return 327;
+ case 0xFF00FF8F: return 3272;
+ case 0xFF0DFF87: return 3275;
+ case 0xFF00F26D: return 3278;
+ case 0xFF00AD5F: return 328;
+ case 0xFF00D975: return 3282;
+ case 0xFF00ED77: return 3285;
+ case 0xFF00CC5E: return 3288;
+ case 0xFF008A4A: return 329;
+ case 0xFF008A46: return 3292;
+ case 0xFF00C95F: return 3295;
+ case 0xFF009440: return 3298;
+ case 0xFF006635: return 330;
+ case 0xFF004F24: return 3302;
+ case 0xFF006327: return 3305;
+ case 0xFF00471D: return 3308;
+ case 0xFFC2FFD6: return 331;
+ case 0xFFB3FFCC: return 332;
+ case 0xFF91FFBA: return 333;
+ /* case 0xFF00AF93: return "Green"; NOTE: N/A COLOR */
+ case 0xFF00F763: return 334;
+ case 0xFF00B33E: return 335;
+ case 0xFF00872D: return 336;
+ case 0xFFB0FFCC: return 337;
+ case 0xFFA6FFBF: return 3375;
+ case 0xFF87FFAD: return 338;
+ case 0xFF8CFFAB: return 3385;
+ case 0xFF29FF70: return 339;
+ case 0xFF63FF8C: return 3395;
+ case 0xFF00E84F: return 340;
+ case 0xFF26FF59: return 3405;
+ case 0xFF00B53C: return 341;
+ case 0xFF00C72E: return 3415;
+ case 0xFF00912A: return 342;
+ case 0xFF009421: return 3425;
+ case 0xFF02631C: return 343;
+ case 0xFF005710: return 3435;
+ case 0xFFBAFFC4: return 344;
+ case 0xFF9EFFAD: return 345;
+ case 0xFF73FF87: return 346;
+ case 0xFF00F723: return 347;
+ case 0xFF00C21D: return 348;
+ case 0xFF00940D: return 349;
+ case 0xFF0D4000: return 350;
+ case 0xFFD4FFD6: return 351;
+ case 0xFFBAFFBF: return 352;
+ case 0xFF9EFFA3: return 353;
+ case 0xFF33FF1A: return 354;
+ case 0xFF0FFF00: return 355;
+ case 0xFF09BA00: return 356;
+ case 0xFF167000: return 357;
+ case 0xFFBAFF9E: return 358;
+ case 0xFFA3FF82: return 359;
+ case 0xFF6BFF33: return 360;
+ case 0xFF4FFF00: return 361;
+ case 0xFF46E800: return 362;
+ case 0xFF3EC200: return 363;
+ case 0xFF349400: return 364;
+ case 0xFFE0FFB5: return 365;
+ case 0xFFCCFF8F: return 366;
+ case 0xFFADFF69: return 367;
+ case 0xFF6EFF00: return 368;
+ case 0xFF61ED00: return 369;
+ case 0xFF52BA00: return 370;
+ case 0xFF407000: return 371;
+ case 0xFFE6FFAB: return 372;
+ case 0xFFD6FF8A: return 373;
+ case 0xFFC2FF6E: return 374;
+ case 0xFF96FF38: return 375;
+ case 0xFF74F200: return 376;
+ case 0xFF6BC200: return 377;
+ case 0xFF436600: return 378;
+ case 0xFFE8FF6B: return 379;
+ case 0xFFDEFF47: return 380;
+ case 0xFFCCFF17: return 381;
+ case 0xFFB5FF00: return 382;
+ case 0xFFA5CF00: return 383;
+ case 0xFF90B000: return 384;
+ case 0xFF686B00: return 385;
+ case 0xFFF0FF70: return 386;
+ case 0xFFE6FF42: return 387;
+ case 0xFFDBFF36: return 388;
+ case 0xFFCCFF26: return 389;
+ case 0xFFB7EB00: return 390;
+ case 0xFF95AB00: return 391;
+ case 0xFF798200: return 392;
+ case 0xFFF7FF73: return 393;
+ case 0xFFFCFF52: return 3935;
+ case 0xFFF0FF3D: return 394;
+ case 0xFFF7FF26: return 3945;
+ case 0xFFEBFF26: return 395;
+ case 0xFFF0FF00: return 3955;
+ case 0xFFE3FF0F: return 396;
+ case 0xFFEBFF00: return 3965;
+ case 0xFFCCE300: return 397;
+ case 0xFFB5B500: return 3975;
+ case 0xFFABB800: return 398;
+ case 0xFF969200: return 3985;
+ case 0xFF919100: return 399;
+ case 0xFF5C5900: return 3995;
+ case 0xFFD6D0C9: return 400;
+ case 0xFFC4BBAF: return 401;
+ case 0xFFB0A597: return 402;
+ case 0xFF918779: return 403;
+ case 0xFF706758: return 404;
+ case 0xFF474030: return 405;
+ /* case 0xFF3D332B: return "Black"; NOTE: N/A COLOR */
+ case 0xFFD6CBC9: return 406;
+ case 0xFFBDAEAC: return 407;
+ case 0xFFA89796: return 408;
+ case 0xFF8C7A77: return 409;
+ case 0xFF705C59: return 410;
+ case 0xFF47342E: return 411;
+ case 0xFF050402: return 412;
+ case 0xFFCCCCBA: return 413;
+ case 0xFFB3B3A1: return 414;
+ case 0xFF969684: return 415;
+ case 0xFF80806B: return 416;
+ case 0xFF585943: return 417;
+ case 0xFF3E402C: return 418;
+ case 0xFF000000: return 419;
+ case 0xFFD9D9D9: return 420;
+ case 0xFFBDBDBD: return 421;
+ case 0xFFABABAB: return 422;
+ case 0xFF8F8F8F: return 423;
+ case 0xFF636363: return 424;
+ case 0xFF3B3B3B: return 425;
+ /* case 0xFF000000: return 426; TODO: duplicate case value */
+ case 0xFFE3E3E3: return 427;
+ case 0xFFCDD1D1: return 428;
+ case 0xFFA8ADAD: return 429;
+ case 0xFF858C8C: return 430;
+ case 0xFF525B5C: return 431;
+ case 0xFF2D393B: return 432;
+ case 0xFF090C0D: return 433;
+ case 0xFFEDE6E8: return 434;
+ case 0xFFDED6DB: return 435;
+ case 0xFFC2BFBF: return 436;
+ case 0xFF8A8C8A: return 437;
+ case 0xFF394500: return 438;
+ case 0xFF293300: return 439;
+ case 0xFF202700: return 440;
+ case 0xFFDAE8D8: return 441;
+ case 0xFFBECFBC: return 442;
+ case 0xFF9DB39D: return 443;
+ case 0xFF7E947E: return 444;
+ case 0xFF475947: return 445;
+ case 0xFF324031: return 446;
+ case 0xFF272E20: return 447;
+ /* BEGIN N/A COLORS */
+ /*
+ case 0xFFE5DBCC: return "Warm Gray 1";
+ case 0xFFDDD1C1: return "Warm Gray 2";
+ case 0xFFCCC1B2: return "Warm Gray 3";
+ case 0xFFC1B5A5: return "Warm Gray 4";
+ case 0xFFB5A899: return "Warm Gray 5";
+ case 0xFFAFA393: return "Warm Gray 6";
+ case 0xFFA39687: return "Warm Gray 7";
+ case 0xFF96897A: return "Warm Gray 8";
+ case 0xFF8C7F70: return "Warm Gray 9";
+ case 0xFF827263: return "Warm Gray 10";
+ case 0xFF6D5E51: return "Warm Gray 11";
+ case 0xFFE8E2D6: return "Cool Gray 1";
+ case 0xFFDDD8CE: return "Cool Gray 2";
+ case 0xFFD3CEC4: return "Cool Gray 3";
+ case 0xFFC4C1BA: return "Cool Gray 4";
+ case 0xFFBAB7AF: return "Cool Gray 5";
+ case 0xFFB5B2AA: return "Cool Gray 6";
+ case 0xFFA5A39E: return "Cool Gray 7";
+ case 0xFF9B9993: return "Cool Gray 8";
+ case 0xFF8C8984: return "Cool Gray 9";
+ case 0xFF777772: return "Cool Gray 10";
+ */
+ /* END N/A COLORS */
+ case 0xFF2D3E00: return 448;
+ case 0xFF4F3A00: return 4485;
+ case 0xFF3D5200: return 449;
+ case 0xFF8A6E07: return 4495;
+ case 0xFF506700: return 450;
+ case 0xFFA38B24: return 4505;
+ case 0xFFABB573: return 451;
+ case 0xFFC2B061: return 4515;
+ case 0xFFC2CF9C: return 452;
+ case 0xFFD4C581: return 4525;
+ case 0xFFDBE3BF: return 453;
+ case 0xFFE3DA9F: return 4535;
+ case 0xFFE8EDD6: return 454;
+ case 0xFFF0E9C2: return 4545;
+ case 0xFF594A00: return 455;
+ case 0xFF917C00: return 456;
+ case 0xFFB89C00: return 457;
+ case 0xFFE6E645: return 458;
+ case 0xFFF0ED73: return 459;
+ case 0xFFF5F28F: return 460;
+ case 0xFFF7F7A6: return 461;
+ case 0xFF402600: return 462;
+ case 0xFF361500: return 4625;
+ case 0xFF6B3D00: return 463;
+ case 0xFF8F4A06: return 4635;
+ case 0xFF955300: return 464;
+ case 0xFFB8743B: return 4645;
+ case 0xFFCCAD6B: return 465;
+ case 0xFFD19B73: return 4655;
+ case 0xFFE0C791: return 466;
+ case 0xFFE6BC9C: return 4665;
+ case 0xFFE8D9A8: return 467;
+ case 0xFFF0D5BD: return 4675;
+ case 0xFFF0E8C4: return 468;
+ case 0xFFF5E4D3: return 4685;
+ case 0xFF4A1A00: return 469;
+ case 0xFF420D00: return 4695;
+ case 0xFFAB4800: return 470;
+ case 0xFF823126: return 4705;
+ case 0xFFD15600: return 471;
+ case 0xFFA8625D: return 4715;
+ case 0xFFFFA87A: return 472;
+ case 0xFFBF827C: return 4725;
+ case 0xFFFFC4A3: return 473;
+ case 0xFFD9A9A7: return 4735;
+ case 0xFFFFD9BD: return 474;
+ case 0xFFE6BEBC: return 4745;
+ case 0xFFFFE3CC: return 475;
+ case 0xFFF0D8D3: return 4755;
+ case 0xFF381C00: return 476;
+ case 0xFF4F1800: return 477;
+ case 0xFF6B1200: return 478;
+ case 0xFFB08573: return 479;
+ case 0xFFD9B5B0: return 480;
+ case 0xFFE8CFC9: return 481;
+ case 0xFFF2E0DE: return 482;
+ case 0xFF660700: return 483;
+ case 0xFFB50900: return 484;
+ case 0xFFFF0D00: return 485;
+ case 0xFFFF8796: return 486;
+ case 0xFFFFA6B8: return 487;
+ case 0xFFFFBDCF: return 488;
+ case 0xFFFFD9E3: return 489;
+ case 0xFF471300: return 490;
+ case 0xFF7A1A00: return 491;
+ case 0xFF942200: return 492;
+ case 0xFFF283BB: return 493;
+ case 0xFFFFABDE: return 494;
+ case 0xFFFFC2E3: return 495;
+ case 0xFFFFD6E8: return 496;
+ case 0xFF381100: return 497;
+ case 0xFF330E00: return 4975;
+ case 0xFF662500: return 498;
+ case 0xFF853241: return 4985;
+ case 0xFF853100: return 499;
+ case 0xFFA85868: return 4995;
+ case 0xFFE38DB3: return 500;
+ case 0xFFC47A8F: return 5005;
+ case 0xFFF7B5D7: return 501;
+ case 0xFFE3AAC1: return 5015;
+ case 0xFFFCCFE3: return 502;
+ case 0xFFEDC2D1: return 5025;
+ case 0xFFFFE3EB: return 503;
+ case 0xFFF7DFE1: return 5035;
+ case 0xFF320000: return 504;
+ case 0xFF600000: return 505;
+ case 0xFF770000: return 506;
+ case 0xFFDE82C4: return 507;
+ case 0xFFF2A3E3: return 508;
+ case 0xFFFFC2ED: return 509;
+ case 0xFFFFD4F0: return 510;
+ case 0xFF3D0066: return 511;
+ case 0xFF2B0041: return 5115;
+ case 0xFF6100CE: return 512;
+ case 0xFF592482: return 5125;
+ case 0xFF8A1FFF: return 513;
+ case 0xFF8257B8: return 5135;
+ case 0xFFD980FF: return 514;
+ case 0xFFB38CE0: return 5145;
+ case 0xFFED9EFF: return 515;
+ case 0xFFD4B3EB: return 5155;
+ case 0xFFF7BAFF: return 516;
+ case 0xFFE8CFF2: return 5165;
+ case 0xFFFFD1FF: return 517;
+ case 0xFFF2E0F7: return 5175;
+ case 0xFF2E005C: return 518;
+ case 0xFF1C0022: return 5185;
+ case 0xFF44009D: return 519;
+ case 0xFF3D0C4E: return 5195;
+ case 0xFF5C00E0: return 520;
+ case 0xFF7A5E85: return 5205;
+ case 0xFFBA87FF: return 521;
+ case 0xFFB59EC2: return 5215;
+ case 0xFFD4A1FF: return 522;
+ case 0xFFD4BAD9: return 5225;
+ case 0xFFE6BDFF: return 523;
+ case 0xFFE6D4E6: return 5235;
+ case 0xFFF0D9FF: return 524;
+ case 0xFFF0E6ED: return 5245;
+ case 0xFF270085: return 525;
+ case 0xFF0D0B4D: return 5255;
+ case 0xFF3B00ED: return 526;
+ case 0xFF20258A: return 5265;
+ case 0xFF4500FF: return 527;
+ case 0xFF3848A8: return 5275;
+ case 0xFF9673FF: return 528;
+ case 0xFF7280C4: return 5285;
+ case 0xFFBD99FF: return 529;
+ case 0xFFA8B3E6: return 5295;
+ case 0xFFD1B0FF: return 530;
+ case 0xFFC7CEED: return 5305;
+ case 0xFFE6CCFF: return 531;
+ case 0xFFE4E4F2: return 5315;
+ case 0xFF00193F: return 532;
+ case 0xFF00227B: return 533;
+ case 0xFF002CAA: return 534;
+ case 0xFF94B3ED: return 535;
+ case 0xFFB0C7F2: return 536;
+ case 0xFFC7DBF7: return 537;
+ case 0xFFDEE8FA: return 538;
+ case 0xFF00274D: return 539;
+ case 0xFF00223D: return 5395;
+ case 0xFF003473: return 540;
+ case 0xFF3A728A: return 5405;
+ case 0xFF00449E: return 541;
+ case 0xFF5A8A96: return 5415;
+ case 0xFF5EC1F7: return 542;
+ case 0xFF79A6AD: return 5425;
+ case 0xFF96E3FF: return 543;
+ case 0xFFB8CDD4: return 5435;
+ case 0xFFB3F0FF: return 544;
+ case 0xFFCCDCDE: return 5445;
+ case 0xFFC7F7FF: return 545;
+ case 0xFFDAE8E8: return 5455;
+ case 0xFF02272B: return 546;
+ case 0xFF002B24: return 5463;
+ case 0xFF000D09: return 5467;
+ case 0xFF003440: return 547;
+ case 0xFF167A58: return 5473;
+ case 0xFF1D4230: return 5477;
+ case 0xFF00465C: return 548;
+ case 0xFF43B08B: return 5483;
+ case 0xFF48705D: return 5487;
+ case 0xFF56ADBA: return 549;
+ case 0xFF73C9AD: return 5493;
+ case 0xFF829E90: return 5497;
+ case 0xFF7BC1C9: return 550;
+ case 0xFF9CDBC5: return 5503;
+ case 0xFFA1B5A8: return 5507;
+ case 0xFFA2D7DE: return 551;
+ case 0xFFC7F2E1: return 5513;
+ case 0xFFBED1C5: return 5517;
+ case 0xFFC5E8E8: return 552;
+ case 0xFFDCF7EB: return 5523;
+ case 0xFFD5E3DA: return 5527;
+ case 0xFF143319: return 553;
+ case 0xFF102E14: return 5535;
+ case 0xFF115422: return 554;
+ case 0xFF327A3D: return 5545;
+ case 0xFF187031: return 555;
+ case 0xFF5A9E68: return 5555;
+ case 0xFF66BA80: return 556;
+ case 0xFF84BD8F: return 5565;
+ case 0xFF98D9AD: return 557;
+ case 0xFFA9D4B2: return 5575;
+ case 0xFFBAE8CA: return 558;
+ case 0xFFCAE6CC: return 5585;
+ case 0xFFCEF0D8: return 559;
+ case 0xFFDDEDDA: return 5595;
+ case 0xFF0D4018: return 560;
+ case 0xFF050F07: return 5605;
+ case 0xFF127A38: return 561;
+ case 0xFF2E522B: return 5615;
+ case 0xFF1AB058: return 562;
+ case 0xFF5A7D57: return 5625;
+ case 0xFF79FCAC: return 563;
+ case 0xFF89A386: return 5635;
+ case 0xFFA1FFCC: return 564;
+ case 0xFFAEBFA6: return 5645;
+ case 0xFFC4FFDE: return 565;
+ case 0xFFC5D1BE: return 5655;
+ case 0xFFDBFFE8: return 566;
+ case 0xFFDAE6D5: return 5665;
+ case 0xFF0E4D1C: return 567;
+ case 0xFF14A346: return 568;
+ case 0xFF04D45B: return 569;
+ case 0xFF85FFB5: return 570;
+ case 0xFFADFFCF: return 571;
+ case 0xFFC4FFDB: return 572;
+ /* case 0xFFDBFFE8: return 573; TODO: duplicate case value */
+ case 0xFF314A0E: return 574;
+ case 0xFF1F2E07: return 5743;
+ case 0xFF243600: return 5747;
+ case 0xFF3E7800: return 575;
+ case 0xFF3F5410: return 5753;
+ case 0xFF547306: return 5757;
+ case 0xFF4F9C00: return 576;
+ case 0xFF5C6E1D: return 5763;
+ case 0xFF849C32: return 5767;
+ case 0xFFAEE67C: return 577;
+ case 0xFF909E5A: return 5773;
+ case 0xFFA5B85E: return 5777;
+ case 0xFFC0F090: return 578;
+ case 0xFFAFBA86: return 5783;
+ case 0xFFCEDE99: return 5787;
+ case 0xFFCDF7A3: return 579;
+ case 0xFFC9D1A5: return 5793;
+ case 0xFFDCE8B0: return 5797;
+ case 0xFFDCFAB9: return 580;
+ case 0xFFDEE3C8: return 5803;
+ case 0xFFE9F0CE: return 5807;
+ case 0xFF464700: return 581;
+ case 0xFF363605: return 5815;
+ case 0xFF788A00: return 582;
+ case 0xFF69660E: return 5825;
+ case 0xFFA3D400: return 583;
+ case 0xFF999632: return 5835;
+ case 0xFFD3F032: return 584;
+ case 0xFFB3B15F: return 5845;
+ case 0xFFDEFA55: return 585;
+ case 0xFFD1D190: return 5855;
+ case 0xFFE8FF78: return 586;
+ case 0xFFDEDEA6: return 5865;
+ case 0xFFF2FF99: return 587;
+ case 0xFFEBEBC0: return 5875;
+ case 0xFFFFFFB5: return 600;
+ case 0xFFFFFF99: return 601;
+ /* case 0xFFFFFF7D: return 602; TODO: duplicate case value */
+ case 0xFFFCFC4E: return 603;
+ case 0xFFF7F71E: return 604;
+ case 0xFFEDE800: return 605;
+ case 0xFFE0D700: return 606;
+ case 0xFFFCFCCF: return 607;
+ case 0xFFFAFAAA: return 608;
+ case 0xFFF5F584: return 609;
+ case 0xFFF0F065: return 610;
+ case 0xFFE3E112: return 611;
+ case 0xFFCCC800: return 612;
+ case 0xFFB3AB00: return 613;
+ case 0xFFF5F5C4: return 614;
+ case 0xFFF0EDAF: return 615;
+ case 0xFFE8E397: return 616;
+ case 0xFFD4CF6E: return 617;
+ case 0xFFB3AD17: return 618;
+ case 0xFF918C00: return 619;
+ case 0xFF787200: return 620;
+ case 0xFFD9FAE1: return 621;
+ case 0xFFBAF5C6: return 622;
+ case 0xFF9CE6AE: return 623;
+ case 0xFF72CC85: return 624;
+ case 0xFF4BAB60: return 625;
+ case 0xFF175E22: return 626;
+ case 0xFF04290A: return 627;
+ case 0xFFCFFFF0: return 628;
+ case 0xFFA8FFE8: return 629;
+ case 0xFF87FFE3: return 630;
+ case 0xFF52FADC: return 631;
+ case 0xFF13F2CE: return 632;
+ case 0xFF00BFAC: return 633;
+ case 0xFF00998B: return 634;
+ case 0xFFADFFEB: return 635;
+ case 0xFF8CFFE8: return 636;
+ case 0xFF73FFE8: return 637;
+ case 0xFF2BFFE6: return 638;
+ case 0xFF00F2E6: return 639;
+ case 0xFF00C7C7: return 640;
+ case 0xFF00ABB3: return 641;
+ case 0xFFD2F0FA: return 642;
+ case 0xFFB8E4F5: return 643;
+ case 0xFF8BCCF0: return 644;
+ case 0xFF64A7E8: return 645;
+ case 0xFF4696E3: return 646;
+ case 0xFF0056C4: return 647;
+ case 0xFF002D75: return 648;
+ case 0xFFD9EDFC: return 649;
+ case 0xFFBEE3FA: return 650;
+ case 0xFF95C5F0: return 651;
+ case 0xFF5C97E6: return 652;
+ case 0xFF004ECC: return 653;
+ case 0xFF00399E: return 654;
+ case 0xFF002B7A: return 655;
+ case 0xFFDBF5FF: return 656;
+ case 0xFFC2EBFF: return 657;
+ case 0xFF96CCFF: return 658;
+ case 0xFF5CA6FF: return 659;
+ case 0xFF1A6EFF: return 660;
+ case 0xFF0048E8: return 661;
+ /* case 0xFF003BD1: return 662; TODO: duplicate case value */
+ case 0xFFEDF0FF: return 663;
+ case 0xFFE3E8FF: return 664;
+ case 0xFFC8CFFA: return 665;
+ case 0xFFA4A6ED: return 666;
+ case 0xFF6970DB: return 667;
+ case 0xFF3E40B3: return 668;
+ case 0xFF201E87: return 669;
+ case 0xFFFFDEFF: return 670;
+ case 0xFFFCCCFF: return 671;
+ case 0xFFF7A8FF: return 672;
+ case 0xFFF082FF: return 673;
+ case 0xFFE854FF: return 674;
+ case 0xFFCD00F7: return 675;
+ case 0xFFBB00C7: return 676;
+ case 0xFFFADEFF: return 677;
+ case 0xFFF7C9FF: return 678;
+ case 0xFFF2BAFF: return 679;
+ case 0xFFE18EFA: return 680;
+ case 0xFFC15FF5: return 681;
+ case 0xFFA82FE0: return 682;
+ case 0xFF810091: return 683;
+ case 0xFFFACFFA: return 684;
+ case 0xFFF7BAF7: return 685;
+ case 0xFFF2AAF2: return 686;
+ case 0xFFDC7EE0: return 687;
+ case 0xFFC459CF: return 688;
+ case 0xFF9D27A8: return 689;
+ case 0xFF690369: return 690;
+ case 0xFFFCD7E8: return 691;
+ case 0xFFFAC0E1: return 692;
+ case 0xFFF0A8D3: return 693;
+ case 0xFFE683BA: return 694;
+ case 0xFFBF508A: return 695;
+ case 0xFF991846: return 696;
+ case 0xFF7D0925: return 697;
+ case 0xFFFFD6EB: return 698;
+ case 0xFFFFC2E6: return 699;
+ case 0xFFFFA3DB: return 700;
+ case 0xFFFF78CC: return 701;
+ case 0xFFF24BA0: return 702;
+ case 0xFFD62463: return 703;
+ case 0xFFBA0025: return 704;
+ case 0xFFFFE8F2: return 705;
+ case 0xFFFFD4E6: return 706;
+ case 0xFFFFB3DB: return 707;
+ case 0xFFFF8AC7: return 708;
+ case 0xFFFF579E: return 709;
+ case 0xFFFF366B: return 710;
+ case 0xFFFA0032: return 711;
+ case 0xFFFFDBB0: return 712;
+ case 0xFFFFCF96: return 713;
+ case 0xFFFFB875: return 714;
+ case 0xFFFFA14A: return 715;
+ case 0xFFFF8717: return 716;
+ case 0xFFFA7000: return 717;
+ case 0xFFEB6300: return 718;
+ case 0xFFFFE6BF: return 719;
+ case 0xFFFCD7A7: return 720;
+ case 0xFFF7BC77: return 721;
+ case 0xFFE89538: return 722;
+ case 0xFFD4740B: return 723;
+ case 0xFFA14C00: return 724;
+ case 0xFF823B00: return 725;
+ case 0xFFFAE6C0: return 726;
+ case 0xFFF2CEA0: return 727;
+ case 0xFFE6B577: return 728;
+ case 0xFFD19052: return 729;
+ case 0xFFB56E2B: return 730;
+ case 0xFF753700: return 731;
+ case 0xFF5C2800: return 732;
+ case 0xFFFFF5D1: return 7401;
+ case 0xFFFFF0B3: return 7402;
+ case 0xFFFFE680: return 7403;
+ /* case 0xFFFFE833: return 7404; TODO: duplicate case value */
+ /* case 0xFFFFE600: return 7405; TODO: duplicate case value */
+ case 0xFFFFD100: return 7406;
+ case 0xFFE3B122: return 7407;
+ case 0xFFFFBF0D: return 7408;
+ case 0xFFFFB30D: return 7409;
+ case 0xFFFFB373: return 7410;
+ case 0xFFFFA64F: return 7411;
+ case 0xFFED8A00: return 7412;
+ case 0xFFF57300: return 7413;
+ case 0xFFE37B00: return 7414;
+ case 0xFFFFD1D9: return 7415;
+ case 0xFFFF6666: return 7416;
+ case 0xFFFF4040: return 7417;
+ case 0xFFF24961: return 7418;
+ case 0xFFD15473: return 7419;
+ case 0xFFCC2976: return 7420;
+ case 0xFF630046: return 7421;
+ /* case 0xFFFFE8F2: return 7422; TODO: duplicate case value */
+ /* case 0xFFFF73C7: return 7423; TODO: duplicate case value */
+ case 0xFFFF40B3: return 7424;
+ case 0xFFED18A6: return 7425;
+ case 0xFFD10073: return 7426;
+ case 0xFFB80040: return 7427;
+ case 0xFF73173F: return 7428;
+ case 0xFFFFD1F7: return 7429;
+ case 0xFFFAB0FF: return 7430;
+ case 0xFFF296ED: return 7431;
+ case 0xFFE667DF: return 7432;
+ case 0xFFD936B8: return 7433;
+ case 0xFFCC29AD: return 7434;
+ case 0xFFA60095: return 7435;
+ case 0xFFF7EBFF: return 7436;
+ case 0xFFF0CCFF: return 7437;
+ case 0xFFD9A6FF: return 7438;
+ case 0xFFCCA6FF: return 7439;
+ case 0xFFB399FF: return 7440;
+ case 0xFFA380FF: return 7441;
+ case 0xFF804DFF: return 7442;
+ case 0xFFF0F2FF: return 7443;
+ case 0xFFCCD4FF: return 7444;
+ case 0xFFADC6F7: return 7445;
+ case 0xFF919EFF: return 7446;
+ case 0xFF5357CF: return 7447;
+ case 0xFF4E4373: return 7448;
+ case 0xFF270020: return 7449;
+ case 0xFFCCE6FF: return 7450;
+ case 0xFF99C9FF: return 7451;
+ case 0xFF80ADFF: return 7452;
+ case 0xFF80BDFF: return 7453;
+ case 0xFF73AEE6: return 7454;
+ case 0xFF3378FF: return 7455;
+ case 0xFF6B9AED: return 7456;
+ case 0xFFE0FFFA: return 7457;
+ case 0xFF90F0E4: return 7458;
+ case 0xFF5FDED1: return 7459;
+ case 0xFF00F2F2: return 7460;
+ case 0xFF38B8FF: return 7461;
+ case 0xFF0073E6: return 7462;
+ case 0xFF003359: return 7463;
+ case 0xFFBFFFE6: return 7464;
+ case 0xFF80FFBF: return 7465;
+ case 0xFF4DFFC4: return 7466;
+ case 0xFF0DFFBF: return 7467;
+ case 0xFF00A5B8: return 7468;
+ case 0xFF007A99: return 7469;
+ case 0xFF1C778C: return 7470;
+ case 0xFFB8FFDB: return 7471;
+ case 0xFF7AFFBF: return 7472;
+ case 0xFF46EB91: return 7473;
+ case 0xFF14C78F: return 7474;
+ case 0xFF59B386: return 7475;
+ case 0xFF00663A: return 7476;
+ case 0xFF105249: return 7477;
+ case 0xFFD1FFDB: return 7478;
+ case 0xFF73FF80: return 7479;
+ case 0xFF66FF80: return 7480;
+ case 0xFF66FF73: return 7481;
+ case 0xFF33FF40: return 7482;
+ case 0xFF117300: return 7483;
+ case 0xFF008013: return 7484;
+ case 0xFFF0FFE6: return 7485;
+ case 0xFFCCFFB3: return 7486;
+ case 0xFFB3FF8C: return 7487;
+ case 0xFF91FF66: return 7488;
+ case 0xFF5FED2F: return 7489;
+ case 0xFF5BA621: return 7490;
+ case 0xFF689900: return 7491;
+ case 0xFFD1ED77: return 7492;
+ case 0xFFC5E693: return 7493;
+ case 0xFFA3D982: return 7494;
+ case 0xFF86B324: return 7495;
+ case 0xFF5F9E00: return 7496;
+ case 0xFF738639: return 7497;
+ case 0xFF263300: return 7498;
+ case 0xFFFFFAD9: return 7499;
+ case 0xFFF7F2D2: return 7500;
+ case 0xFFF0E6C0: return 7501;
+ case 0xFFE6D395: return 7502;
+ case 0xFFBFA87C: return 7503;
+ case 0xFF997354: return 7504;
+ case 0xFF735022: return 7505;
+ case 0xFFFFF2D9: return 7506;
+ case 0xFFFFE6B3: return 7507;
+ case 0xFFF5D093: return 7508;
+ case 0xFFF2C279: return 7509;
+ case 0xFFE39F40: return 7510;
+ case 0xFFBF6900: return 7511;
+ case 0xFFAB5C00: return 7512;
+ case 0xFFF7CBB2: return 7513;
+ case 0xFFF2B896: return 7514;
+ case 0xFFE09270: return 7515;
+ case 0xFFA65000: return 7516;
+ case 0xFF8F3900: return 7517;
+ case 0xFF663D2E: return 7518;
+ case 0xFF423500: return 7519;
+ case 0xFFFFD6CF: return 7520;
+ case 0xFFE6ACB8: return 7521;
+ case 0xFFD68196: return 7522;
+ case 0xFFCC7A85: return 7523;
+ case 0xFFBA544A: return 7524;
+ case 0xFFB36259: return 7525;
+ case 0xFFA63A00: return 7526;
+ case 0xFFEDE8DF: return 7527;
+ case 0xFFE6DFCF: return 7528;
+ case 0xFFD4CBBA: return 7529;
+ case 0xFFADA089: return 7530;
+ case 0xFF80735D: return 7531;
+ case 0xFF594A2D: return 7532;
+ case 0xFF261E06: return 7533;
+ case 0xFFE6E1D3: return 7534;
+ case 0xFFCCC6AD: return 7535;
+ case 0xFFADA687: return 7536;
+ case 0xFFC6CCB8: return 7537;
+ case 0xFFA2B39B: return 7538;
+ case 0xFFA0A395: return 7539;
+ case 0xFF474747: return 7540;
+ case 0xFFEDF2F2: return 7541;
+ case 0xFFC1D6D0: return 7542;
+ case 0xFFA6B3B3: return 7543;
+ case 0xFF8A9799: return 7544;
+ case 0xFF495C5E: return 7545;
+ case 0xFF304547: return 7546;
+ case 0xFF0A0F0F: return 7547;
+ /* BEGIN N/A COLORS */
+ /*
+ case 0xFF050403: return "Black";
+ case 0xFFFCE216: return "Yellow 2X";
+ case 0xFFF7B50C: return "116 2X";
+ case 0xFFE29100: return "130 2X";
+ case 0xFFEA4F00: return "165 2X";
+ case 0xFFE03A00: return "Warm Red 2X";
+ case 0xFFD62100: return "1788 2X";
+ case 0xFFD11600: return "185 2X";
+ case 0xFFCC0C00: return "485 2X";
+ case 0xFFC6003D: return "Rubine Red 2X";
+ case 0xFFD10572: return "Rhodamine Red 2X";
+ case 0xFFC4057C: return "239 2X";
+ case 0xFFAA0096: return "Purple 2X";
+ case 0xFF720082: return "2592 2X";
+ case 0xFF59008E: return "Violet 2X";
+ case 0xFF1C007A: return "Reflex Blue 2X";
+ case 0xFF0077BF: return "Process Blue 2X";
+ case 0xFF007FCC: return "299 2X";
+ case 0xFF00A3D1: return "306 2X";
+ case 0xFF007F82: return "320 2X";
+ case 0xFF008977: return "327 2X";
+ case 0xFF009677: return "Green 2X";
+ case 0xFF009944: return "354 2X";
+ case 0xFF009E0F: return "368 2X";
+ case 0xFF54BC00: return "375 2X";
+ case 0xFF9EC400: return "382 2X";
+ case 0xFFA34402: return "471 2X";
+ case 0xFF704214: return "464 2X";
+ case 0xFF0A0C11: return "433 2X";
+ case 0xFF3A3321: return "Black 2";
+ case 0xFF282D26: return "Black 3";
+ case 0xFF3D3023: return "Black 4";
+ case 0xFF422D2D: return "Black 5";
+ case 0xFF1C2630: return "Black 6";
+ case 0xFF443D38: return "Black 7";
+ case 0xFF111111: return "Black 2 2X";
+ case 0xFF111114: return "Black 3 2X";
+ case 0xFF0F0F0F: return "Black 4 2X";
+ case 0xFF110C0F: return "Black 5 2X";
+ case 0xFF070C0F: return "Black 6 2X";
+ case 0xFF33302B: return "Black 7 2X";
+ */
+ /* END N/A COLORS */
+ }
+
+ return -1;
+}
+
+const char* getName_Pantone(unsigned int color)
+{
+ switch(color)
+ {
+ case 0xFFF7E214: return "Process Yellow";
+
+ /* SNIP 8<-------------------- */
+
+ case 0xFFFCE016: return "Pantone Yellow";
+
+ /* SNIP 8<-------------------- */
+
+ case 0xFFEF6B00: return "Orange 021";
+
+ /* SNIP 8<-------------------- */
+
+ case 0xFFF93F26: return "Warm Red";
+
+ /* SNIP 8<-------------------- */
+
+ case 0xFFEF2B2D: return "Red 032";
+
+ /* SNIP 8<-------------------- */
+
+ case 0xFFD10056: return "Rubine Red";
+
+ /* SNIP 8<-------------------- */
+
+ case 0xFFED0091: return "Rhodamine Red";
+
+ /* SNIP 8<-------------------- */
+
+ case 0xFFBF30B5: return "Purple";
+
+ /* SNIP 8<-------------------- */
+
+ case 0xFF6607A5: return "Violet";
+
+ /* SNIP 8<-------------------- */
+
+ case 0xFF380096: return "Blue 072";
+
+ /* SNIP 8<-------------------- */
+
+ case 0xFF0C1C8C: return "Reflex Blue";
+
+ /* SNIP 8<-------------------- */
+
+ case 0xFF0091C9: return "Process Blue";
+
+ /* SNIP 8<-------------------- */
+
+ case 0xFF00AF93: return "Green";
+
+ /* SNIP 8<-------------------- */
+
+ case 0xFF3D332B: return "Black";
+
+ /* SNIP 8<-------------------- */
+
+ case 0xFFE5DBCC: return "Warm Gray 1";
+ case 0xFFDDD1C1: return "Warm Gray 2";
+ case 0xFFCCC1B2: return "Warm Gray 3";
+ case 0xFFC1B5A5: return "Warm Gray 4";
+ case 0xFFB5A899: return "Warm Gray 5";
+ case 0xFFAFA393: return "Warm Gray 6";
+ case 0xFFA39687: return "Warm Gray 7";
+ case 0xFF96897A: return "Warm Gray 8";
+ case 0xFF8C7F70: return "Warm Gray 9";
+ case 0xFF827263: return "Warm Gray 10";
+ case 0xFF6D5E51: return "Warm Gray 11";
+ case 0xFFE8E2D6: return "Cool Gray 1";
+ case 0xFFDDD8CE: return "Cool Gray 2";
+ case 0xFFD3CEC4: return "Cool Gray 3";
+ case 0xFFC4C1BA: return "Cool Gray 4";
+ case 0xFFBAB7AF: return "Cool Gray 5";
+ case 0xFFB5B2AA: return "Cool Gray 6";
+ case 0xFFA5A39E: return "Cool Gray 7";
+ case 0xFF9B9993: return "Cool Gray 8";
+ case 0xFF8C8984: return "Cool Gray 9";
+ case 0xFF777772: return "Cool Gray 10";
+
+ /* SNIP 8<-------------------- */
+
+ case 0xFF050403: return "Black";
+ case 0xFFFCE216: return "Yellow 2X";
+ case 0xFFF7B50C: return "116 2X";
+ case 0xFFE29100: return "130 2X";
+ case 0xFFEA4F00: return "165 2X";
+ case 0xFFE03A00: return "Warm Red 2X";
+ case 0xFFD62100: return "1788 2X";
+ case 0xFFD11600: return "185 2X";
+ case 0xFFCC0C00: return "485 2X";
+ case 0xFFC6003D: return "Rubine Red 2X";
+ case 0xFFD10572: return "Rhodamine Red 2X";
+ case 0xFFC4057C: return "239 2X";
+ case 0xFFAA0096: return "Purple 2X";
+ case 0xFF720082: return "2592 2X";
+ case 0xFF59008E: return "Violet 2X";
+ case 0xFF1C007A: return "Reflex Blue 2X";
+ case 0xFF0077BF: return "Process Blue 2X";
+ case 0xFF007FCC: return "299 2X";
+ case 0xFF00A3D1: return "306 2X";
+ case 0xFF007F82: return "320 2X";
+ case 0xFF008977: return "327 2X";
+ case 0xFF009677: return "Green 2X";
+ case 0xFF009944: return "354 2X";
+ case 0xFF009E0F: return "368 2X";
+ case 0xFF54BC00: return "375 2X";
+ case 0xFF9EC400: return "382 2X";
+ case 0xFFA34402: return "471 2X";
+ case 0xFF704214: return "464 2X";
+ case 0xFF0A0C11: return "433 2X";
+ case 0xFF3A3321: return "Black 2";
+ case 0xFF282D26: return "Black 3";
+ case 0xFF3D3023: return "Black 4";
+ case 0xFF422D2D: return "Black 5";
+ case 0xFF1C2630: return "Black 6";
+ case 0xFF443D38: return "Black 7";
+ case 0xFF111111: return "Black 2 2X";
+ case 0xFF111114: return "Black 3 2X";
+ case 0xFF0F0F0F: return "Black 4 2X";
+ case 0xFF110C0F: return "Black 5 2X";
+ case 0xFF070C0F: return "Black 6 2X";
+ case 0xFF33302B: return "Black 7 2X";
+ }
+
+ return "";
+}
+
+int getNum_RobisonAnton_Polyester(unsigned int color) { return -1; } /*TODO: finish */
+const char* getName_RobisonAnton_Polyester(unsigned int color) { return ""; } /*TODO: finish */
+
+int getNum_RobisonAnton_Rayon(unsigned int color)
+{
+ switch(color)
+ {
+ case 0xFFEFCCCE: return 2243;
+ case 0xFFFCBFC9: return 2223;
+ case 0xFFEFC6D3: return 2599;
+ case 0xFFF9B2B7: return 2373;
+ case 0xFFF9AFAD: return 2374;
+ case 0xFFFC9BB2: return 2293;
+ case 0xFFFC8C99: return 2244;
+ case 0xFFF2AFC1: return 2237;
+ case 0xFFE5566D: return 2246;
+ case 0xFFF4476B: return 2248;
+ /* case 0xFFE5566D: return 2228; TODO: duplicate case value */
+ case 0xFFF9848E: return 2412;
+ case 0xFFF26877: return 2375;
+ case 0xFFD8899B: return 2591;
+ case 0xFF8C2633: return 2249;
+ case 0xFF7C2128: return 2608;
+ case 0xFF7A2638: return 2252;
+ case 0xFF75263D: return 2622;
+ case 0xFF772D35: return 2225;
+ case 0xFF593344: return 2587;
+ case 0xFF4F213A: return 2376;
+ case 0xFF931638: return 2494;
+ /* case 0xFFF9B2B7: return 2495; TODO: duplicate case value */
+ case 0xFF661E2B: return 2496;
+ /* case 0xFFE5566D: return 2491; TODO: duplicate case value */
+ case 0xFF8E2344: return 2497;
+ case 0xFF6D213F: return 2498;
+ /* case 0xFF8E2344: return 2499; TODO: duplicate case value */
+ case 0xFFAD0075: return 2500;
+ case 0xFFFCC9C6: return 2501;
+ case 0xFFF4BFD1: return 2502;
+ case 0xFFF7BFBF: return 2503;
+ case 0xFFCE007C: return 2259;
+ case 0xFFED72AA: return 2415;
+ case 0xFFD36B9E: return 2260;
+ case 0xFFD60270: return 2416;
+ case 0xFFE22882: return 2261;
+ case 0xFFAA004F: return 2504;
+ /* case 0xFFAA004F: return 2417; TODO: duplicate case value */
+ case 0xFFEA0F6B: return 2262;
+ case 0xFFAF1E2D: return 2418;
+ case 0xFFBF0A30: return 2281;
+ /* case 0xFFBF0A30: return 2419; TODO: duplicate case value */
+ /* case 0xFFBF0A30: return 2378; TODO: duplicate case value */
+ case 0xFFCE1126: return 2263;
+ case 0xFFD62828: return 2420;
+ /* case 0xFFBF0A30: return 2233; TODO: duplicate case value */
+ case 0xFFC41E3A: return 2219;
+ /* case 0xFFC41E3A: return 2266; TODO: duplicate case value */
+ case 0xFFA32638: return 2267;
+ /* case 0xFF8C2633: return 2268; TODO: duplicate case value */
+ /* case 0xFF75263D: return 2421; TODO: duplicate case value */
+ case 0xFF992135: return 2270;
+ /* case 0xFFA32638: return 2505; TODO: duplicate case value */
+ /* case 0xFFC41E3A: return 2506; TODO: duplicate case value */
+ case 0xFFAF003D: return 2507;
+ case 0xFFD81C3F: return 2508;
+ case 0xFFFC5E72: return 2509;
+ case 0xFFF2C4AF: return 2377;
+ case 0xFFF4CCAA: return 2413;
+ case 0xFFF9BAAA: return 2253;
+ /* case 0xFFF7BFBF: return 2255; TODO: duplicate case value */
+ case 0xFFF9BF9E: return 2256;
+ case 0xFFF9C6AA: return 2257;
+ case 0xFFF98E6D: return 2294;
+ case 0xFFF9A58C: return 2258;
+ case 0xFFF98972: return 2414;
+ case 0xFFF43F4F: return 2277;
+ /* case 0xFFF9C6AA: return 2510; TODO: duplicate case value */
+ /* case 0xFFF9BAAA: return 2511; TODO: duplicate case value */
+ /* case 0xFFF98972: return 2512; TODO: duplicate case value */
+ case 0xFFE23D28: return 2513;
+ case 0xFF008C82: return 2514;
+ case 0xFF00B2A0: return 2515;
+ case 0xFF47D6C1: return 2516;
+ case 0xFF87DDD1: return 2517;
+ case 0xFF008789: return 2492;
+ case 0xFF2DC6D6: return 2518;
+ case 0xFF00A5DB: return 2519;
+ case 0xFF00A3DD: return 2520;
+ case 0xFF003F54: return 2589;
+ case 0xFF002D47: return 2620;
+ case 0xFF006D75: return 2521;
+ case 0xFF9BC4E2: return 2239;
+ case 0xFFAFBCDB: return 2304;
+ case 0xFF5B77CC: return 2614;
+ case 0xFF6D87A8: return 2275;
+ case 0xFF99D6DD: return 2305;
+ case 0xFF28C4D8: return 2306;
+ case 0xFF00ADC6: return 2307;
+ case 0xFF00A0C4: return 2389;
+ case 0xFF008ED6: return 2441;
+ case 0xFF0054A0: return 2442;
+ /* case 0xFF008ED6: return 2388; TODO: duplicate case value */
+ /* case 0xFF00A3DD: return 2730; TODO: duplicate case value */
+ case 0xFF00709E: return 2737;
+ case 0xFF007AA5: return 2740;
+ case 0xFFC9E8DD: return 2222;
+ case 0xFF1E1C77: return 2210;
+ case 0xFF002B7F: return 2438;
+ case 0xFF335687: return 2302;
+ /* case 0xFFAFBCDB: return 2522; TODO: duplicate case value */
+ /* case 0xFF335687: return 2523; TODO: duplicate case value */
+ case 0xFF26547C: return 2612;
+ case 0xFF7796B2: return 2524;
+ case 0xFFC1C9DD: return 2525;
+ /* case 0xFF7796B2: return 2624; TODO: duplicate case value */
+ case 0xFF6689CC: return 2526;
+ case 0xFF5960A8: return 2527;
+ case 0xFF0051BA: return 2619;
+ /* case 0xFF6689CC: return 2528; TODO: duplicate case value */
+ case 0xFF3A75C4: return 2529;
+ case 0xFF75AADB: return 2530;
+ case 0xFFC4D8E2: return 2531;
+ /* case 0xFFC4D8E2: return 2532; TODO: duplicate case value */
+ case 0xFF60AFDD: return 2533;
+ case 0xFF003D6B: return 2534;
+ case 0xFF0F2B5B: return 2439;
+ case 0xFF192168: return 2625;
+ case 0xFF2B265B: return 2440;
+ case 0xFF002654: return 2613;
+ case 0xFF002649: return 2647;
+ case 0xFF353F5B: return 2386;
+ case 0xFF35264F: return 2450;
+ case 0xFF112151: return 2303;
+ case 0xFF14213D: return 2603;
+ /* case 0xFF002654: return 2609; TODO: duplicate case value */
+ /* case 0xFF14213D: return 2215; TODO: duplicate case value */
+ /* case 0xFF14213D: return 2387; TODO: duplicate case value */
+ case 0xFFC6D1D6: return 2382;
+ /* case 0xFFC1C9DD: return 2598; TODO: duplicate case value */
+ case 0xFFB5D1E8: return 2300;
+ case 0xFFD1CEDD: return 2283;
+ case 0xFF99BADD: return 2206;
+ /* case 0xFFAFBCDB: return 2269; TODO: duplicate case value */
+ case 0xFFA5BAE0: return 2383;
+ case 0xFF75B2DD: return 2433;
+ /* case 0xFF75AADB: return 2434; TODO: duplicate case value */
+ /* case 0xFF6689CC: return 2435; TODO: duplicate case value */
+ case 0xFF7F8CBF: return 2301;
+ /* case 0xFF6D87A8: return 2245; TODO: duplicate case value */
+ /* case 0xFF5B77CC: return 2384; TODO: duplicate case value */
+ case 0xFF2D338E: return 2220;
+ /* case 0xFF2D338E: return 2280; TODO: duplicate case value */
+ case 0xFF00337F: return 2627;
+ case 0xFF003893: return 2436;
+ /* case 0xFF2D338E: return 2385; TODO: duplicate case value */
+ case 0xFF3F2893: return 2437;
+ case 0xFF3A564F: return 2535;
+ case 0xFF8499A5: return 2617;
+ case 0xFF9BAABF: return 2536;
+ case 0xFF5E99AA: return 2577;
+ case 0xFFADAFAA: return 2540;
+ case 0xFFBFBAAF: return 2537;
+ case 0xFFBAB7AF: return 2741;
+ case 0xFFC4C1BA: return 2733;
+ case 0xFFCCC1B2: return 2538;
+ case 0xFFD1CCBF: return 2539;
+ /* case 0xFFADAFAA: return 2618; TODO: duplicate case value */
+ case 0xFF8C8984: return 2731;
+ case 0xFF686663: return 2729;
+ case 0xFF443D38: return 2541;
+ case 0xFFDDC6C4: return 2271;
+ case 0xFFD3B7A3: return 2272;
+ case 0xFFB5939B: return 2314;
+ case 0xFF8E6877: return 2422;
+ /* case 0xFFFCBFC9: return 2423; TODO: duplicate case value */
+ case 0xFFE5BFC6: return 2379;
+ /* case 0xFFEFC6D3: return 2276; TODO: duplicate case value */
+ case 0xFFEDC4DD: return 2285;
+ case 0xFFB58CB2: return 2424;
+ case 0xFFC9ADD8: return 2286;
+ case 0xFFE29ED6: return 2588;
+ case 0xFF512654: return 2600;
+ case 0xFF512D44: return 2616;
+ case 0xFF8E47AD: return 2425;
+ case 0xFFAF72C1: return 2288;
+ case 0xFF9B4F96: return 2426;
+ case 0xFF66116D: return 2380;
+ case 0xFF63305E: return 2490;
+ /* case 0xFF1E1C77: return 2429; TODO: duplicate case value */
+ case 0xFF332875: return 2427;
+ case 0xFF35006D: return 2428;
+ case 0xFF2B1166: return 2736;
+ case 0xFF38197A: return 2742;
+ /* case 0xFF35006D: return 2628; TODO: duplicate case value */
+ /* case 0xFF8E47AD: return 2254; TODO: duplicate case value */
+ case 0xFF5B027A: return 2430;
+ case 0xFF4C145E: return 2381;
+ case 0xFF8977BA: return 2287;
+ case 0xFF44235E: return 2431;
+ case 0xFFAA0066: return 2590;
+ /* case 0xFFCE007C: return 2291; TODO: duplicate case value */
+ /* case 0xFFAA004F: return 2432; TODO: duplicate case value */
+ case 0xFF9E2387: return 2292;
+ /* case 0xFF5E99AA: return 2308; TODO: duplicate case value */
+ case 0xFF609191: return 2443;
+ /* case 0xFF609191: return 2309; TODO: duplicate case value */
+ /* case 0xFF003F54: return 2444; TODO: duplicate case value */
+ case 0xFF93DDDB: return 2310;
+ case 0xFF7FD6DB: return 2204;
+ case 0xFF007272: return 2445;
+ case 0xFF70CE9B: return 2311;
+ /* case 0xFF70CE9B: return 2312; TODO: duplicate case value */
+ case 0xFF35C4AF: return 2390;
+ /* case 0xFF006D75: return 2446; TODO: duplicate case value */
+ case 0xFF006B77: return 2621;
+ case 0xFF006663: return 2447;
+ case 0xFF006D66: return 2735;
+ /* case 0xFF008C82: return 2391; TODO: duplicate case value */
+ case 0xFF008272: return 2448;
+ /* case 0xFF006663: return 2449; TODO: duplicate case value */
+ /* case 0xFF006D66: return 2615; TODO: duplicate case value */
+ case 0xFFBCC1B2: return 2241;
+ case 0xFFC6D6A0: return 2282;
+ case 0xFF9EAA99: return 2221;
+ case 0xFFB2D8D8: return 2313;
+ case 0xFF7AA891: return 2278;
+ /* case 0xFF7AA891: return 2594; TODO: duplicate case value */
+ case 0xFF006056: return 2451;
+ /* case 0xFF006056: return 2743; TODO: duplicate case value */
+ case 0xFF4F6D5E: return 2392;
+ case 0xFF024930: return 2315;
+ case 0xFF004438: return 2734;
+ case 0xFF2B4C3F: return 2631;
+ case 0xFF282D26: return 2411;
+ case 0xFFF2EABC: return 2316;
+ case 0xFFCCC693: return 2250;
+ case 0xFF5E663A: return 2317;
+ case 0xFF779182: return 2202;
+ /* case 0xFFC9E8DD: return 2318; TODO: duplicate case value */
+ /* case 0xFF93DDDB: return 2452; TODO: duplicate case value */
+ /* case 0xFF93DDDB: return 2393; TODO: duplicate case value */
+ case 0xFFB5E8BF: return 2238;
+ case 0xFFAADD6D: return 2279;
+ case 0xFFA0DB8E: return 2211;
+ case 0xFFB5CC8E: return 2319;
+ case 0xFF8CD600: return 2320;
+ case 0xFF56AA1C: return 2738;
+ case 0xFF339E35: return 2214;
+ case 0xFF007A3D: return 2453;
+ /* case 0xFF007A3D: return 2410; TODO: duplicate case value */
+ /* case 0xFF007A3D: return 2240; TODO: duplicate case value */
+ case 0xFF008751: return 2208;
+ case 0xFF006B3F: return 2454;
+ case 0xFF006854: return 2607;
+ case 0xFF1EB53A: return 2578;
+ case 0xFF009E49: return 2579;
+ /* case 0xFF009E49: return 2580; TODO: duplicate case value */
+ /* case 0xFF006B3F: return 2284; TODO: duplicate case value */
+ case 0xFF006B54: return 2455;
+ case 0xFF007C66: return 2597;
+ case 0xFFA3AF07: return 2456;
+ case 0xFF7FBA00: return 2321;
+ /* case 0xFF7FBA00: return 2457; TODO: duplicate case value */
+ /* case 0xFF7FBA00: return 2322; TODO: duplicate case value */
+ case 0xFF568E14: return 2226;
+ case 0xFF939905: return 2230;
+ case 0xFF566314: return 2229;
+ /* case 0xFF024930: return 2458; TODO: duplicate case value */
+ case 0xFF547730: return 2595;
+ case 0xFF3F4926: return 2601;
+ case 0xFF3A7728: return 2209;
+ case 0xFF193833: return 2459;
+ case 0xFF215B33: return 2323;
+ case 0xFF265142: return 2460;
+ /* case 0xFF3F4926: return 2584; TODO: duplicate case value */
+ case 0xFF99840A: return 2542;
+ case 0xFFA38205: return 2543;
+ case 0xFF897719: return 2544;
+ case 0xFF707014: return 2545;
+ case 0xFF848205: return 2546;
+ case 0xFFE2E584: return 2547;
+ case 0xFF998E07: return 2548;
+ case 0xFF00494F: return 2549;
+ /* case 0xFF4F6D5E: return 2550; TODO: duplicate case value */
+ /* case 0xFF779182: return 2551; TODO: duplicate case value */
+ case 0xFF546856: return 2554;
+ case 0xFF0C3026: return 2552;
+ case 0xFF233A2D: return 2553;
+ case 0xFF213D30: return 2728;
+ case 0xFFC9D6A3: return 2555;
+ case 0xFFE0AA0F: return 2556;
+ case 0xFFF4E287: return 2557;
+ case 0xFFFFC61E: return 2558;
+ case 0xFFF7E8AA: return 2559;
+ case 0xFFF9DD16: return 2560;
+ case 0xFFC6A00C: return 2561;
+ case 0xFFA37F14: return 2562;
+ /* case 0xFFF7E8AA: return 2324; TODO: duplicate case value */
+ /* case 0xFFF7E8AA: return 2264; TODO: duplicate case value */
+ case 0xFFEADD96: return 2461;
+ case 0xFFF9E08C: return 2732;
+ case 0xFFFFD87F: return 2234;
+ case 0xFFFCD856: return 2408;
+ case 0xFFFCA311: return 2394;
+ /* case 0xFFFCA311: return 2409; TODO: duplicate case value */
+ /* case 0xFFFCA311: return 2213; TODO: duplicate case value */
+ /* case 0xFFF9DD16: return 2462; TODO: duplicate case value */
+ case 0xFFF4ED47: return 2325;
+ case 0xFFF9E814: return 2326;
+ case 0xFFFCB514: return 2463;
+ case 0xFFFFCC49: return 2395;
+ /* case 0xFFFFC61E: return 2464; TODO: duplicate case value */
+ case 0xFFFCBF49: return 2465;
+ case 0xFFFCE016: return 2235;
+ /* case 0xFFFFC61E: return 2626; TODO: duplicate case value */
+ case 0xFFFCD116: return 2466;
+ /* case 0xFFFCD116: return 2242; TODO: duplicate case value */
+ /* case 0xFFFFCC49: return 2396; TODO: duplicate case value */
+ case 0xFFF99B0C: return 2327;
+ case 0xFFF77F00: return 2328;
+ case 0xFFF74902: return 2467;
+ /* case 0xFFF74902: return 2397; TODO: duplicate case value */
+ case 0xFFF95602: return 2236;
+ case 0xFFF93F26: return 2329;
+ /* case 0xFFF95602: return 2468; TODO: duplicate case value */
+ case 0xFFF96B07: return 2218;
+ case 0xFFF96302: return 2469;
+ case 0xFFA53F0F: return 2581;
+ case 0xFFFC8744: return 2330;
+ case 0xFFBC4F07: return 2289;
+ case 0xFFAF7505: return 2295;
+ case 0xFFC18E60: return 2493;
+ case 0xFFFCCE87: return 2398;
+ /* case 0xFFFFCC49: return 2605; TODO: duplicate case value */
+ case 0xFFFCBA5E: return 2247;
+ /* case 0xFFFFCC49: return 2216; TODO: duplicate case value */
+ /* case 0xFFE0AA0F: return 2331; TODO: duplicate case value */
+ /* case 0xFFE0AA0F: return 2212; TODO: duplicate case value */
+ /* case 0xFFE0AA0F: return 2470; TODO: duplicate case value */
+ case 0xFFF2BF49: return 2332;
+ /* case 0xFFFCCE87: return 2399; TODO: duplicate case value */
+ case 0xFFE2D6B5: return 2630;
+ /* case 0xFFC6A00C: return 2596; TODO: duplicate case value */
+ /* case 0xFFA37F14: return 2333; TODO: duplicate case value */
+ /* case 0xFFC6A00C: return 2471; TODO: duplicate case value */
+ case 0xFFBF910C: return 2201;
+ case 0xFFEAB2B2: return 2299;
+ case 0xFFC13828: return 2205;
+ case 0xFFA03033: return 2334;
+ /* case 0xFFAF1E2D: return 2623; TODO: duplicate case value */
+ /* case 0xFFAF1E2D: return 2472; TODO: duplicate case value */
+ case 0xFFFAE6CC: return 2582;
+ case 0xFFFAE6CF: return 2335;
+ case 0xFFF7D3B5: return 2473;
+ case 0xFFEDD3BC: return 2232;
+ case 0xFFAA753F: return 2489;
+ case 0xFFD3A87C: return 2273;
+ case 0xFFEDD3B5: return 2593;
+ case 0xFFC1A875: return 2474;
+ case 0xFFE2BF9B: return 2203;
+ /* case 0xFFD3A87C: return 2475; TODO: duplicate case value */
+ /* case 0xFFBF910C: return 2400; TODO: duplicate case value */
+ case 0xFFD18E54: return 2401;
+ case 0xFFD8B596: return 2336;
+ case 0xFFD6CCAF: return 2476;
+ case 0xFFF2E3C4: return 2604;
+ /* case 0xFFAA753F: return 2224; TODO: duplicate case value */
+ case 0xFF6B4714: return 2477;
+ case 0xFFD1BF91: return 2298;
+ case 0xFF6C463D: return 2610;
+ case 0xFF876028: return 2227;
+ case 0xFF755426: return 2629;
+ /* case 0xFF755426: return 2478; TODO: duplicate case value */
+ case 0xFFB28260: return 2488;
+ case 0xFF593D2B: return 2251;
+ /* case 0xFF593D2B: return 2372; TODO: duplicate case value */
+ case 0xFF3F302B: return 2337;
+ /* case 0xFFC18E60: return 2338; TODO: duplicate case value */
+ /* case 0xFFAF7505: return 2479; TODO: duplicate case value */
+ case 0xFFBA7530: return 2231;
+ /* case 0xFF755426: return 2402; TODO: duplicate case value */
+ case 0xFFB26B70: return 2480;
+ case 0xFFA2464E: return 2611;
+ case 0xFF9B4F19: return 2290;
+ /* case 0xFF9B4F19: return 2481; TODO: duplicate case value */
+ case 0xFF5B2D28: return 2339;
+ /* case 0xFF593D2B: return 2563; TODO: duplicate case value */
+ /* case 0xFF3F302B: return 2564; TODO: duplicate case value */
+ case 0xFF3D3028: return 2566;
+ case 0xFF633A11: return 2567;
+ /* case 0xFFC1A875: return 2568; TODO: duplicate case value */
+ case 0xFF7A5B11: return 2569;
+ /* case 0xFFC1A875: return 2570; TODO: duplicate case value */
+ /* case 0xFFF2BF49: return 2586; TODO: duplicate case value */
+ case 0xFFF2CE68: return 2606;
+ case 0xFFD88C02: return 2602;
+ case 0xFFC1B5A5: return 2571;
+ case 0xFF99897C: return 2739;
+ case 0xFFADA07A: return 2572;
+ /* case 0xFFADA07A: return 2573; TODO: duplicate case value */
+ case 0xFFF5E3CC: return 2574;
+ case 0xFF66594C: return 2575;
+ case 0xFF493533: return 2576;
+ case 0xFFF5EBE0: return 2403;
+ /* case 0xFFDDC6C4: return 2207; TODO: duplicate case value */
+ case 0xFFDBD3D3: return 2340;
+ case 0xFFD8CCD1: return 2274;
+ case 0xFFCCC1C6: return 2482;
+ case 0xFFAFAAA3: return 2483;
+ /* case 0xFFADAFAA: return 2592; TODO: duplicate case value */
+ case 0xFF919693: return 2585;
+ /* case 0xFF8C8984: return 2484; TODO: duplicate case value */
+ /* case 0xFFCCC1C6: return 2404; TODO: duplicate case value */
+ /* case 0xFFDBD3D3: return 2485; TODO: duplicate case value */
+ /* case 0xFFCCC1C6: return 2405; TODO: duplicate case value */
+ case 0xFFB2A8B5: return 2486;
+ case 0xFFA893AD: return 2406;
+ case 0xFF666D70: return 2407;
+ /* case 0xFF686663: return 2217; TODO: duplicate case value */
+ /* case 0xFF443D38: return 2565; TODO: duplicate case value */
+ case 0xFF777772: return 2265;
+ case 0xFF353842: return 2487;
+ case 0xFF3A4972: return 2341;
+ case 0xFF1C2630: return 2296;
+ /* case 0xFFF5EBE0: return 2297; TODO: duplicate case value */
+ case 0xFFF5EDDE: return 2342;
+ case 0xFFF0E8D6: return 2343;
+ /* case 0xFF1C2630: return 2632; TODO: duplicate case value */
+
+ /* BEGIN N/A COLORS */
+ /*
+ return 2344;
+ return 2345;
+ return 2346;
+ return 2347;
+ return 2348;
+ return 2349;
+ return 2350;
+ return 2351;
+ return 2352;
+ return 2353;
+ return 2354;
+ return 2355;
+ return 2583;
+ return 2356;
+ return 2357;
+ return 2358;
+ return 2359;
+ return 2360;
+ return 2361;
+ return 2362;
+ return 2363;
+ return 2364;
+ return 2365;
+ return 2366;
+ return 2367;
+ return 2368;
+ return 2369;
+ return 2370;
+ return 2371;
+ */
+ /* END N/A COLORS */
+ }
+
+ return -1;
+}
+
+const char* getName_RobisonAnton_Rayon(unsigned int color)
+{
+ switch(color)
+ {
+ case 0xFFEFCCCE: return "Light Pink";
+ case 0xFFFCBFC9: return "Pink";
+ case 0xFFEFC6D3: return "Pink Bazaar";
+ case 0xFFF9B2B7: return "Pink Mist";
+ case 0xFFF9AFAD: return "Emily Pink";
+ case 0xFFFC9BB2: return "Rose";
+ case 0xFFFC8C99: return "Rose Cerise";
+ case 0xFFF2AFC1: return "Carnation";
+ case 0xFFE5566D: return "Shrimp";
+ case 0xFFF4476B: return "Bashful Pink";
+ /* case 0xFFE5566D: return "Begonia"; TODO: duplicate case value */
+ case 0xFFF9848E: return "Azalea";
+ case 0xFFF26877: return "Dusty Rose";
+ case 0xFFD8899B: return "Rose Tint";
+ case 0xFF8C2633: return "Burgundy";
+ case 0xFF7C2128: return "TH Burgundy";
+ case 0xFF7A2638: return "Russet";
+ case 0xFF75263D: return "Pro Firebrand";
+ case 0xFF772D35: return "Wine";
+ case 0xFF593344: return "Intense Maroon";
+ case 0xFF4F213A: return "Dark Maroon";
+ case 0xFF931638: return "Carbernet";
+ /* case 0xFFF9B2B7: return "Mountain Rose"; TODO: duplicate case value */
+ case 0xFF661E2B: return "Warm Wine";
+ /* case 0xFFE5566D: return "Primrose"; TODO: duplicate case value */
+ case 0xFF8E2344: return "Perfect Ruby";
+ case 0xFF6D213F: return "Brushed Burgundy";
+ /* case 0xFF8E2344: return "Passion Rose"; TODO: duplicate case value */
+ case 0xFFAD0075: return "New Berry";
+ case 0xFFFCC9C6: return "Petal Pink";
+ case 0xFFF4BFD1: return "Memphis Belle";
+ case 0xFFF7BFBF: return "Desert Bloom";
+ case 0xFFCE007C: return "Wild Pink";
+ case 0xFFED72AA: return "Floral Pink";
+ case 0xFFD36B9E: return "Hot Pink";
+ case 0xFFD60270: return "Crimson";
+ case 0xFFE22882: return "Ruby Glint";
+ case 0xFFAA004F: return "Cherrystone";
+ /* case 0xFFAA004F: return "Cherry Punch"; TODO: duplicate case value */
+ case 0xFFEA0F6B: return "Cherry Blossom";
+ case 0xFFAF1E2D: return "Red Berry";
+ case 0xFFBF0A30: return "Jockey Red";
+ /* case 0xFFBF0A30: return "Very Red"; TODO: duplicate case value */
+ /* case 0xFFBF0A30: return "Red Berry"; TODO: duplicate case value */
+ case 0xFFCE1126: return "Foxy Red";
+ case 0xFFD62828: return "Tuxedo Red";
+ /* case 0xFFBF0A30: return "Lipstick"; TODO: duplicate case value */
+ case 0xFFC41E3A: return "Scarlet";
+ /* case 0xFFC41E3A: return "Radiant Red"; TODO: duplicate case value */
+ case 0xFFA32638: return "Wildfire";
+ /* case 0xFF8C2633: return "Carolina Red"; TODO: duplicate case value */
+ /* case 0xFF75263D: return "Red Jubilee"; TODO: duplicate case value */
+ case 0xFF992135: return "Cranberry";
+ /* case 0xFFA32638: return "Antique Red"; TODO: duplicate case value */
+ /* case 0xFFC41E3A: return "Devil Red"; TODO: duplicate case value */
+ case 0xFFAF003D: return "Candy Apple Red";
+ case 0xFFD81C3F: return "Rosewood";
+ case 0xFFFC5E72: return "Bitteroot";
+ case 0xFFF2C4AF: return "Bisque";
+ case 0xFFF4CCAA: return "Flesh";
+ case 0xFFF9BAAA: return "Flesh Pink";
+ /* case 0xFFF7BFBF: return "Opal Mist"; TODO: duplicate case value */
+ case 0xFFF9BF9E: return "Tawny";
+ case 0xFFF9C6AA: return "Peach";
+ case 0xFFF98E6D: return "Melon";
+ case 0xFFF9A58C: return "Flamingo";
+ case 0xFFF98972: return "Coral";
+ case 0xFFF43F4F: return "Persimmon";
+ /* case 0xFFF9C6AA: return "Peach Blossom"; TODO: duplicate case value */
+ /* case 0xFFF9BAAA: return "Illusion"; TODO: duplicate case value */
+ /* case 0xFFF98972: return "Melonade"; TODO: duplicate case value */
+ case 0xFFE23D28: return "Honeysuckle";
+ case 0xFF008C82: return "Brite Jade";
+ case 0xFF00B2A0: return "Bluestone";
+ case 0xFF47D6C1: return "Aqua Pearl";
+ case 0xFF87DDD1: return "Seafrost";
+ case 0xFF008789: return "J. Turquoise";
+ case 0xFF2DC6D6: return "Indian Ocean Blue";
+ case 0xFF00A5DB: return "Surf Blue";
+ case 0xFF00A3DD: return "Mid Windsor";
+ case 0xFF003F54: return "Deep Windsor";
+ case 0xFF002D47: return "Pro Dark Blue";
+ case 0xFF006D75: return "Mallard Blue";
+ case 0xFF9BC4E2: return "Sky Blue";
+ case 0xFFAFBCDB: return "Lake Blue";
+ case 0xFF5B77CC: return "Pro Lusty Blue";
+ case 0xFF6D87A8: return "Slate Blue";
+ case 0xFF99D6DD: return "Blue Frost";
+ case 0xFF28C4D8: return "Periwinkle";
+ case 0xFF00ADC6: return "Aquamarine";
+ case 0xFF00A0C4: return "California Blue";
+ case 0xFF008ED6: return "Baltic Blue";
+ case 0xFF0054A0: return "Solar Blue";
+ /* case 0xFF008ED6: return "Pacific Blue"; TODO: duplicate case value */
+ /* case 0xFF00A3DD: return "Boo Boo Blue"; TODO: duplicate case value */
+ case 0xFF00709E: return "Pro Band Blue";
+ case 0xFF007AA5: return "Pro Peacock";
+ case 0xFFC9E8DD: return "Light Blue";
+ case 0xFF1E1C77: return "Royal";
+ case 0xFF002B7F: return "Blue Suede";
+ case 0xFF335687: return "Imperial Blue";
+ /* case 0xFFAFBCDB: return "Bridgeport Blue"; TODO: duplicate case value */
+ /* case 0xFF335687: return "China Blue"; TODO: duplicate case value */
+ case 0xFF26547C: return "Pro Imperial";
+ case 0xFF7796B2: return "Country Blue";
+ case 0xFFC1C9DD: return "Heron Blue";
+ /* case 0xFF7796B2: return "Pro Saxon"; TODO: duplicate case value */
+ case 0xFF6689CC: return "Bright Blue";
+ case 0xFF5960A8: return "Soldier Blue";
+ case 0xFF0051BA: return "Pro Brilliance";
+ /* case 0xFF6689CC: return "Atlantis Blue"; TODO: duplicate case value */
+ case 0xFF3A75C4: return "Dolphin Blue";
+ case 0xFF75AADB: return "Caribbean Blue";
+ case 0xFFC4D8E2: return "Dana Blue";
+ /* case 0xFFC4D8E2: return "Cadet Blue"; TODO: duplicate case value */
+ case 0xFF60AFDD: return "Ozone";
+ case 0xFF003D6B: return "Salem Blue";
+ case 0xFF0F2B5B: return "Blue Ribbon";
+ case 0xFF192168: return "Pro Navy";
+ case 0xFF2B265B: return "Blue Ink";
+ case 0xFF002654: return "Pro Midnight";
+ case 0xFF002649: return "Pro College Blue";
+ case 0xFF353F5B: return "Light Midnight";
+ case 0xFF35264F: return "Fleet Blue";
+ case 0xFF112151: return "Light Navy";
+ case 0xFF14213D: return "Flag Blue";
+ /* case 0xFF002654: return "TH Navy"; TODO: duplicate case value */
+ /* case 0xFF14213D: return "Navy"; TODO: duplicate case value */
+ /* case 0xFF14213D: return "Midnight Navy"; TODO: duplicate case value */
+ case 0xFFC6D1D6: return "Pastel Blue";
+ /* case 0xFFC1C9DD: return "Blue Hint"; TODO: duplicate case value */
+ case 0xFFB5D1E8: return "Ice Blue";
+ case 0xFFD1CEDD: return "Paris Blue";
+ case 0xFF99BADD: return "Baby Blue";
+ /* case 0xFFAFBCDB: return "Sun Blue"; TODO: duplicate case value */
+ case 0xFFA5BAE0: return "Cristy Blue";
+ case 0xFF75B2DD: return "Ultra Blue";
+ /* case 0xFF75AADB: return "Tropic Blue"; TODO: duplicate case value */
+ /* case 0xFF6689CC: return "Blue Horizon"; TODO: duplicate case value */
+ case 0xFF7F8CBF: return "Oriental Blue";
+ /* case 0xFF6D87A8: return "Copen"; TODO: duplicate case value */
+ /* case 0xFF5B77CC: return "Jay Blue"; TODO: duplicate case value */
+ case 0xFF2D338E: return "Blue";
+ /* case 0xFF2D338E: return "Sapphire"; TODO: duplicate case value */
+ case 0xFF00337F: return "Pro Royal";
+ case 0xFF003893: return "Fire Blue";
+ /* case 0xFF2D338E: return "Jamie Blue"; TODO: duplicate case value */
+ case 0xFF3F2893: return "Empire Blue";
+ case 0xFF3A564F: return "Enchanted Sea";
+ case 0xFF8499A5: return "Pro Twinkle";
+ case 0xFF9BAABF: return "Rockport Blue";
+ case 0xFF5E99AA: return "Wonder Blue";
+ case 0xFFADAFAA: return "Traditional Gray";
+ case 0xFFBFBAAF: return "Steel";
+ case 0xFFBAB7AF: return "Pro Pearl";
+ case 0xFFC4C1BA: return "Pro Cool Gray";
+ case 0xFFCCC1B2: return "Stainless Steel";
+ case 0xFFD1CCBF: return "Chrome";
+ /* case 0xFFADAFAA: return "Pro Night Sky"; TODO: duplicate case value */
+ case 0xFF8C8984: return "Gull";
+ case 0xFF686663: return "Mineral";
+ case 0xFF443D38: return "Black Chrome";
+ case 0xFFDDC6C4: return "Heather";
+ case 0xFFD3B7A3: return "Grape";
+ case 0xFFB5939B: return "Satin Wine";
+ case 0xFF8E6877: return "Ducky Mauve";
+ /* case 0xFFFCBFC9: return "Pale Orchid"; TODO: duplicate case value */
+ case 0xFFE5BFC6: return "Orchid";
+ /* case 0xFFEFC6D3: return "Lavender"; TODO: duplicate case value */
+ case 0xFFEDC4DD: return "Violet";
+ case 0xFFB58CB2: return "Cachet";
+ case 0xFFC9ADD8: return "Tulip";
+ case 0xFFE29ED6: return "Mid Lilac";
+ case 0xFF512654: return "Port Wine";
+ case 0xFF512D44: return "Pro Maroon";
+ case 0xFF8E47AD: return "Laurie Lilac";
+ case 0xFFAF72C1: return "Iris";
+ case 0xFF9B4F96: return "Raspberry";
+ case 0xFF66116D: return "Mulberry";
+ case 0xFF63305E: return "Plum Wine";
+ /* case 0xFF1E1C77: return "Purple Twist"; TODO: duplicate case value */
+ case 0xFF332875: return "Violet Blue";
+ case 0xFF35006D: return "Purple Maze";
+ case 0xFF2B1166: return "Pro Brite Star";
+ case 0xFF38197A: return "Pro Violet";
+ /* case 0xFF35006D: return "Pro Purple"; TODO: duplicate case value */
+ /* case 0xFF8E47AD: return "Purple"; TODO: duplicate case value */
+ case 0xFF5B027A: return "Purple Shadow";
+ case 0xFF4C145E: return "Dark Purple";
+ case 0xFF8977BA: return "Mauve";
+ case 0xFF44235E: return "Purple Accent";
+ case 0xFFAA0066: return "Hot Peony";
+ /* case 0xFFCE007C: return "Passion"; TODO: duplicate case value */
+ /* case 0xFFAA004F: return "Strawberry"; TODO: duplicate case value */
+ case 0xFF9E2387: return "Plum";
+ /* case 0xFF5E99AA: return "Misty"; TODO: duplicate case value */
+ case 0xFF609191: return "Mystic Teal";
+ /* case 0xFF609191: return "Teal"; TODO: duplicate case value */
+ /* case 0xFF003F54: return "Dark Teal"; TODO: duplicate case value */
+ case 0xFF93DDDB: return "Mint Julep";
+ case 0xFF7FD6DB: return "Turquoise";
+ case 0xFF007272: return "M.D. Green";
+ case 0xFF70CE9B: return "Seafoam";
+ /* case 0xFF70CE9B: return "Isle Green"; TODO: duplicate case value */
+ case 0xFF35C4AF: return "Peppermint";
+ /* case 0xFF006D75: return "Oceanic Green"; TODO: duplicate case value */
+ case 0xFF006B77: return "Pro Teal";
+ case 0xFF006663: return "Garden Green";
+ case 0xFF006D66: return "Pro Green";
+ /* case 0xFF008C82: return "Pine Green"; TODO: duplicate case value */
+ case 0xFF008272: return "Greenstone";
+ /* case 0xFF006663: return "Fern Green"; TODO: duplicate case value */
+ /* case 0xFF006D66: return "Pro Hunter"; TODO: duplicate case value */
+ case 0xFFBCC1B2: return "Palm Leaf";
+ case 0xFFC6D6A0: return "Flite Green";
+ case 0xFF9EAA99: return "Willow";
+ case 0xFFB2D8D8: return "Sprite";
+ case 0xFF7AA891: return "Moss";
+ /* case 0xFF7AA891: return "Wintergreen"; TODO: duplicate case value */
+ case 0xFF006056: return "Green Forest";
+ /* case 0xFF006056: return "Pro Forest"; TODO: duplicate case value */
+ case 0xFF4F6D5E: return "Harbor Green";
+ case 0xFF024930: return "Evergreen";
+ case 0xFF004438: return "Pro Dark Green";
+ case 0xFF2B4C3F: return "Lizzy Lime";
+ case 0xFF282D26: return "D.H. Green";
+ case 0xFFF2EABC: return "Celery";
+ case 0xFFCCC693: return "Pistachio";
+ case 0xFF5E663A: return "Olive Drab";
+ case 0xFF779182: return "Olive";
+ /* case 0xFFC9E8DD: return "Pale Green"; TODO: duplicate case value */
+ /* case 0xFF93DDDB: return "Green Pearl"; TODO: duplicate case value */
+ /* case 0xFF93DDDB: return "Sea Mist"; TODO: duplicate case value */
+ case 0xFFB5E8BF: return "Mint";
+ case 0xFFAADD6D: return "Spruce";
+ case 0xFFA0DB8E: return "Nile";
+ case 0xFFB5CC8E: return "Green Oak";
+ case 0xFF8CD600: return "Erin Green";
+ case 0xFF56AA1C: return "Pro Erin";
+ case 0xFF339E35: return "Emerald";
+ case 0xFF007A3D: return "Dark Emerald";
+ /* case 0xFF007A3D: return "Light Kelly"; TODO: duplicate case value */
+ /* case 0xFF007A3D: return "Kelly"; TODO: duplicate case value */
+ case 0xFF008751: return "Dark Green";
+ case 0xFF006B3F: return "Fleece Green";
+ case 0xFF006854: return "TH Green";
+ case 0xFF1EB53A: return "Harvest Green";
+ case 0xFF009E49: return "Vibrant Green";
+ /* case 0xFF009E49: return "Green Grass"; TODO: duplicate case value */
+ /* case 0xFF006B3F: return "Deep Green"; TODO: duplicate case value */
+ case 0xFF006B54: return "Green Bay";
+ case 0xFF007C66: return "Jungle Green";
+ case 0xFFA3AF07: return "Peapod";
+ case 0xFF7FBA00: return "Pastoral Green";
+ /* case 0xFF7FBA00: return "Green Dust"; TODO: duplicate case value */
+ /* case 0xFF7FBA00: return "Ming"; TODO: duplicate case value */
+ case 0xFF568E14: return "Meadow";
+ case 0xFF939905: return "Tamarack";
+ case 0xFF566314: return "Palmetto";
+ /* case 0xFF024930: return "Green Petal"; TODO: duplicate case value */
+ case 0xFF547730: return "Sage";
+ case 0xFF3F4926: return "Hedge";
+ case 0xFF3A7728: return "Green";
+ case 0xFF193833: return "Green Sail";
+ case 0xFF215B33: return "Holly";
+ case 0xFF265142: return "Field Green";
+ /* case 0xFF3F4926: return "Dress Green"; TODO: duplicate case value */
+ case 0xFF99840A: return "Foliage Green";
+ case 0xFFA38205: return "Autumn Green";
+ case 0xFF897719: return "Desert Cactus";
+ case 0xFF707014: return "Cypress";
+ case 0xFF848205: return "Crescent Moon";
+ case 0xFFE2E584: return "Pebblestone";
+ case 0xFF998E07: return "Sun Shadow";
+ case 0xFF00494F: return "Blue Spruce";
+ /* case 0xFF4F6D5E: return "Newport"; TODO: duplicate case value */
+ /* case 0xFF779182: return "Spring Garden"; TODO: duplicate case value */
+ case 0xFF546856: return "Water Lilly";
+ case 0xFF0C3026: return "Ivy";
+ case 0xFF233A2D: return "Dark Army Green";
+ case 0xFF213D30: return "Army Green";
+ case 0xFFC9D6A3: return "Pastel Green";
+ case 0xFFE0AA0F: return "Pollen Gold";
+ case 0xFFF4E287: return "Pale Yellow";
+ case 0xFFFFC61E: return "Buttercup";
+ case 0xFFF7E8AA: return "Tusk";
+ case 0xFFF9DD16: return "Moonbeam";
+ case 0xFFC6A00C: return "Black Eyed Susie";
+ case 0xFFA37F14: return "Bullion";
+ /* case 0xFFF7E8AA: return "Chinese Yellow"; TODO: duplicate case value */
+ /* case 0xFFF7E8AA: return "Maize"; TODO: duplicate case value */
+ case 0xFFEADD96: return "Wheat";
+ case 0xFFF9E08C: return "Pro Maize";
+ case 0xFFFFD87F: return "Glow";
+ case 0xFFFCD856: return "Star Gold";
+ case 0xFFFCA311: return "Mango";
+ /* case 0xFFFCA311: return "Yellow Mist"; TODO: duplicate case value */
+ /* case 0xFFFCA311: return "Yellow"; TODO: duplicate case value */
+ /* case 0xFFF9DD16: return "Sunflower"; TODO: duplicate case value */
+ case 0xFFF4ED47: return "Lemon";
+ case 0xFFF9E814: return "Daffodil";
+ case 0xFFFCB514: return "Merit Gold";
+ case 0xFFFFCC49: return "Cornsilk";
+ /* case 0xFFFFC61E: return "Nectar"; TODO: duplicate case value */
+ case 0xFFFCBF49: return "Scholastic";
+ case 0xFFFCE016: return "Canary Yellow";
+ /* case 0xFFFFC61E: return "Pro Gold"; TODO: duplicate case value */
+ case 0xFFFCD116: return "Manila";
+ /* case 0xFFFCD116: return "Goldenrod"; TODO: duplicate case value */
+ /* case 0xFFFFCC49: return "Brite Yellow"; TODO: duplicate case value */
+ case 0xFFF99B0C: return "Honeydew";
+ case 0xFFF77F00: return "Pumpkin";
+ case 0xFFF74902: return "Orangeade";
+ /* case 0xFFF74902: return "Sun Orange"; TODO: duplicate case value */
+ case 0xFFF95602: return "Paprika";
+ case 0xFFF93F26: return "Saffron";
+ /* case 0xFFF95602: return "Tex Orange"; TODO: duplicate case value */
+ case 0xFFF96B07: return "Orange";
+ case 0xFFF96302: return "Dark Tex Orange";
+ case 0xFFA53F0F: return "Old Dark Tex Orange";
+ case 0xFFFC8744: return "Golden Poppy";
+ case 0xFFBC4F07: return "Rust";
+ case 0xFFAF7505: return "Copper";
+ case 0xFFC18E60: return "Light Bronze";
+ case 0xFFFCCE87: return "Visor Gold";
+ /* case 0xFFFFCC49: return "Goldenlite"; TODO: duplicate case value */
+ case 0xFFFCBA5E: return "Honey";
+ /* case 0xFFFFCC49: return "Marigold"; TODO: duplicate case value */
+ /* case 0xFFE0AA0F: return "Mustard"; TODO: duplicate case value */
+ /* case 0xFFE0AA0F: return "Sun Gold"; TODO: duplicate case value */
+ /* case 0xFFE0AA0F: return "Karat"; TODO: duplicate case value */
+ case 0xFFF2BF49: return "Penny";
+ /* case 0xFFFCCE87: return "New Gold"; TODO: duplicate case value */
+ case 0xFFE2D6B5: return "Pro Beige";
+ /* case 0xFFC6A00C: return "Marine Gold"; TODO: duplicate case value */
+ /* case 0xFFA37F14: return "Ginger"; TODO: duplicate case value */
+ /* case 0xFFC6A00C: return "Shimmering Gold"; TODO: duplicate case value */
+ case 0xFFBF910C: return "Old Gold";
+ case 0xFFEAB2B2: return "Salmon";
+ case 0xFFC13828: return "Dark Rust";
+ case 0xFFA03033: return "Terra Cotta";
+ /* case 0xFFAF1E2D: return "Pro Red"; TODO: duplicate case value */
+ /* case 0xFFAF1E2D: return "Auburn"; TODO: duplicate case value */
+ case 0xFFFAE6CC: return "Bone";
+ case 0xFFFAE6CF: return "Ivory";
+ case 0xFFF7D3B5: return "Opaline";
+ case 0xFFEDD3BC: return "Ecru";
+ case 0xFFAA753F: return "Wicker";
+ case 0xFFD3A87C: return "Tan";
+ case 0xFFEDD3B5: return "Cottage Beige";
+ case 0xFFC1A875: return "Rattan";
+ case 0xFFE2BF9B: return "Gold";
+ /* case 0xFFD3A87C: return "Mocha Cream"; TODO: duplicate case value */
+ /* case 0xFFBF910C: return "Topaz"; TODO: duplicate case value */
+ case 0xFFD18E54: return "Ashley Gold";
+ case 0xFFD8B596: return "Amber Beige";
+ case 0xFFD6CCAF: return "Seashell";
+ case 0xFFF2E3C4: return "Light Maize";
+ /* case 0xFFAA753F: return "Beige"; TODO: duplicate case value */
+ case 0xFF6B4714: return "Sand Dune";
+ case 0xFFD1BF91: return "Taupe";
+ case 0xFF6C463D: return "Pro Brown";
+ case 0xFF876028: return "Chocolate";
+ case 0xFF755426: return "Pro Walnut";
+ /* case 0xFF755426: return "Light Cocoa"; TODO: duplicate case value */
+ case 0xFFB28260: return "Cocoa Mulch";
+ case 0xFF593D2B: return "Brown";
+ /* case 0xFF593D2B: return "Dark Brown"; TODO: duplicate case value */
+ case 0xFF3F302B: return "Espresso";
+ /* case 0xFFC18E60: return "Bamboo"; TODO: duplicate case value */
+ /* case 0xFFAF7505: return "Almond"; TODO: duplicate case value */
+ case 0xFFBA7530: return "Toast";
+ /* case 0xFF755426: return "Sienna"; TODO: duplicate case value */
+ case 0xFFB26B70: return "K.A. Bronze";
+ case 0xFFA2464E: return "Pro Cinnamon";
+ case 0xFF9B4F19: return "Date";
+ /* case 0xFF9B4F19: return "Hazel"; TODO: duplicate case value */
+ case 0xFF5B2D28: return "Coffee Bean";
+ /* case 0xFF593D2B: return "Dogwood"; TODO: duplicate case value */
+ /* case 0xFF3F302B: return "Mahogany"; TODO: duplicate case value */
+ case 0xFF3D3028: return "Best Brown";
+ case 0xFF633A11: return "Mushroom";
+ /* case 0xFFC1A875: return "Perfect Tan"; TODO: duplicate case value */
+ case 0xFF7A5B11: return "Earthen Tan";
+ /* case 0xFFC1A875: return "Golden Tan"; TODO: duplicate case value */
+ /* case 0xFFF2BF49: return "14 Kt. Gold"; TODO: duplicate case value */
+ case 0xFFF2CE68: return "TH Gold";
+ case 0xFFD88C02: return "24 Kt. Gold";
+ case 0xFFC1B5A5: return "Platinum";
+ case 0xFF99897C: return "Pro Gray";
+ case 0xFFADA07A: return "Grayrod";
+ /* case 0xFFADA07A: return "Pewter"; TODO: duplicate case value */
+ case 0xFFF5E3CC: return "Aspen White";
+ case 0xFF66594C: return "Dark Taupe";
+ case 0xFF493533: return "Egyptian Brown";
+ case 0xFFF5EBE0: return "Oyster";
+ /* case 0xFFDDC6C4: return "Gray"; TODO: duplicate case value */
+ case 0xFFDBD3D3: return "Pearl Gray";
+ case 0xFFD8CCD1: return "Steel Gray";
+ case 0xFFCCC1C6: return "Skylight";
+ case 0xFFAFAAA3: return "Cloud";
+ /* case 0xFFADAFAA: return "Silver Steel"; TODO: duplicate case value */
+ case 0xFF919693: return "Banner Gray";
+ /* case 0xFF8C8984: return "Silvery Gray"; TODO: duplicate case value */
+ /* case 0xFFCCC1C6: return "Cinder"; TODO: duplicate case value */
+ /* case 0xFFDBD3D3: return "Saturn Gray"; TODO: duplicate case value */
+ /* case 0xFFCCC1C6: return "Dover Gray"; TODO: duplicate case value */
+ case 0xFFB2A8B5: return "Storm Gray";
+ case 0xFFA893AD: return "Sterling";
+ case 0xFF666D70: return "Metal";
+ /* case 0xFF686663: return "Twilight"; TODO: duplicate case value */
+ /* case 0xFF443D38: return "Aged Charcoal"; TODO: duplicate case value */
+ case 0xFF777772: return "Charcoal";
+ case 0xFF353842: return "Smokey";
+ case 0xFF3A4972: return "Ash";
+ case 0xFF1C2630: return "Black";
+ /* case 0xFFF5EBE0: return "Snow White"; TODO: duplicate case value */
+ case 0xFFF5EDDE: return "Natural White";
+ case 0xFFF0E8D6: return "Eggshell";
+ /* case 0xFF1C2630: return "Jet Black"; TODO: duplicate case value */
+
+ /* BEGIN N/A COLORS */
+ /*
+ return "3CC Red";
+ return "3CC Rose";
+ return "3CC Apricot";
+ return "3CC Pink";
+ return "3CC Purple";
+ return "3CC Lilac";
+ return "3CC Blue";
+ return "3CC Light Blue";
+ return "3CC Turquoise";
+ return "3CC Green";
+ return "3CC Kelly";
+ return "3CC Light Green";
+ return "3CC Olive";
+ return "3CC Yellow";
+ return "3CC Maize";
+ return "3CC Tangerine";
+ return "3CC Orange";
+ return "3CC Brown";
+ return "3CC Nugget";
+ return "3CC Gold";
+ return "3CC Gray";
+ return "3CC Flag";
+ return "3CC Horizon";
+ return "3CC Autumn";
+ return "4CC Fiesta";
+ return "4CC Mexicana";
+ return "4CC Pastel";
+ return "4CC Melody";
+ return "4CC Rainbow";
+ */
+ /* END N/A COLORS */
+ }
+
+ return "";
+}
+
+int getNum_Sigma_Polyester(unsigned int color)
+{
+ switch(color)
+ {
+ case 0xFFFFFFFF: return 10;
+ case 0xFF000000: return 20;
+ case 0xFFEDFF50: return 21;
+ case 0xFF96E845: return 32;
+ case 0xFFFFE756: return 33;
+ case 0xFFFF7824: return 43;
+ case 0xFFF28DA6: return 46;
+ case 0xFFC70C57: return 47;
+ case 0xFFE22D2A: return 101;
+ case 0xFFB8B8B8: return 102;
+ case 0xFF889186: return 112;
+ case 0xFF737F7F: return 115;
+ case 0xFF565E5A: return 116;
+ case 0xFF515250: return 117;
+ case 0xFF787668: return 118;
+ case 0xFFED572F: return 135;
+ case 0xFF2EA59C: return 138;
+ case 0xFF396276: return 142;
+ case 0xFF9B3B40: return 213;
+ case 0xFF6C3E47: return 216;
+ case 0xFFBA6E4D: return 253;
+ case 0xFFBB3D2E: return 255;
+ case 0xFFF9DFCF: return 301;
+ case 0xFFFBDED6: return 303;
+ case 0xFFF7CDD5: return 304;
+ case 0xFFF2AFB4: return 305;
+ case 0xFFE8418C: return 307;
+ case 0xFFE77F9D: return 309;
+ case 0xFFF06F8C: return 313;
+ case 0xFF008340: return 317;
+ case 0xFFDF99B6: return 321;
+ case 0xFF820052: return 325;
+ case 0xFFB1415F: return 333;
+ case 0xFFC394AE: return 345;
+ case 0xFFA86E91: return 347;
+ case 0xFF694169: return 348;
+ case 0xFFE6CFD5: return 376;
+ case 0xFFA8BED7: return 379;
+ case 0xFFA0BFD7: return 380;
+ case 0xFF90A6C6: return 381;
+ case 0xFF8FAFC6: return 382;
+ case 0xFFB1B8D3: return 383;
+ case 0xFF416C9B: return 385;
+ case 0xFF7D77AF: return 386;
+ case 0xFFFADAF4: return 387;
+ case 0xFF664090: return 390;
+ case 0xFFEAF0F9: return 402;
+ case 0xFFA6D8F6: return 403;
+ case 0xFF7B9CB0: return 404;
+ case 0xFF648DC7: return 406;
+ case 0xFF3D6AA1: return 409;
+ case 0xFF2D4491: return 413;
+ case 0xFF143D7A: return 414;
+ case 0xFF113263: return 415;
+ case 0xFF0E1F38: return 423;
+ /* case 0xFF0E1F38: return 432; TODO: duplicate case value */
+ case 0xFF0091A5: return 443;
+ case 0xFF005B63: return 448;
+ case 0xFF00474D: return 449;
+ case 0xFFE5B15C: return 466;
+ case 0xFFD5BF9B: return 501;
+ case 0xFFFFD085: return 503;
+ case 0xFFF6B08E: return 505;
+ case 0xFFB3E851: return 506;
+ case 0xFFF1A236: return 508;
+ case 0xFF6E4337: return 513;
+ case 0xFFD8493E: return 527;
+ case 0xFF697698: return 541;
+ case 0xFFFDE896: return 601;
+ case 0xFFEDE55D: return 602;
+ case 0xFFDFA200: return 609;
+ /* case 0xFFFDE896: return 612; TODO: duplicate case value */
+ case 0xFFCEB24C: return 616;
+ case 0xFFAD953E: return 619;
+ case 0xFFFEF9EA: return 627;
+ case 0xFFBD9565: return 628;
+ case 0xFFFDF76C: return 632;
+ case 0xFFEDEF05: return 633;
+ case 0xFFF8C300: return 646;
+ case 0xFFE77817: return 649;
+ case 0xFFE66535: return 650;
+ case 0xFFC69632: return 652;
+ case 0xFF98996D: return 653;
+ case 0xFFC98300: return 654;
+ case 0xFF007B8D: return 688;
+ case 0xFF004D3D: return 695;
+ case 0xFF007EBA: return 697;
+ case 0xFFCF0040: return 700;
+ case 0xFF28438C: return 809;
+ case 0xFFD0B478: return 812;
+ case 0xFFE5BE6C: return 818;
+ case 0xFF449284: return 825;
+ case 0xFFCFCFCF: return 829;
+ case 0xFFDC875E: return 831;
+ case 0xFFB4705D: return 832;
+ case 0xFF9B5C4B: return 833;
+ case 0xFFA93121: return 838;
+ case 0xFFB18B00: return 842;
+ case 0xFF86462E: return 857;
+ case 0xFF614125: return 859;
+ case 0xFFB25C31: return 864;
+ case 0xFF806A61: return 873;
+ case 0xFF634831: return 878;
+ case 0xFF1A0C06: return 891;
+ case 0xFF96D5C8: return 903;
+ case 0xFFB4DCD8: return 904;
+ case 0xFFAF7D3E: return 905;
+ case 0xFF00A3A0: return 906;
+ case 0xFF00405D: return 913;
+ case 0xFFC9E3C5: return 947;
+ case 0xFF55AF78: return 949;
+ case 0xFF858325: return 951;
+ case 0xFF61601C: return 955;
+ case 0xFF709188: return 961;
+ case 0xFFBEDC8C: return 984;
+ case 0xFFBEE678: return 985;
+ case 0xFF76C850: return 988;
+ case 0xFF466E64: return 448;
+ case 0xFF356936: return 992;
+ case 0xFF4B4884: return 1031;
+ case 0xFFEDEDD2: return 1140;
+ case 0xFFF3D8A8: return 1145;
+ case 0xFFC8BE96: return 1148;
+ case 0xFF243A7D: return 1163;
+ case 0xFF86BE4E: return 1183;
+ case 0xFF8E4044: return 1241;
+ case 0xFF893480: return 1323;
+ case 0xFF8C6DAA: return 1324;
+ case 0xFFB6A36C: return 1552;
+ case 0xFF2E9F76: return 1615;
+ case 0xFF98C173: return 1619;
+ case 0xFFCDCDCD: return 1707;
+ case 0xFF2A377E: return 2031;
+ case 0xFF006CA5: return 2093;
+ case 0xFF834455: return 2250;
+ case 0xFFD0A44F: return 2518;
+ case 0xFFED9206: return 2519;
+ /* case 0xFFEDEF05: return 3001; TODO: duplicate case value */
+ case 0xFFC07A46: return 3014;
+ case 0xFFB43C3C: return 3015;
+ case 0xFF915F46: return 3142;
+ case 0xFFFFC500: return 4117;
+ case 0xFFA68A68: return 4371;
+ case 0xFF00A4D9: return 4419;
+ case 0xFF0B7F85: return 4627;
+ case 0xFF002D1F: return 4735;
+ case 0xFF11263C: return 5552;
+ case 0xFF91B9E2: return 5554;
+ case 0xFF429648: return 5557;
+ case 0xFF878C8C: return 8010;
+ }
+
+ return -1;
+}
+const char* getName_Sigma_Polyester(unsigned int color)
+{
+ switch(color)
+ {
+ case 0xFFFFFFFF: return "White";
+ case 0xFF000000: return "Black";
+ case 0xFFEDFF50: return "Light Neon Green";
+ case 0xFF96E845: return "Neon Green";
+ case 0xFFFFE756: return "Light Neon Orange";
+ case 0xFFFF7824: return "Med Neon Orange";
+ case 0xFFF28DA6: return "Neon Pink";
+ case 0xFFC70C57: return "Neon Orange Pink";
+ case 0xFFE22D2A: return "Silver";
+ case 0xFFB8B8B8: return "Silver Diamond";
+ case 0xFF889186: return "Lava Stone";
+ case 0xFF737F7F: return "Medium Grey";
+ case 0xFF565E5A: return "Dark Platinum";
+ case 0xFF515250: return "Charcoal";
+ case 0xFF787668: return "Badger Grey";
+ case 0xFFED572F: return "Pumpkin Orange";
+ case 0xFF2EA59C: return "Turquoise";
+ case 0xFF396276: return "Dark Wedgewood";
+ case 0xFF9B3B40: return "Cardinal Red";
+ case 0xFF6C3E47: return "Maroon";
+ case 0xFFBA6E4D: return "Rust";
+ case 0xFFBB3D2E: return "Medium Rust";
+ case 0xFFF9DFCF: return "Natural Pink";
+ case 0xFFFBDED6: return "Baby Pink";
+ case 0xFFF7CDD5: return "Piggy Pink";
+ case 0xFFF2AFB4: return "Sweet Pink";
+ case 0xFFE8418C: return "Blushing Pink";
+ case 0xFFE77F9D: return "Pink";
+ case 0xFFF06F8C: return "Rose Pink";
+ case 0xFF008340: return "Green";
+ case 0xFFDF99B6: return "Shocking Pink";
+ case 0xFF820052: return "Ruby";
+ case 0xFFB1415F: return "Garnet";
+ case 0xFFC394AE: return "Light Purple";
+ case 0xFFA86E91: return "Medium Purple";
+ case 0xFF694169: return "Dark Grape";
+ case 0xFFE6CFD5: return "Pastel Light Pink";
+ case 0xFFA8BED7: return "Light Baby Blue";
+ case 0xFFA0BFD7: return "Crystal Blue";
+ case 0xFF90A6C6: return "Very Light Lavender";
+ case 0xFF8FAFC6: return "Cornflower";
+ case 0xFFB1B8D3: return "Lavender";
+ case 0xFF416C9B: return "Denim";
+ case 0xFF7D77AF: return "Light Violet";
+ case 0xFFFADAF4: return "Misty Rose";
+ case 0xFF664090: return "Grape";
+ case 0xFFEAF0F9: return "Lt. Weathered Blue";
+ case 0xFFA6D8F6: return "Baby Blue";
+ case 0xFF7B9CB0: return "Med Baby Blue";
+ case 0xFF648DC7: return "Med Pastel Blue";
+ case 0xFF3D6AA1: return "Blue Raspberry";
+ case 0xFF2D4491: return "Med Royal Blue";
+ case 0xFF143D7A: return "Ocean Blue";
+ case 0xFF113263: return "Med Navy";
+ case 0xFF0E1F38: return "Dark Navy";
+ /* case 0xFF0E1F38: return "Bright Sunshine"; TODO: duplicate case value */
+ case 0xFF0091A5: return "Teal";
+ case 0xFF005B63: return "Deep Teal";
+ case 0xFF00474D: return "Dark Teal";
+ case 0xFFE5B15C: return "Old Gold";
+ case 0xFFD5BF9B: return "Cream";
+ case 0xFFFFD085: return "Pale Salmon";
+ case 0xFFF6B08E: return "Med Peach";
+ case 0xFFB3E851: return "Pink Salmon";
+ case 0xFFF1A236: return "Dark Peach";
+ case 0xFF6E4337: return "Dark Brown";
+ case 0xFFD8493E: return "Pale Red";
+ case 0xFF697698: return "Heron Blue";
+ case 0xFFFDE896: return "Pale Yellow";
+ case 0xFFEDE55D: return "Pastel Yellow";
+ case 0xFFDFA200: return "Golden Puppy";
+ /* case 0xFFFDE896: return "Buttercup"; TODO: duplicate case value */
+ case 0xFFCEB24C: return "Treasure Gold";
+ case 0xFFAD953E: return "Old Gold";
+ case 0xFFFEF9EA: return "Pale Apricot";
+ case 0xFFBD9565: return "Tan";
+ case 0xFFFDF76C: return "Mellow Yellow";
+ case 0xFFEDEF05: return "Lemon";
+ case 0xFFF8C300: return "Amber";
+ case 0xFFE77817: return "Mandarina";
+ case 0xFFE66535: return "Orange";
+ case 0xFFC69632: return "Golden Rod";
+ case 0xFF98996D: return "Light Olive";
+ case 0xFFC98300: return "Bright Gold";
+ case 0xFF007B8D: return "Blue-Green";
+ case 0xFF004D3D: return "Forrest Green";
+ case 0xFF007EBA: return "Midnight Blue";
+ case 0xFFCF0040: return "Med Red";
+ case 0xFF28438C: return "Med Blue";
+ case 0xFFD0B478: return "Sweet Apricot";
+ case 0xFFE5BE6C: return "Skin";
+ case 0xFF449284: return "Jade";
+ case 0xFFCFCFCF: return "Light Silver";
+ case 0xFFDC875E: return "Papaya Whip";
+ case 0xFFB4705D: return "Cooper";
+ case 0xFF9B5C4B: return "Light Pecan";
+ case 0xFFA93121: return "Burnt Rust";
+ case 0xFFB18B00: return "Vegas Gold";
+ case 0xFF86462E: return "Med Brown";
+ case 0xFF614125: return "Med Russett";
+ case 0xFFB25C31: return "Med Copper";
+ case 0xFF806A61: return "Dark Driftwood";
+ case 0xFF634831: return "Birch";
+ case 0xFF1A0C06: return "Dark Chocolate";
+ case 0xFF96D5C8: return "Sky Blue 2";
+ case 0xFFB4DCD8: return "Aquamarine";
+ case 0xFFAF7D3E: return "Golden Brown";
+ case 0xFF00A3A0: return "Sea Blue";
+ case 0xFF00405D: return "Deep Sea";
+ case 0xFFC9E3C5: return "Pastel Mint";
+ case 0xFF55AF78: return "True Green";
+ case 0xFF858325: return "Med Olive";
+ case 0xFF61601C: return "Olive";
+ case 0xFF709188: return "Light Jade";
+ case 0xFFBEDC8C: return "Smith Apple";
+ case 0xFFBEE678: return "Light Lime";
+ case 0xFF76C850: return "Grass Green";
+ case 0xFF466E64: return "Deep Teal";
+ case 0xFF356936: return "Med Forrest Green";
+ case 0xFF4B4884: return "Deep Violet";
+ case 0xFFEDEDD2: return "Light Natural";
+ case 0xFFF3D8A8: return "Wheat";
+ case 0xFFC8BE96: return "Desert Sand";
+ case 0xFF243A7D: return "Egyptian Blue";
+ case 0xFF86BE4E: return "Gecko";
+ case 0xFF8E4044: return "Burgandy";
+ case 0xFF893480: return "Med Orchid";
+ case 0xFF8C6DAA: return "Med Purple";
+ case 0xFFB6A36C: return "Very Old Gold";
+ case 0xFF2E9F76: return "Light Spruce";
+ case 0xFF98C173: return "Paris Green";
+ case 0xFFCDCDCD: return "Timberwolf";
+ case 0xFF2A377E: return "Bright Blue";
+ case 0xFF006CA5: return "Turquoise Blue";
+ case 0xFF834455: return "Dark Wine";
+ case 0xFFD0A44F: return "Beige";
+ case 0xFFED9206: return "Gold";
+ /* case 0xFFEDEF05: return "Med Orange"; TODO: duplicate case value */
+ case 0xFFC07A46: return "Dark Salmon";
+ case 0xFFB43C3C: return "Fire Red";
+ case 0xFF915F46: return "Saddle Brown";
+ case 0xFFFFC500: return "Yellow Sun";
+ case 0xFFA68A68: return "Deep Taupe";
+ case 0xFF00A4D9: return "Sky Blue";
+ case 0xFF0B7F85: return "Wild Peacock";
+ case 0xFF002D1F: return "Millard Green";
+ case 0xFF11263C: return "Dark Blue";
+ case 0xFF91B9E2: return "Powder Blue";
+ case 0xFF429648: return "Froggy Green";
+ case 0xFF878C8C: return "Stone Grey";
+ }
+
+ return "";
+}
+
+int getNum_Sulky_Rayon(unsigned int color)
+{
+ switch(color)
+ {
+ case 0xFFEFC810: return 502;
+ case 0xFF0C082D: return 505;
+ case 0xFFB26C29: return 521;
+ case 0xFFE79002: return 523;
+ case 0xFF34481E: return 525;
+ case 0xFF113675: return 526;
+ case 0xFF111408: return 538;
+ case 0xFFE10000: return 561;
+ case 0xFFFFB435: return 562;
+ case 0xFFF3A001: return 567;
+ case 0xFFE66D00: return 568;
+ case 0xFF165F28: return 569;
+ case 0xFF088E6C: return 571;
+ case 0xFF100A7C: return 572;
+ case 0xFF35693D: return 580;
+ case 0xFFE9BD96: return 619;
+ case 0xFFCD3900: return 621;
+ case 0xFF777113: return 630;
+ case 0xFF1C6F51: return 640;
+ case 0xFF262345: return 643;
+ case 0xFFF9F9FF: return 1001;
+ case 0xFFF9F9F4: return 1002;
+ case 0xFF000000: return 1005;
+ case 0xFFB7A9AC: return 1011;
+ case 0xFFE1AF9A: return 1015;
+ case 0xFFEC968C: return 1016;
+ case 0xFFEFDFBD: return 1017;
+ case 0xFFECA082: return 1019;
+ case 0xFFF08278: return 1020;
+ case 0xFFEB6602: return 1021;
+ case 0xFFFFF7D5: return 1022;
+ case 0xFFFFE669: return 1023;
+ case 0xFFFFB800: return 1024;
+ case 0xFFD78000: return 1025;
+ case 0xFFBEC3E1: return 1028;
+ case 0xFFA0C3EB: return 1029;
+ case 0xFFA6A2C6: return 1030;
+ case 0xFFDFBEC8: return 1031;
+ case 0xFFE68CEB: return 1032;
+ case 0xFFD86496: return 1033;
+ case 0xFFC6323C: return 1034;
+ case 0xFF790000: return 1035;
+ case 0xFFF90000: return 1037;
+ case 0xFFEB0000: return 1039;
+ case 0xFF877375: return 1040;
+ case 0xFF8C7F83: return 1041;
+ case 0xFF321E50: return 1042;
+ case 0xFF190525: return 1043;
+ case 0xFF1D062F: return 1044;
+ case 0xFFC3EFBF: return 1045;
+ case 0xFF2E8359: return 1046;
+ case 0xFFA6C284: return 1047;
+ case 0xFF42A021: return 1049;
+ case 0xFF1E6419: return 1051;
+ case 0xFFEEBEAE: return 1054;
+ case 0xFFEBBC80: return 1055;
+ case 0xFFAF5B00: return 1056;
+ case 0xFF642702: return 1057;
+ case 0xFF663500: return 1058;
+ case 0xFF530601: return 1059;
+ case 0xFFFFF7B9: return 1061;
+ case 0xFFF0F8EC: return 1063;
+ case 0xFFE6B4AA: return 1064;
+ case 0xFFFF9100: return 1065;
+ case 0xFFFFF180: return 1066;
+ case 0xFFFFFF85: return 1067;
+ case 0xFFF3DBD9: return 1068;
+ case 0xFFF6CE69: return 1070;
+ case 0xFFF9F9EA: return 1071;
+ case 0xFFD6D5E8: return 1074;
+ case 0xFF5A5A8B: return 1076;
+ case 0xFFBECDC8: return 1077;
+ case 0xFFFF6600: return 1078;
+ case 0xFF175523: return 1079;
+ case 0xFFDC82A0: return 1080;
+ case 0xFFF06E78: return 1081;
+ case 0xFFF7E3BB: return 1082;
+ case 0xFFFFC100: return 1083;
+ case 0xFFE2CFC7: return 1085;
+ case 0xFFF9F9E0: return 1086;
+ case 0xFF16625F: return 1090;
+ case 0xFF26BFCA: return 1094;
+ case 0xFF10D1BD: return 1095;
+ case 0xFF0F6978: return 1096;
+ case 0xFFC2D37D: return 1100;
+ case 0xFF098531: return 1101;
+ case 0xFF02140F: return 1103;
+ case 0xFFA5AF68: return 1104;
+ case 0xFFFAA4A4: return 1108;
+ case 0xFFDC6496: return 1109;
+ case 0xFFFCCBDF: return 1111;
+ case 0xFF46016E: return 1112;
+ case 0xFFF0C8B4: return 1113;
+ case 0xFFF0B9B9: return 1115;
+ case 0xFFF5A9A0: return 1117;
+ case 0xFFB46E75: return 1119;
+ case 0xFFF0D6D2: return 1120;
+ case 0xFFFAB9CB: return 1121;
+ case 0xFF82288E: return 1122;
+ case 0xFFFFEC00: return 1124;
+ case 0xFFDC8C17: return 1126;
+ case 0xFFFAECC6: return 1127;
+ case 0xFFC39471: return 1128;
+ case 0xFF6A1F06: return 1129;
+ case 0xFF551602: return 1130;
+ case 0xFF490002: return 1131;
+ case 0xFF507DAA: return 1134;
+ case 0xFFFFF072: return 1135;
+ case 0xFFFFBE00: return 1137;
+ case 0xFF4A5870: return 1143;
+ case 0xFFB4E1EB: return 1145;
+ /* case 0xFFEB0000: return 1147; TODO: duplicate case value */
+ case 0xFFFFBDBD: return 1148;
+ case 0xFFE8C89C: return 1149;
+ case 0xFFE2E2EB: return 1151;
+ case 0xFFFA9999: return 1154;
+ case 0xFF636327: return 1156;
+ case 0xFFBA4500: return 1158;
+ case 0xFFD39D00: return 1159;
+ case 0xFF10394A: return 1162;
+ case 0xFFDFE5EB: return 1165;
+ case 0xFF8E7E7E: return 1166;
+ case 0xFFFFD226: return 1167;
+ case 0xFFF5740A: return 1168;
+ case 0xFF9C0000: return 1169;
+ case 0xFF975F2F: return 1170;
+ case 0xFF08180E: return 1171;
+ case 0xFF6E788C: return 1172;
+ case 0xFF59591D: return 1173;
+ case 0xFF0D2904: return 1174;
+ case 0xFF152D04: return 1175;
+ case 0xFF515308: return 1176;
+ case 0xFF899812: return 1177;
+ case 0xFF8F623D: return 1179;
+ case 0xFFA58973: return 1180;
+ case 0xFFCB0000: return 1181;
+ case 0xFF020114: return 1182;
+ case 0xFF320614: return 1183;
+ /* case 0xFFFF6600: return 1184; TODO: duplicate case value */
+ case 0xFFFCBE05: return 1185;
+ case 0xFF5B0000: return 1186;
+ case 0xFFFFE500: return 1187;
+ case 0xFFFF004B: return 1188;
+ case 0xFF4B122D: return 1189;
+ case 0xFFA04656: return 1190;
+ case 0xFFBD1E60: return 1191;
+ case 0xFFD21E82: return 1192;
+ case 0xFFE6AFD2: return 1193;
+ case 0xFFD274D7: return 1194;
+ case 0xFF370150: return 1195;
+ case 0xFF96C3E1: return 1196;
+ case 0xFF220F34: return 1197;
+ case 0xFF3C5075: return 1198;
+ case 0xFF2A143F: return 1199;
+ case 0xFF140B2D: return 1200;
+ case 0xFF648BBE: return 1201;
+ case 0xFF182B56: return 1202;
+ case 0xFFAEB8C3: return 1203;
+ case 0xFFA8C8BC: return 1204;
+ case 0xFF6E90A5: return 1205;
+ case 0xFF1E6E6F: return 1206;
+ case 0xFF80A388: return 1207;
+ case 0xFF0C3D03: return 1208;
+ case 0xFFBDD163: return 1209;
+ case 0xFF273B00: return 1210;
+ case 0xFF95A490: return 1211;
+ case 0xFF63632D: return 1212;
+ case 0xFFB9A096: return 1213;
+ case 0xFF642828: return 1214;
+ case 0xFF500A1E: return 1215;
+ case 0xFFAC1C01: return 1216;
+ case 0xFF971F01: return 1217;
+ case 0xFFDFDFCB: return 1218;
+ case 0xFF98888C: return 1219;
+ case 0xFF765960: return 1220;
+ case 0xFFD1DBFF: return 1222;
+ case 0xFFDCE0F1: return 1223;
+ case 0xFFF0A0B9: return 1224;
+ case 0xFFFACBCB: return 1225;
+ case 0xFF57369E: return 1226;
+ case 0xFFAF8901: return 1227;
+ case 0xFF96AA8B: return 1228;
+ case 0xFFE0DBDB: return 1229;
+ case 0xFF0B4133: return 1230;
+ case 0xFFE5326A: return 1231;
+ case 0xFF193207: return 1232;
+ case 0xFF0D2210: return 1233;
+ case 0xFF3C1B1F: return 1234;
+ case 0xFF783298: return 1235;
+ case 0xFFEAE4E4: return 1236;
+ case 0xFFBC3D2C: return 1237;
+ case 0xFFFF8300: return 1238;
+ case 0xFFFFAB57: return 1239;
+ case 0xFF74586C: return 1240;
+ case 0xFF543A8D: return 1242;
+ case 0xFFFF0000: return 1246;
+ case 0xFF660000: return 1247;
+ case 0xFFD2E6F0: return 1248;
+ case 0xFF62AADC: return 1249;
+ case 0xFF275C70: return 1250;
+ case 0xFF306F75: return 1251;
+ case 0xFF09A1A8: return 1252;
+ case 0xFF1B4CA4: return 1253;
+ case 0xFFE6B9F5: return 1254;
+ case 0xFFBE1982: return 1255;
+ case 0xFFEB8296: return 1256;
+ case 0xFFE60041: return 1257;
+ case 0xFFF0C4A0: return 1258;
+ case 0xFFE28264: return 1259;
+ case 0xFFB30000: return 1263;
+ case 0xFF6A0000: return 1264;
+ case 0xFF9B6B2C: return 1265;
+ case 0xFF9C6D45: return 1266;
+ case 0xFF864C31: return 1267;
+ case 0xFFEFEFE5: return 1268;
+ case 0xFFB7B7AF: return 1270;
+ case 0xFF3C4F31: return 1271;
+ case 0xFF4A4A19: return 1272;
+ case 0xFF5C9A1A: return 1274;
+ case 0xFFE0E6C8: return 1275;
+ case 0xFF70770F: return 1276;
+ case 0xFF027602: return 1277;
+ case 0xFF00AF38: return 1278;
+ case 0xFF93D16C: return 1279;
+ case 0xFF46B774: return 1280;
+ case 0xFF483D59: return 1283;
+ case 0xFF466E78: return 1284;
+ case 0xFF134F45: return 1285;
+ case 0xFF343213: return 1286;
+ case 0xFF415545: return 1287;
+ case 0xFF0FA56F: return 1288;
+ case 0xFFDCEBF0: return 1289;
+ case 0xFF727483: return 1291;
+ case 0xFFD1DCFA: return 1292;
+ case 0xFF44235D: return 1293;
+ case 0xFF412044: return 1294;
+ case 0xFF82878C: return 1295;
+ case 0xFFD2AAF0: return 1296;
+ case 0xFF735A64: return 1297;
+ case 0xFF644664: return 1298;
+ case 0xFF411446: return 1299;
+ case 0xFF7E1E46: return 1300;
+ case 0xFF320046: return 1301;
+ case 0xFF6E0A96: return 1302;
+ case 0xFFB47364: return 1304;
+ case 0xFFAEC6BB: return 1305;
+ case 0xFF7E6C7C: return 1306;
+ case 0xFFDB6478: return 1307;
+ case 0xFF782346: return 1309;
+ case 0xFF961A32: return 1311;
+ case 0xFF840000: return 1312;
+ case 0xFFFC8F0C: return 1313;
+ /* case 0xFFFF0000: return 1317; TODO: duplicate case value */
+ case 0xFFCBCBBD: return 1321;
+ case 0xFF818901: return 1322;
+ case 0xFFF8F5F1: return 1325;
+ case 0xFFD5C7C3: return 1327;
+ case 0xFFC0B2B7: return 1328;
+ case 0xFFABA0A8: return 1329;
+ case 0xFFEDF6D4: return 1331;
+ case 0xFF868105: return 1332;
+ case 0xFFF3B600: return 1333;
+ case 0xFF349669: return 1503;
+ case 0xFFC1CBB9: return 1508;
+ case 0xFF7AB31D: return 1510;
+ case 0xFFEE5078: return 1511;
+ case 0xFF007A67: return 1513;
+ case 0xFFFF8CCB: return 1515;
+ case 0xFF014F3A: return 1517;
+ case 0xFFCD054D: return 1533;
+ case 0xFF347DCB: return 1534;
+ case 0xFF23238B: return 1535;
+ case 0xFF081705: return 1536;
+ case 0xFFFFD6C7: return 1543;
+ case 0xFF9C6484: return 1545;
+ case 0xFFE6AE6F: return 1549;
+ case 0xFF6C8E87: return 1550;
+ case 0xFF80B0AE: return 1551;
+ case 0xFF6C7C71: return 1552;
+ case 0xFF8C748C: return 1554;
+ case 0xFFEB7183: return 1558;
+ case 0xFF68E0F8: return 1560;
+ case 0xFFB58CC7: return 1561;
+ /* BEGIN N/A COLORS */
+ /*
+ return 2100;
+ return 2101;
+ return 2102;
+ return 2103;
+ return 2104;
+ return 2105;
+ return 2106;
+ return 2107;
+ return 2108;
+ return 2109;
+ return 2110;
+ return 2111;
+ return 2112;
+ return 2113;
+ return 2114;
+ return 2115;
+ return 2116;
+ return 2117;
+ return 2118;
+ return 2119;
+ return 2120;
+ return 2121;
+ return 2122;
+ return 2123;
+ return 2124;
+ return 2125;
+ return 2126;
+ return 2127;
+ return 2128;
+ return 2129;
+ return 2130;
+ return 2131;
+ return 2132;
+ return 2133;
+ return 2134;
+ return 2135;
+ return 2201;
+ return 2202;
+ return 2203;
+ return 2204;
+ return 2205;
+ return 2206;
+ return 2207;
+ return 2208;
+ return 2209;
+ return 2210;
+ return 2240;
+ return 2241;
+ return 2242;
+ return 2243;
+ return 2244;
+ return 2245;
+ return 2246;
+ return 2247;
+ */
+ /* END N/A COLORS */
+ case 0xFFFAD2AA: return 1800;
+ case 0xFFFADC96: return 1801;
+ case 0xFFFFC896: return 1802;
+ case 0xFFFF9B6E: return 1803;
+ case 0xFF375A73: return 1804;
+ case 0xFF28505A: return 1805;
+ case 0xFFA0B9C3: return 1806;
+ case 0xFFB49682: return 1807;
+ case 0xFFD2AF9B: return 1808;
+ case 0xFFA07D82: return 1809;
+ case 0xFF645055: return 1810;
+ case 0xFF3C2837: return 1811;
+ case 0xFF6E2D5A: return 1812;
+ case 0xFF6E2D41: return 1813;
+ case 0xFFAF4B69: return 1814;
+ case 0xFF91B432: return 1815;
+ case 0xFFD7F58C: return 1816;
+ case 0xFFAAAF14: return 1817;
+ case 0xFFC8F58C: return 1818;
+ case 0xFFC3913C: return 1819;
+ case 0xFFC38C73: return 1820;
+ case 0xFFFAC896: return 1821;
+ case 0xFF965A37: return 1822;
+ case 0xFF965A28: return 1823;
+ case 0xFFD2C3AF: return 1824;
+ case 0xFF5F9619: return 1825;
+ case 0xFFAA820A: return 1826;
+ case 0xFFFF643C: return 1827;
+ case 0xFFFFE6AA: return 1828;
+ case 0xFFF0EBA5: return 1829;
+ case 0xFFB47396: return 1830;
+ case 0xFF91E12D: return 1831;
+ case 0xFFE19119: return 1832;
+ case 0xFFD25F00: return 1833;
+ case 0xFFAFAA05: return 1834;
+ case 0xFF6E8205: return 1835;
+ case 0xFF3C4B05: return 1836;
+ case 0xFF9B735A: return 1837;
+ case 0xFFCDAA7D: return 1838;
+ case 0xFF87C887: return 1839;
+ case 0xFFF9E6CA: return 508;
+ case 0xFFFDF3DA: return 520;
+ case 0xFF5D3446: return 1241;
+ case 0xFFE0C63B: return 1243;
+ case 0xFFDDAB00: return 1260;
+ case 0xFFA98803: return 1262;
+ case 0xFFAC8783: return 1269;
+ case 0xFF36361F: return 1273;
+ case 0xFFFA5F7F: return 1303;
+ case 0xFFA3C2D7: return 1644;
+ }
+
+ return -1;
+}
+
+const char* getName_Sulky_Rayon(unsigned int color)
+{
+ switch(color)
+ {
+ case 0xFFEFC810: return "Cornsilk";
+ case 0xFF0C082D: return "Deep Arctic Sky";
+ case 0xFFB26C29: return "Nutmeg";
+ case 0xFFE79002: return "Autumn Gold";
+ case 0xFF34481E: return "English Green";
+ case 0xFF113675: return "Cobalt Blue";
+ case 0xFF111408: return "Forest Green";
+ case 0xFFE10000: return "Lipstick";
+ case 0xFFFFB435: return "Spice";
+ case 0xFFF3A001: return "Butterfly Gold";
+ case 0xFFE66D00: return "Cinnamon";
+ case 0xFF165F28: return "Garden Green";
+ case 0xFF088E6C: return "Deep Aqua";
+ case 0xFF100A7C: return "Blue Ribbon";
+ case 0xFF35693D: return "Mint Julep";
+ case 0xFFE9BD96: return "Dusty Peach";
+ case 0xFFCD3900: return "Sunset";
+ case 0xFF777113: return "Moss Green";
+ case 0xFF1C6F51: return "Med. Aqua";
+ case 0xFF262345: return "Arctic Sky";
+ case 0xFFF9F9FF: return "Bright White";
+ case 0xFFF9F9F4: return "Soft White";
+ case 0xFF000000: return "Black";
+ case 0xFFB7A9AC: return "Steel Gray";
+ case 0xFFE1AF9A: return "Med. Peach";
+ case 0xFFEC968C: return "Pastel Coral";
+ case 0xFFEFDFBD: return "Pastel Peach";
+ case 0xFFECA082: return "Peach";
+ case 0xFFF08278: return "Dark Peach";
+ case 0xFFEB6602: return "Maple";
+ case 0xFFFFF7D5: return "Cream";
+ case 0xFFFFE669: return "Yellow";
+ case 0xFFFFB800: return "Goldenrod";
+ case 0xFFD78000: return "Mine Gold";
+ case 0xFFBEC3E1: return "Baby Blue";
+ case 0xFFA0C3EB: return "Med. Blue";
+ case 0xFFA6A2C6: return "Periwinkle";
+ case 0xFFDFBEC8: return "Med. Orchid";
+ case 0xFFE68CEB: return "Med. Purple";
+ case 0xFFD86496: return "Dk. Orchid";
+ case 0xFFC6323C: return "Burgundy";
+ case 0xFF790000: return "Dk. Burgundy";
+ case 0xFFF90000: return "Lt.Red";
+ case 0xFFEB0000: return "True Red";
+ case 0xFF877375: return "Med. Dk. Khaki";
+ case 0xFF8C7F83: return "Med. Dk. Gray";
+ case 0xFF321E50: return "Bright Navy Blue";
+ case 0xFF190525: return "Dk. Navy";
+ case 0xFF1D062F: return "Midnight Blue";
+ case 0xFFC3EFBF: return "Lt. Teal";
+ case 0xFF2E8359: return "Teal";
+ case 0xFFA6C284: return "Mint Green";
+ case 0xFF42A021: return "Grass Green";
+ case 0xFF1E6419: return "Xmas Green";
+ case 0xFFEEBEAE: return "Med. Dk. Ecru";
+ case 0xFFEBBC80: return "Tawny Tan";
+ case 0xFFAF5B00: return "Med Tawny Tan";
+ case 0xFF642702: return "Dk Tawny Tan";
+ case 0xFF663500: return "Tawny Brown";
+ case 0xFF530601: return "Dk Tawny Brown";
+ case 0xFFFFF7B9: return "Pale Yellow";
+ case 0xFFF0F8EC: return "Pale Yellow-Green";
+ case 0xFFE6B4AA: return "Pale Peach";
+ case 0xFFFF9100: return "Orange Yellow";
+ case 0xFFFFF180: return "Primrose";
+ case 0xFFFFFF85: return "Lemon Yellow";
+ case 0xFFF3DBD9: return "Pink Tint";
+ case 0xFFF6CE69: return "Gold";
+ case 0xFFF9F9EA: return "Off White";
+ case 0xFFD6D5E8: return "Pale Powder Blue";
+ case 0xFF5A5A8B: return "Royal Blue";
+ case 0xFFBECDC8: return "Jade Tint";
+ case 0xFFFF6600: return "Tangerine";
+ case 0xFF175523: return "Emerald Green";
+ case 0xFFDC82A0: return "Orchid";
+ case 0xFFF06E78: return "Brick";
+ case 0xFFF7E3BB: return "Ecru";
+ case 0xFFFFC100: return "Spark Gold";
+ case 0xFFE2CFC7: return "Silver";
+ case 0xFFF9F9E0: return "Pale Sea Foam";
+ case 0xFF16625F: return "Deep Peacock";
+ case 0xFF26BFCA: return "Med Turquoise";
+ case 0xFF10D1BD: return "Turquoise";
+ case 0xFF0F6978: return "Dk Turquoise";
+ case 0xFFC2D37D: return "Lt Grass Green";
+ case 0xFF098531: return "True Green";
+ case 0xFF02140F: return "Dk Khaki";
+ case 0xFFA5AF68: return "Pastel Yellow-Grn";
+ case 0xFFFAA4A4: return "Lt Mauve";
+ case 0xFFDC6496: return "Hot Pink";
+ case 0xFFFCCBDF: return "Pastel Orchid";
+ case 0xFF46016E: return "Royal Purple";
+ case 0xFFF0C8B4: return "Pastel Mauve";
+ case 0xFFF0B9B9: return "Lt Pink";
+ case 0xFFF5A9A0: return "Mauve";
+ case 0xFFB46E75: return "Dk Mauve";
+ case 0xFFF0D6D2: return "Pale Pink";
+ case 0xFFFAB9CB: return "Pink";
+ case 0xFF82288E: return "Purple";
+ case 0xFFFFEC00: return "Sun Yellow";
+ case 0xFFDC8C17: return "Tan";
+ case 0xFFFAECC6: return "Med Ecru";
+ case 0xFFC39471: return "Dk Ecru";
+ case 0xFF6A1F06: return "Brown";
+ case 0xFF551602: return "Dark Brown";
+ case 0xFF490002: return "Cloister Brown";
+ case 0xFF507DAA: return "Peacock Blue";
+ case 0xFFFFF072: return "Pastel Yellow";
+ case 0xFFFFBE00: return "Yellow Orange";
+ case 0xFF4A5870: return "True Blue";
+ case 0xFFB4E1EB: return "Powder Blue";
+ /* case 0xFFEB0000: return "Xmas Red"; TODO: duplicate case value */
+ case 0xFFFFBDBD: return "Lt Coral";
+ case 0xFFE8C89C: return "Deep Ecru";
+ case 0xFFE2E2EB: return "Powder Blue Tint";
+ case 0xFFFA9999: return "Coral";
+ case 0xFF636327: return "Lt Army Green";
+ case 0xFFBA4500: return "Dk Maple";
+ case 0xFFD39D00: return "Temple Gold";
+ case 0xFF10394A: return "Deep Teal";
+ case 0xFFDFE5EB: return "Lt Sky Blue";
+ case 0xFF8E7E7E: return "Med Steel Gray";
+ case 0xFFFFD226: return "Maize Yellow";
+ case 0xFFF5740A: return "True Orange";
+ case 0xFF9C0000: return "Bayberry Red";
+ case 0xFF975F2F: return "Lt Brown";
+ case 0xFF08180E: return "Weathered Blue";
+ case 0xFF6E788C: return "Med Weathered Blue";
+ case 0xFF59591D: return "Med Army Green";
+ case 0xFF0D2904: return "Dk Pine Green";
+ case 0xFF152D04: return "Dk Avocado";
+ case 0xFF515308: return "Med Dk Avocado";
+ case 0xFF899812: return "Avocado";
+ case 0xFF8F623D: return "Dk Taupe";
+ case 0xFFA58973: return "Med Taupe";
+ case 0xFFCB0000: return "Rust";
+ case 0xFF020114: return "Blue Black";
+ case 0xFF320614: return "Black Cherry";
+ /* case 0xFFFF6600: return "Orange Red"; TODO: duplicate case value */
+ case 0xFFFCBE05: return "Golden Yellow";
+ case 0xFF5B0000: return "Sable Brown";
+ case 0xFFFFE500: return "Mimosa Yellow";
+ case 0xFFFF004B: return "Red Geranium";
+ case 0xFF4B122D: return "Dk Chestnut";
+ case 0xFFA04656: return "Med Burgundy";
+ case 0xFFBD1E60: return "Dk Rose";
+ case 0xFFD21E82: return "Fuchsia";
+ case 0xFFE6AFD2: return "Lavender";
+ case 0xFFD274D7: return "Lt Purple";
+ case 0xFF370150: return "Dk Purple";
+ case 0xFF96C3E1: return "Blue";
+ case 0xFF220F34: return "Med Navy";
+ case 0xFF3C5075: return "Dusty Navy";
+ case 0xFF2A143F: return "Admiral Navy Blue";
+ case 0xFF140B2D: return "Med Dk Navy";
+ case 0xFF648BBE: return "Med Powder Blue";
+ case 0xFF182B56: return "Deep Turquoise";
+ case 0xFFAEB8C3: return "Lt Weathered Blue";
+ case 0xFFA8C8BC: return "Pastel Jade";
+ case 0xFF6E90A5: return "Med Jade";
+ case 0xFF1E6E6F: return "Dark Jade";
+ case 0xFF80A388: return "Sea Foam Green";
+ case 0xFF0C3D03: return "Mallard Green";
+ case 0xFFBDD163: return "Lt Avocado";
+ case 0xFF273B00: return "Dk Army Green";
+ case 0xFF95A490: return "Lt Khaki";
+ case 0xFF63632D: return "Khaki";
+ case 0xFFB9A096: return "Taupe";
+ case 0xFF642828: return "Med Chestnut";
+ case 0xFF500A1E: return "Blackberry";
+ case 0xFFAC1C01: return "Med Maple";
+ case 0xFF971F01: return "Chestnut";
+ case 0xFFDFDFCB: return "Silver Gray";
+ case 0xFF98888C: return "Gray";
+ case 0xFF765960: return "Charcoal Gray";
+ case 0xFFD1DBFF: return "Lt Baby Blue";
+ case 0xFFDCE0F1: return "Baby Blue Tint";
+ case 0xFFF0A0B9: return "Bright Pink";
+ case 0xFFFACBCB: return "Pastel Pink";
+ case 0xFF57369E: return "Dkl Periwinkle";
+ case 0xFFAF8901: return "Gold Green";
+ case 0xFF96AA8B: return "Drab Green";
+ case 0xFFE0DBDB: return "Lt Putty";
+ case 0xFF0B4133: return "Dk Teal";
+ case 0xFFE5326A: return "Med Rose";
+ case 0xFF193207: return "Classic Green";
+ case 0xFF0D2210: return "Ocean Teal";
+ case 0xFF3C1B1F: return "Almost Black";
+ case 0xFF783298: return "Deep Purple";
+ case 0xFFEAE4E4: return "Lt Silver";
+ case 0xFFBC3D2C: return "Deep Mauve";
+ case 0xFFFF8300: return "Orange Sunrise";
+ case 0xFFFFAB57: return "Apricot";
+ case 0xFF74586C: return "Smokey Grey";
+ case 0xFF543A8D: return "Nassau Blue";
+ case 0xFFFF0000: return "Orange Flame";
+ case 0xFF660000: return "Mahogany";
+ case 0xFFD2E6F0: return "Med Pastel Blue";
+ case 0xFF62AADC: return "Cornflower Blue";
+ case 0xFF275C70: return "Duck Wing Blue";
+ case 0xFF306F75: return "Bright Turquoise";
+ case 0xFF09A1A8: return "Bright Peacock";
+ case 0xFF1B4CA4: return "Dk Sapphire";
+ case 0xFFE6B9F5: return "Dusty Lavender";
+ case 0xFFBE1982: return "Deep Orchid";
+ case 0xFFEB8296: return "Sweet Pink";
+ case 0xFFE60041: return "Deep Coral";
+ case 0xFFF0C4A0: return "Coral Reed";
+ case 0xFFE28264: return "Salmon Peach";
+ case 0xFFB30000: return "Red Jubilee";
+ case 0xFF6A0000: return "Cognac";
+ case 0xFF9B6B2C: return "Burnt Toast";
+ case 0xFF9C6D45: return "Toast";
+ case 0xFF864C31: return "Mink Brown";
+ case 0xFFEFEFE5: return "Light Gray Khaki";
+ case 0xFFB7B7AF: return "Dk Gray Khaki";
+ case 0xFF3C4F31: return "Evergreen";
+ case 0xFF4A4A19: return "Hedge Green";
+ case 0xFF5C9A1A: return "Nile Green";
+ case 0xFFE0E6C8: return "Sea Mist";
+ case 0xFF70770F: return "Pistachio";
+ case 0xFF027602: return "Ivy Green";
+ case 0xFF00AF38: return "Bright Green";
+ case 0xFF93D16C: return "Willow Green";
+ case 0xFF46B774: return "Dk Willow Green";
+ case 0xFF483D59: return "Slate Gray";
+ case 0xFF466E78: return "Dk Winter Sky";
+ case 0xFF134F45: return "Dk Sage Green";
+ case 0xFF343213: return "Dk French Green";
+ case 0xFF415545: return "French Green";
+ case 0xFF0FA56F: return "Aqua";
+ case 0xFFDCEBF0: return "Ice Blue";
+ case 0xFF727483: return "Winter Sky";
+ case 0xFFD1DCFA: return "Heron Blue";
+ case 0xFF44235D: return "Deep Nassau Blue";
+ case 0xFF412044: return "Deep Slate Gray";
+ case 0xFF82878C: return "Sterling";
+ case 0xFFD2AAF0: return "Hyacinth";
+ case 0xFF735A64: return "Lt Plum";
+ case 0xFF644664: return "Dk Plum";
+ case 0xFF411446: return "Purple Shadow";
+ case 0xFF7E1E46: return "Plum";
+ case 0xFF320046: return "Deep Eggplant";
+ case 0xFF6E0A96: return "Eggplant";
+ case 0xFFB47364: return "Dewberry";
+ case 0xFFAEC6BB: return "Sage Green";
+ case 0xFF7E6C7C: return "Gun Metal Gray";
+ case 0xFFDB6478: return "Petal Pink";
+ case 0xFF782346: return "Magenta";
+ case 0xFF961A32: return "Mulberry";
+ case 0xFF840000: return "Wine";
+ case 0xFFFC8F0C: return "Bittersweet";
+ /* case 0xFFFF0000: return "Poppy"; TODO: duplicate case value */
+ case 0xFFCBCBBD: return "Gray Khaki";
+ case 0xFF818901: return "Chartreuse";
+ case 0xFFF8F5F1: return "Whisper Gray";
+ case 0xFFD5C7C3: return "Dk Whisper Gray";
+ case 0xFFC0B2B7: return "Nickel Gray";
+ case 0xFFABA0A8: return "Dk Nickel Gray";
+ case 0xFFEDF6D4: return "Pale Green";
+ case 0xFF868105: return "Deep Chartreuse";
+ case 0xFFF3B600: return "Sunflower Gold";
+ case 0xFF349669: return "Green Peacock";
+ case 0xFFC1CBB9: return "Putty";
+ case 0xFF7AB31D: return "Lime Green";
+ case 0xFFEE5078: return "Deep Rose";
+ case 0xFF007A67: return "Wild Peacock";
+ case 0xFFFF8CCB: return "Rosebud";
+ case 0xFF014F3A: return "Coachman Green";
+ case 0xFFCD054D: return "Lt Rose";
+ case 0xFF347DCB: return "Sapphire";
+ case 0xFF23238B: return "Team Blue";
+ case 0xFF081705: return "Midnight Teal";
+ case 0xFFFFD6C7: return "Peach Fluff";
+ case 0xFF9C6484: return "Purple Accent";
+ case 0xFFE6AE6F: return "Flax";
+ case 0xFF6C8E87: return "Desert Cactus";
+ case 0xFF80B0AE: return "Ocean Aqua";
+ case 0xFF6C7C71: return "Dk Desert Cactus";
+ case 0xFF8C748C: return "Purple Passion";
+ case 0xFFEB7183: return "Tea Rose";
+ case 0xFF68E0F8: return "Marine Aqua";
+ case 0xFFB58CC7: return "Deep Hyacinth";
+ /* BEGIN N/A COLORS */
+ /*
+ return "Vari-Pastel Pinks";
+ return "Vari-Pinks";
+ return "Vari-Roses";
+ return "Vari-Oranges";
+ return "Vari-Pastel Blues";
+ return "Teal Blues";
+ return "Vari-Blues";
+ return "Vari-Navy Blues";
+ return "Vari-Grays/Silvers";
+ return "Vari-Grays/Blacks";
+ return "Vari-True Greens";
+ return "Vari-Grass Greens";
+ return "Vari-Mint Greens";
+ return "Vari-Bright Greens";
+ return "Vari-Avocado Grns";
+ return "Vari-Pine Greens";
+ return "Vari-Taupes";
+ return "Vari-Yellows";
+ return "Vari-Med Brown";
+ return "Vari-Lt Browns";
+ return "Vari-Dk Browns";
+ return "Vari-Orchids";
+ return "Vari-Baby Pinks";
+ return "Vari-Reds";
+ return "Vari-Purples";
+ return "Vari-Royal Purples";
+ return "Vari-Rust Peaches";
+ return "Vari-Dk Taupes";
+ return "Vari-Willow Greens";
+ return "Vari-French Greens";
+ return "Vari-Fuchsias";
+ return "Vari-Khakis";
+ return "Vari-Aqua Teals";
+ return "Vari-Coffee Browns";
+ return "Vari-Golden Ylws";
+ return "Vari-Peaches";
+ return "Baby Blue/Pink/Mint";
+ return "Mint Greens/Pinks";
+ return "Baby Pink/Mint/Blue";
+ return "Teal/Purple/Fuchsia";
+ return "Blue/Fuchsia/Purple";
+ return "Turq/Coral/Silver";
+ return "Green/Burgundy/Tan";
+ return "Burg/Green/Blue/Tan";
+ return "Seafoam/Coralrf/Ecru";
+ return "Dk Gr/Brn Burg/Lt Br";
+ return "Grn/Coral/Blue/Ylw";
+ return "Peach/Blue/Rust/Grn";
+ return "Red/Gold/Blue";
+ return "Med Grn/Purple/Gold";
+ return "Coral/Brown/Teal";
+ return "Old Gold/Black/Red";
+ return "Med Blue/Green/Tan";
+ return "Blue/Lav/Red/Ylw/Grn";
+ */
+ /* END N/A COLORS */
+ case 0xFFFAD2AA: return "Shrimp";
+ case 0xFFFADC96: return "Flesh";
+ case 0xFFFFC896: return "Soft Blush";
+ case 0xFFFF9B6E: return "Island Peach";
+ case 0xFF375A73: return "Bayou Blue";
+ case 0xFF28505A: return "Ocean View";
+ case 0xFFA0B9C3: return "Madras Blue";
+ case 0xFFB49682: return "Soft Heather";
+ case 0xFFD2AF9B: return "Velvet Slipper";
+ case 0xFFA07D82: return "Iced Mauve";
+ case 0xFF645055: return "Wild Mulberry";
+ case 0xFF3C2837: return "Wineberry";
+ case 0xFF6E2D5A: return "Wildflower";
+ case 0xFF6E2D41: return "Plum Wine";
+ case 0xFFAF4B69: return "Orchid Kiss";
+ case 0xFF91B432: return "Japanese Fern";
+ case 0xFFD7F58C: return "Honeydew";
+ case 0xFFAAAF14: return "Lemon Grass";
+ case 0xFFC8F58C: return "Fairway Mist";
+ case 0xFFC3913C: return "Outback";
+ case 0xFFC38C73: return "Fruit Shake";
+ case 0xFFFAC896: return "Creamy Peach";
+ case 0xFF965A37: return "Toffee";
+ case 0xFF965A28: return "Cocoa";
+ case 0xFFD2C3AF: return "Gentle Rain";
+ case 0xFF5F9619: return "Barnyard Grass";
+ case 0xFFAA820A: return "Galley Gold";
+ case 0xFFFF643C: return "Coral Sunset";
+ case 0xFFFFE6AA: return "Seashell";
+ case 0xFFF0EBA5: return "Crème Brulee";
+ case 0xFFB47396: return "Lilac";
+ case 0xFF91E12D: return "Liimeade";
+ case 0xFFE19119: return "Desert Glow";
+ case 0xFFD25F00: return "Pumpkin Pie";
+ case 0xFFAFAA05: return "Pea Soup";
+ case 0xFF6E8205: return "Peapod Green";
+ case 0xFF3C4B05: return "Loden Green";
+ case 0xFF9B735A: return "Lt. Cocoa";
+ case 0xFFCDAA7D: return "Cocoa Cream";
+ case 0xFF87C887: return "Cameo";
+ case 0xFFF9E6CA: return "Sand";
+ case 0xFFFDF3DA: return "Bone";
+ case 0xFF5D3446: return "Dark Ash";
+ case 0xFFE0C63B: return "Spring Moss";
+ case 0xFFDDAB00: return "Summer Gold";
+ case 0xFFA98803: return "Dk. Autumn Gold";
+ case 0xFFAC8783: return "Mushroom";
+ case 0xFF36361F: return "Dark Forest";
+ case 0xFFFA5F7F: return "Watermelon";
+ case 0xFFA3C2D7: return "Caribbean Mist";
+ }
+
+ return "";
+}
+
+int getNum_ThreadArt_Rayon(unsigned int color) { return -1; } /*TODO: finish */
+const char* getName_ThreadArt_Rayon(unsigned int color) { return ""; } /*TODO: finish */
+
+int getNum_ThreadArt_Polyester(unsigned int color) { return -1; } /*TODO: finish */
+const char* getName_ThreadArt_Polyester(unsigned int color) { return ""; } /*TODO: finish */
+
+int getNum_ThreaDelight_Polyester(unsigned int color) { return -1; } /*TODO: finish */
+const char* getName_ThreaDelight_Polyester(unsigned int color) { return ""; } /*TODO: finish */
+
+int getNum_Z102_Isacord_Polyester(unsigned int color)
+{
+ switch(color)
+ {
+ case 0xFFF8FFFF: return 17;
+ case 0xFF000000: return 20;
+ case 0xFFB7BABA: return 105;
+ case 0xFF73787A: return 108;
+ case 0xFF454B58: return 138;
+ case 0xFF9EA9A6: return 142;
+ case 0xFFC8C6BD: return 150;
+ case 0xFFFAEE5C: return 220;
+ case 0xFFE5CB4F: return 221;
+ case 0xFFFFF46A: return 230;
+ case 0xFFFEF9D9: return 270;
+ case 0xFFFFDC00: return 311;
+ case 0xFF624F00: return 345;
+ case 0xFFB8B25A: return 352;
+ case 0xFF8D8F5B: return 453;
+ case 0xFFFFF4A5: return 520;
+ case 0xFFB98E03: return 542;
+ case 0xFFE4C180: return 651;
+ case 0xFFC5BFA6: return 672;
+ case 0xFF96836D: return 722;
+ case 0xFF4E3500: return 747;
+ case 0xFFDDCBA5: return 761;
+ case 0xFF605840: return 776;
+ case 0xFFFFAF02: return 800;
+ case 0xFFF6AE32: return 811;
+ case 0xFFC89334: return 822;
+ case 0xFFE59300: return 824;
+ case 0xFFC89340: return 832;
+ case 0xFF9E947F: return 873;
+ case 0xFFC8700B: return 922;
+ case 0xFFBB5704: return 931;
+ case 0xFFB19072: return 1061;
+ case 0xFFFF8101: return 1102;
+ case 0xFFB1500A: return 1115;
+ case 0xFFC09C72: return 1123;
+ case 0xFF843D07: return 1134;
+ case 0xFFD8A67D: return 1141;
+ case 0xFF82421B: return 1154;
+ case 0xFFFF7319: return 1300;
+ case 0xFFFF3D1E: return 1305;
+ case 0xFFBA4005: return 1311;
+ case 0xFFC73C13: return 1312;
+ case 0xFFE66B21: return 1332;
+ case 0xFF3D1C11: return 1346;
+ case 0xFFFFBC95: return 1351;
+ case 0xFFFFCC93: return 1362;
+ case 0xFF373732: return 1375;
+ case 0xFFFFAF94: return 1532;
+ case 0xFF5B4032: return 1565;
+ case 0xFFFF6046: return 1600;
+ case 0xFFFF6D71: return 1753;
+ case 0xFFEBBAAE: return 1755;
+ case 0xFFEB2D2B: return 1805;
+ case 0xFFFF988F: return 1840;
+ case 0xFF434331: return 1874;
+ case 0xFFC11914: return 1902;
+ case 0xFFC8100D: return 1903;
+ case 0xFFBF0A21: return 1906;
+ case 0xFFD23C3E: return 1921;
+ case 0xFF8F8C93: return 1972;
+ case 0xFFA31A1C: return 2011;
+ case 0xFF4D0308: return 2115;
+ case 0xFFFFCDCC: return 2155;
+ case 0xFF871C45: return 2500;
+ case 0xFFDB4083: return 2508;
+ case 0xFFFF668A: return 2520;
+ case 0xFFC91243: return 2521;
+ case 0xFFFFA0B6: return 2530;
+ case 0xFFFEA5B9: return 2550;
+ case 0xFF626C7E: return 2674;
+ case 0xFF5E1942: return 2711;
+ case 0xFF33001D: return 2715;
+ case 0xFFA57B8D: return 2764;
+ case 0xFF702A69: return 2810;
+ case 0xFFB385BC: return 2830;
+ case 0xFF240047: return 2900;
+ case 0xFF724593: return 2910;
+ case 0xFF634D86: return 2920;
+ case 0xFF000136: return 3110;
+ case 0xFF000021: return 3355;
+ case 0xFF054ABD: return 3522;
+ case 0xFF1C005D: return 3541;
+ case 0xFF001F71: return 3544;
+ case 0xFF002E5E: return 3622;
+ case 0xFF71AAD8: return 3630;
+ case 0xFF001748: return 3644;
+ case 0xFFC8DBE4: return 3650;
+ case 0xFF9FC7DF: return 3730;
+ case 0xFF082E4D: return 3743;
+ case 0xFF98B0BC: return 3750;
+ case 0xFF23679C: return 3810;
+ case 0xFF3D657E: return 3842;
+ case 0xFF00669F: return 3901;
+ case 0xFF47AEDD: return 3910;
+ case 0xFFBBDFEB: return 3962;
+ case 0xFFBABEB7: return 3971;
+ case 0xFF015D7E: return 4032;
+ case 0xFFD5DDDB: return 4071;
+ case 0xFF888D8E: return 4073;
+ case 0xFF007CA6: return 4103;
+ case 0xFF3EBBC8: return 4111;
+ case 0xFF005C79: return 4116;
+ case 0xFF80CCD8: return 4240;
+ case 0xFFACCEC7: return 4250;
+ case 0xFF006E74: return 4410;
+ case 0xFF002A29: return 4515;
+ case 0xFF38A4AE: return 4620;
+ case 0xFFAFD8CD: return 5050;
+ case 0xFF149B7B: return 5210;
+ case 0xFF7AC8AF: return 5220;
+ case 0xFF187166: return 5233;
+ case 0xFF004B23: return 5374;
+ case 0xFF006835: return 5415;
+ case 0xFF5C9C51: return 5531;
+ case 0xFF0E9543: return 5613;
+ case 0xFF5E7A17: return 5833;
+ case 0xFF225926: return 5944;
+ case 0xFFBCD633: return 6011;
+ case 0xFFBBCD91: return 6051;
+ case 0xFF978B3C: return 6133;
+ }
+
+ return -1;
+}
+
+const char* getName_Z102_Isacord_Polyester(unsigned int color) { return ""; } /*TODO: finish */
+
+#endif /* ARDUINO TODO: remove this line when thread-color.c is arduino compatible. This is a temporary arduino build fix. */
+
+int threadColorNum(unsigned int color, ThreadBrand brand)
+{
+ switch(brand)
+ {
+ case Arc_Polyester: return getNum_Arc_Polyester(color);
+ case Arc_Rayon: return getNum_Arc_Rayon(color);
+ case CoatsAndClark_Rayon: return getNum_CoatsAndClark_Rayon(color);
+ case Exquisite_Polyester: return getNum_Exquisite_Polyester(color);
+ case Fufu_Polyester: return getNum_Fufu_Polyester(color);
+ case Fufu_Rayon: return getNum_Fufu_Rayon(color);
+ case Hemingworth_Polyester: return getNum_Hemingworth_Polyester(color);
+ case Isacord_Polyester: return getNum_Isacord_Polyester(color);
+ case Isafil_Rayon: return getNum_Isafil_Rayon(color);
+ case Marathon_Polyester: return getNum_Marathon_Polyester(color);
+ case Marathon_Rayon: return getNum_Marathon_Rayon(color);
+ case Madeira_Polyester: return getNum_Madeira_Polyester(color);
+ case Madeira_Rayon: return getNum_Madeira_Rayon(color);
+ case Metro_Polyester: return getNum_Metro_Polyester(color);
+ case Pantone: return getNum_Pantone(color);
+ case RobisonAnton_Polyester: return getNum_RobisonAnton_Polyester(color);
+ case RobisonAnton_Rayon: return getNum_RobisonAnton_Rayon(color);
+ case Sigma_Polyester: return getNum_Sigma_Polyester(color);
+ case Sulky_Rayon: return getNum_Sulky_Rayon(color);
+ case ThreadArt_Rayon: return getNum_ThreadArt_Rayon(color);
+ case ThreadArt_Polyester: return getNum_ThreadArt_Polyester(color);
+ case ThreaDelight_Polyester: return getNum_ThreaDelight_Polyester(color);
+ case Z102_Isacord_Polyester: return getNum_Z102_Isacord_Polyester(color);
+ }
+
+ return -1;
+}
+
+const char* threadColorName(unsigned int color, ThreadBrand brand)
+{
+ switch(brand)
+ {
+ case Arc_Polyester: return getName_Arc_Polyester(color);
+ case Arc_Rayon: return getName_Arc_Rayon(color);
+ case CoatsAndClark_Rayon: return getName_CoatsAndClark_Rayon(color);
+ case Exquisite_Polyester: return getName_Exquisite_Polyester(color);
+ case Fufu_Polyester: return getName_Fufu_Polyester(color);
+ case Fufu_Rayon: return getName_Fufu_Rayon(color);
+ case Hemingworth_Polyester: return getName_Hemingworth_Polyester(color);
+ case Isacord_Polyester: return getName_Isacord_Polyester(color);
+ case Isafil_Rayon: return getName_Isafil_Rayon(color);
+ case Marathon_Polyester: return getName_Marathon_Polyester(color);
+ case Marathon_Rayon: return getName_Marathon_Rayon(color);
+ case Madeira_Polyester: return getName_Madeira_Polyester(color);
+ case Madeira_Rayon: return getName_Madeira_Rayon(color);
+ case Metro_Polyester: return getName_Metro_Polyester(color);
+ case Pantone: return getName_Pantone(color);
+ case RobisonAnton_Polyester: return getName_RobisonAnton_Polyester(color);
+ case RobisonAnton_Rayon: return getName_RobisonAnton_Rayon(color);
+ case Sigma_Polyester: return getName_Sigma_Polyester(color);
+ case Sulky_Rayon: return getName_Sulky_Rayon(color);
+ case ThreadArt_Rayon: return getName_ThreadArt_Rayon(color);
+ case ThreadArt_Polyester: return getName_ThreadArt_Polyester(color);
+ case ThreaDelight_Polyester: return getName_ThreaDelight_Polyester(color);
+ case Z102_Isacord_Polyester: return getName_Z102_Isacord_Polyester(color);
+ }
+
+ return "";
+}
+
+/* gcc -DTEST_THREAD_COLOR -o thread-color thread-color.c */
+#ifdef TEST_THREAD_COLOR
+
+#include <stdio.h>
+
+int main(void)
+{
+ unsigned int tColor = 0xFFD25F00;
+ ThreadBrand tBrand = Sulky_Rayon;
+ int tNum = threadColorNum(tColor, tBrand);
+ const char* tName = threadColorName(tColor, tBrand);
+
+ printf("Color : 0x%X\n"
+ "Brand : %d\n"
+ "Num : %d\n"
+ "Name : %s\n\n",
+ tColor,
+ tBrand,
+ tNum, /* Solution: 1833 */
+ tName); /* Solution: Pumpkin Pie */
+ return 0;
+}
+
+#endif
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/thread-color.h b/Software/Visual_Studio/Embroidery/libembroidery/thread-color.h
new file mode 100644
index 000000000..826065825
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/thread-color.h
@@ -0,0 +1,49 @@
+#ifndef THREAD_COLOR_H
+#define THREAD_COLOR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{
+ Arc_Polyester,
+ Arc_Rayon,
+ CoatsAndClark_Rayon,
+ Exquisite_Polyester,
+ Fufu_Polyester,
+ Fufu_Rayon,
+ Hemingworth_Polyester,
+ Isacord_Polyester,
+ Isafil_Rayon,
+ Marathon_Polyester,
+ Marathon_Rayon,
+ Madeira_Polyester,
+ Madeira_Rayon,
+ Metro_Polyester,
+ Pantone,
+ RobisonAnton_Polyester,
+ RobisonAnton_Rayon,
+ Sigma_Polyester,
+ Sulky_Rayon,
+ ThreadArt_Rayon,
+ ThreadArt_Polyester,
+ ThreaDelight_Polyester,
+ Z102_Isacord_Polyester
+} ThreadBrand;
+
+/* NOTE:
+ * colors must be passed in #AARRGGBB format with
+ * the alpha value always being FF, i.e. opaque
+*/
+
+int threadColorNum(unsigned int color, ThreadBrand brand);
+const char* threadColorName(unsigned int color, ThreadBrand brand);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* THREAD_COLOR_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/utility/README.md b/Software/Visual_Studio/Embroidery/libembroidery/utility/README.md
new file mode 100644
index 000000000..76e185977
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/utility/README.md
@@ -0,0 +1,49 @@
+libembroidery on Arduino
+------------------------
+
+This folder contains Arduino specific files for libembroidery.
+
+Compatible Boards
+-----------------
+
+We recommend using an Arduino Mega 2560 or another board
+with equal or greater specs. That being said, we have had success
+using an Arduino Uno R3 but this will likely require further
+optimization and other improvements to ensure continued compatibility
+with the Uno. See below for more information.
+
+Arduino Considerations
+----------------------
+There are two main concerns here: Flash Storage & SRAM.
+
+libembroidery continually outgrows the 32KB of Flash storage
+on the Arduino Uno and every time this occurs, a decision has to
+be made as to what capabilities should be included or omitted. While
+reading files is the main focus on arduino, writing files may
+also play a bigger role in the future. Long term, it would be most
+practical to handle the inclusion or omission of any feature
+via a single configuration header file that the user can modify
+to suit their needs.
+
+SRAM is in extremely limited supply and it will deplete quickly so
+any dynamic allocation should occur early during the setup phase
+of the sketch and sparingly or not at all later in the sketch.
+To help minimize SRAM consumption on Arduino and ensure libembroidery
+can be used in any way the sketch creator desires, it is required that
+any sketch using libembroidery must implement event handlers. See
+the ino-event source and header files for more information.
+
+There is also an excellent article by Bill Earl on the
+Adafruit Learning System which covers these topics in more depth:
+http://learn.adafruit.com/memories-of-an-arduino?view=all
+
+Special Notes
+-------------
+
+Due to historical reasons and to remain compatible with the
+Arduino 1.0 IDE, this folder must be called "utility".
+Refer to the arduino build process for more info:
+https://code.google.com/p/arduino/wiki/BuildProcess
+
+libembroidery relies on the Arduino SD library for reading files.
+See the ino-file source and header files for more information.
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/utility/ino-event.cpp b/Software/Visual_Studio/Embroidery/libembroidery/utility/ino-event.cpp
new file mode 100644
index 000000000..4d2e3a11f
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/utility/ino-event.cpp
@@ -0,0 +1,19 @@
+#include "ino-event.h"
+#include "emb-logging.h"
+
+#include "Arduino.h"
+
+/**************************************************/
+/* EventHandlers - These need to be in the sketch */
+/**************************************************/
+extern void eventHandler_addStitchAbs(InoPattern*, double, double, int, int);
+
+/**************************************************/
+/* EventSenders */
+/**************************************************/
+void inoEvent_addStitchAbs(InoPattern* p, double x, double y, int flags, int isAutoColorIndex)
+{
+ eventHandler_addStitchAbs(p, x, y, flags, isAutoColorIndex);
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/utility/ino-event.h b/Software/Visual_Studio/Embroidery/libembroidery/utility/ino-event.h
new file mode 100644
index 000000000..4119a5df7
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/utility/ino-event.h
@@ -0,0 +1,20 @@
+/*! @file ino-event.h */
+#ifndef INO_EVENT_H
+#define INO_EVENT_H
+
+#include "emb-pattern.h"
+typedef EmbPattern InoPattern;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void inoEvent_addStitchAbs(InoPattern* p, double x, double y, int flags, int isAutoColorIndex);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* INO_EVENT_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/utility/ino-file.cpp b/Software/Visual_Studio/Embroidery/libembroidery/utility/ino-file.cpp
new file mode 100644
index 000000000..4eb3acc10
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/utility/ino-file.cpp
@@ -0,0 +1,92 @@
+#include "ino-file.h"
+
+#include "SD.h"
+
+struct InoFile_
+{
+ File file;
+};
+
+InoFile* inoFile_open(const char* fileName, const char* mode)
+{
+ Serial.println(F("inoFile_open"));
+
+ InoFile* iFile;
+
+ iFile = (InoFile*)malloc(sizeof(InoFile));
+ if(!iFile)
+ return 0;
+
+ iFile->file = SD.open(fileName, FILE_READ); /* ARDUINO TODO: add FILE_WRITE capability */
+ if(!iFile->file)
+ Serial.println(F("ERROR: SD.open() failed"));
+
+ return iFile;
+}
+
+int inoFile_close(InoFile* stream)
+{
+ Serial.println(F("inoFile_close"));
+
+ stream->file.close();
+ free(stream);
+ stream = 0;
+ return 0;
+}
+
+int inoFile_eof(InoFile* stream)
+{
+ //Serial.println(F("inoFile_eof"));
+
+ int avail = stream->file.available();
+ //Serial.print(F("avail: "));
+ //Serial.println(avail);
+ if(avail)
+ {
+ return 0;
+ }
+ Serial.println(F("EOF"));
+ return 1;
+}
+
+int inoFile_getc(InoFile* stream)
+{
+ //Serial.println(F("inoFile_getc"));
+
+ return stream->file.read();
+}
+
+int inoFile_seek(InoFile* stream, long offset, int origin)
+{
+ Serial.println(F("TODO: inoFile_seek"));
+
+ return 0;//TODO: fseek(stream->file, offset, origin);
+}
+
+long inoFile_tell(InoFile* stream)
+{
+ Serial.println(F("TODO: inoFile_tell"));
+
+ return 0;//TODO: ftell(stream->file);
+}
+
+InoFile* inoFile_tmpfile(void)
+{
+ Serial.println(F("inoFile_tmpfile"));
+
+ return 0; //TODO: finish inoFile_tmpfile()
+}
+
+int inoFile_putc(int ch, InoFile* stream)
+{
+ Serial.println(F("inoFile_putc"));
+
+ return 0; //TODO: finish inoFile_putc()
+}
+
+int inoFile_printf(InoFile* stream, const char* msg)
+{
+ return stream->file.print(msg);
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/utility/ino-file.h b/Software/Visual_Studio/Embroidery/libembroidery/utility/ino-file.h
new file mode 100644
index 000000000..07e0c8277
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/utility/ino-file.h
@@ -0,0 +1,29 @@
+/*! @file ino-file.h */
+#ifndef INO_FILE_H
+#define INO_FILE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct InoFile_ InoFile;
+typedef InoFile EmbFile;
+
+InoFile* inoFile_open(const char* fileName, const char* mode);
+int inoFile_close(InoFile* stream);
+int inoFile_eof(InoFile* stream);
+int inoFile_getc(InoFile* stream);
+int inoFile_seek(InoFile* stream, long offset, int origin);
+long inoFile_tell(InoFile* stream);
+InoFile* inoFile_tmpfile(void);
+int inoFile_putc(int ch, InoFile* stream);
+
+int inoFile_printf(InoFile* stream, const char* msg);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* INO_FILE_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/utility/ino-logging.cpp b/Software/Visual_Studio/Embroidery/libembroidery/utility/ino-logging.cpp
new file mode 100644
index 000000000..03d4f79fb
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/utility/ino-logging.cpp
@@ -0,0 +1,10 @@
+#include "ino-logging.h"
+
+#include "Arduino.h"
+
+void inoLog_serial(const char* msg)
+{
+ Serial.println(msg);
+}
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/libembroidery/utility/ino-logging.h b/Software/Visual_Studio/Embroidery/libembroidery/utility/ino-logging.h
new file mode 100644
index 000000000..0cdc23de3
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/libembroidery/utility/ino-logging.h
@@ -0,0 +1,17 @@
+/*! @file ino-logging.h */
+#ifndef INO_LOGGING_H
+#define INO_LOGGING_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void inoLog_serial(const char* msg);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* INO_LOGGING_H */
+
+/* kate: bom off; indent-mode cstyle; indent-width 4; replace-trailing-space-save on; */
diff --git a/Software/Visual_Studio/Embroidery/project-files/README.md b/Software/Visual_Studio/Embroidery/project-files/README.md
new file mode 100644
index 000000000..66ad2e4fc
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/README.md
@@ -0,0 +1,9 @@
+Project files
+-------------
+
+This folder contains project files for building Embroidermodder and/or related
+applications on various platforms and with various compilers.
+
+The qmake folder contains our master file which should always be up to date. If you
+wish to add files for another operating system or compiler, we will add them, but
+we will likely not maintain them. If you wish to become a maintainer, please contact us.
diff --git a/Software/Visual_Studio/Embroidery/project-files/TODO b/Software/Visual_Studio/Embroidery/project-files/TODO
new file mode 100644
index 000000000..53327e357
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/TODO
@@ -0,0 +1,160 @@
+//====================
+//Stuff for 2.0 alpha1:
+//====================
+WIP - Statistics from 1.0, needs histogram
+WIP - Saving DST/PES/JEF (varga)
+WIP - Saving CSV/SVG (rt) + CSV read/write UNKNOWN interpreted as COLOR bug
+
+//====================
+//Stuff for 2.0 alpha2:
+//====================
+TODO - Notify user of data loss if not saving to an object format.
+TODO - Import Raster Image
+TODO - SNAP/ORTHO/POLAR
+TODO - Layer Manager + LayerSwitcher DockWidget
+TODO - Reading DXF
+
+//====================
+//Stuff for 2.0 alpha3:
+//====================
+TODO - Writing DXF
+DONE - Up and Down keys cycle thru commands in the command prompt
+TODO - Amount of Thread & Machine Time Estimation (also allow customizable times for setup, color changes, manually trimming jump threads, etc...that way a realistic total time can be estimated)
+TODO - Otto Theme Icons - whatsthis icon doesn't scale well, needs redone
+TODO - embroidermodder2.ico 16 x 16 looks horrible
+
+//====================
+//Stuff for 2.0 alpha4:
+//====================
+WIP - CAD Command: Arc (rt)
+TODO - Load/Save Menu/Toolbars configurations into settings.ini
+TODO - automate changelog and write to a javascript file for the docs: git log --pretty=tformat:'<a href="https://github.com/Embroidermodder/Embroidermodder/commit/%H">%s</a>'
+
+//====================
+//Stuff for 2.0 beta1:
+//====================
+TODO - Custom Filter Bug - doesn't save changes in some cases
+TODO - Cannot open file with # in name when opening multiple files (works fine when opening the single file)
+TODO - Closing Settings Dialog with the X in the window saves settings rather than discards them
+WIP - Advanced Printing
+TODO - Filling Algorithms (varga)
+TODO - Otto Theme Icons - beta (rt) - Units, Render, Selectors
+
+//====================
+//Stuff for 2.0 rc1:
+//====================
+TODO - QDoc Comments
+TODO - Review KDE4 Thumbnailer
+TODO - Documentation for libembroidery & formats
+TODO - HTML Help files
+TODO - Update language translations
+TODO - CAD Command review: line
+TODO - CAD Command review: circle
+TODO - CAD Command review: rectangle
+TODO - CAD Command review: polygon
+TODO - CAD Command review: polyline
+TODO - CAD Command review: point
+TODO - CAD Command review: ellipse
+TODO - CAD Command review: arc
+TODO - CAD Command review: distance
+TODO - CAD Command review: locatepoint
+TODO - CAD Command review: move
+TODO - CAD Command review: rgb
+TODO - CAD Command review: rotate
+TODO - CAD Command review: scale
+TODO - CAD Command review: singlelinetext
+TODO - CAD Command review: star
+TODO - Clean up all compiler warning messages, right now theres plenty :P
+
+//====================
+//Stuff for 2.0 release:
+//====================
+TODO - tar.gz archive
+TODO - zip archive
+TODO - Debian Package (rt)
+TODO - NSIS Installer (rt)
+TODO - Mac Bundle?
+TODO - press release
+
+//====================
+//Stuff for 2.x/Ideas:
+//====================
+TODO - libembroidery.mk for MXE project (refer to qt submodule packages for qmake based building. Also refer to plibc.mk for example of how write an update macro for github.)
+TODO - libembroidery safeguard for all writers - check if the last stitch is an END stitch. If not, add an end stitch in the writer and modify the header data if necessary.
+TODO - Cut/Copy - Allow Post-selection
+TODO - CAD Command: Array
+TODO - CAD Command: Offset
+TODO - CAD Command: Extend
+TODO - CAD Command: Trim
+TODO - CAD Command: BreakAtPoint
+TODO - CAD Command: Break2Points
+TODO - CAD Command: Fillet
+TODO - CAD Command: Chamfer
+TODO - CAD Command: Split
+TODO - CAD Command: Area
+TODO - CAD Command: Time
+TODO - CAD Command: PickAdd
+TODO - CAD Command: Product
+TODO - CAD Command: Program
+TODO - CAD Command: ZoomFactor
+TODO - CAD Command: GripHot
+TODO - CAD Command: GripColor & GripCool
+TODO - CAD Command: GripSize
+TODO - CAD Command: Highlight
+TODO - CAD Command: Units
+TODO - CAD Command: Grid
+TODO - CAD Command: Find
+TODO - CAD Command: Divide
+TODO - CAD Command: ZoomWindow (Move out of view.cpp)
+TODO - Command: Web (Generates Spiderweb patterns)
+TODO - Command: Guilloche (Generates Guilloche patterns)
+TODO - Command: Celtic Knots
+TODO - Command: Knotted Wreath
+TODO - Lego Mindstorms NXT/EV3 ports and/or commands.
+TODO - native function that flashes the command prompt to get users attention when using the prompt is required for a command.
+TODO - libembroidery-composer like app that combines multiple files into one.
+TODO - Settings Dialog, it would be nice to have it notify you when switching tabs that a setting has been changed. Adding an Apply button is what would make sense for this to happen.
+TODO - Keyboard Zooming/Panning
+TODO - G-Code format?
+TODO - 3D Raised Embroidery
+TODO - Gradient Filling Algorithms
+TODO - Stitching Simulation
+TODO - RPM packages?
+TODO - Reports?
+TODO - Record and Playback Commands
+TODO - Settings option for reversing zoom scrolling direction
+TODO - Qt GUI for libembroidery-convert
+TODO - EPS format? Look at using Ghostscript as an optional add-on to libembroidery...
+TODO - optional compile option for including LGPL/GPL libs etc... with warning to user about license requirements.
+TODO - Realistic Visualization - Bump Mapping/OpenGL/Gradients?
+TODO - Stippling Fill
+TODO - User Designed Custom Fill
+TODO - Honeycomb Fill
+TODO - Hilburt Curve Fill
+TODO - Sierpinski Triangle fill
+TODO - Circle Grid Fill
+TODO - Spiral Fill
+TODO - Offset Fill
+TODO - Brick Fill
+TODO - Trim jumps over a certain length.
+TODO - FAQ about setting high number of jumps for more controlled trimming.
+TODO - Minimum stitch length option. (Many machines also have this option too)
+TODO - Add 'Design Details' functionality to libembroidery-convert
+TODO - Add 'Batch convert many to one format' functionality to libembroidery-convert
+TODO - EmbroideryFLOSS - Color picker that displays catalog numbers and names.
+TODO - emscripten/javascript port of libembroidery
+
+//====================
+//Stuff for Arduino:
+//====================
+TODO - Fix emb-outline files
+TODO - Fix thread-color files
+TODO - Logging of Last Stitch Location to External USB Storage(commonly available and easily replaced) ...wait until TRE is available to avoid rework
+TODO - inotool.org - seems like the logical solution for Nightly/CI builds
+TODO - Smoothieboard experiments
+
+//====================
+//libembroidery-tests:
+//====================
+TODO - looping test that reads 10 times while running valgrind. See embPattern_loadExternalColorFile() Arduino leak note for more info.
+
diff --git a/Software/Visual_Studio/Embroidery/project-files/debian/control/control b/Software/Visual_Studio/Embroidery/project-files/debian/control/control
new file mode 100644
index 000000000..8942a6249
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/debian/control/control
@@ -0,0 +1,14 @@
+Package: embroidermodder
+Version: 2.0.0
+Architecture: amd64
+Maintainer: Embroidermodder Team
+Installed-Size: 6000
+Pre-Depends: dpkg (>= 1.15.4)
+Depends: libc6 (>= 2.4), libgcc1 (>= 1:4.1.1), libgl1-mesa-glx | libgl1, libglu1-mesa | libglu1, libqt4-help (>= 4.6.0), libqt4-opengl (>= 4.6.0), libqt4-svg (>= 4.6.0), libqt4-test (>= 4.6.0), libqt4-webkit (>= 4.6.0), libqtcore4 (>= 4.6.0), libqtgui4 (>= 4.6.0), libstdc++6 (>= 4.1.1),
+Section: graphics
+Priority: optional
+Homepage: http://embroidermodder.github.io
+Description: Embroidery modification software
+ Embroidermodder is a free software tool that allows the user to add custom modifications to their embroidery designs.
+ .
+ This package contains the main application. \ No newline at end of file
diff --git a/Software/Visual_Studio/Embroidery/project-files/debian/control/postinst b/Software/Visual_Studio/Embroidery/project-files/debian/control/postinst
new file mode 100644
index 000000000..647663225
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/debian/control/postinst
@@ -0,0 +1,2 @@
+#!/bin/sh
+echo "Installation complete."
diff --git a/Software/Visual_Studio/Embroidery/project-files/debian/control/postrm b/Software/Visual_Studio/Embroidery/project-files/debian/control/postrm
new file mode 100644
index 000000000..13f47935d
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/debian/control/postrm
@@ -0,0 +1,2 @@
+#!/bin/sh
+
diff --git a/Software/Visual_Studio/Embroidery/project-files/debian/control/prerm b/Software/Visual_Studio/Embroidery/project-files/debian/control/prerm
new file mode 100644
index 000000000..13f47935d
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/debian/control/prerm
@@ -0,0 +1,2 @@
+#!/bin/sh
+
diff --git a/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/application-registry/embroidermodder2.applications b/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/application-registry/embroidermodder2.applications
new file mode 100644
index 000000000..51d1106c5
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/application-registry/embroidermodder2.applications
@@ -0,0 +1,7 @@
+embroidermodder2
+ name=EmbroiderModder2
+ command=embroidermodder2
+ requires_terminal=false
+ expects_uris=false
+ can_open_multiple_files=true
+ mime_types=application/x-embroidermodder
diff --git a/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/applications/embroidermodder2.desktop b/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/applications/embroidermodder2.desktop
new file mode 100644
index 000000000..7577e8546
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/applications/embroidermodder2.desktop
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Version=2.0
+Type=Application
+Name=EmbroiderModder 2
+Comment=Embroidery modification software
+Path=/usr/bin
+Exec=/usr/bin/embroidermodder2 %F
+Icon=embroidermodder2.png
+Categories=Graphics;
+MimeType=application/x-embroidermodder \ No newline at end of file
diff --git a/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/doc/embroidermodder2/README b/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/doc/embroidermodder2/README
new file mode 100644
index 000000000..f27601ed5
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/doc/embroidermodder2/README
@@ -0,0 +1,7 @@
+EmbroiderModder 2
+-----------------
+
+1) What is it?
+
+Embroidermodder is a free software tool that allows the user to add custom modifications to their embroidery designs.
+
diff --git a/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/man/man1/embroidermodder2.1.gz b/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/man/man1/embroidermodder2.1.gz
new file mode 100644
index 000000000..6a0a45a2b
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/man/man1/embroidermodder2.1.gz
Binary files differ
diff --git a/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/menu/embroidermodder2 b/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/menu/embroidermodder2
new file mode 100644
index 000000000..1215b2bac
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/menu/embroidermodder2
@@ -0,0 +1,7 @@
+?package(embroidermodder2):needs="X11" \
+ section="Applications/Graphics" \
+ hints="Embroidery" \
+ title="EmbroiderModder2" \
+ longtitle="Embroidery modification software" \
+ icon="/usr/share/pixmaps/embroidermodder2.png" \
+ command="/usr/bin/embroidermodder2"
diff --git a/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/mime-info/embroidermodder2.keys b/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/mime-info/embroidermodder2.keys
new file mode 100644
index 000000000..e54d34378
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/mime-info/embroidermodder2.keys
@@ -0,0 +1,4 @@
+application/x-embroidermodder
+ description=Embroidery File
+ category=Vector Graphics
+ icon_filename=embroidermodder2
diff --git a/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/mime-info/embroidermodder2.mime b/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/mime-info/embroidermodder2.mime
new file mode 100644
index 000000000..7277185ba
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/mime-info/embroidermodder2.mime
@@ -0,0 +1,51 @@
+application/x-embroidermodder
+ ext: 100
+ ext: 10o
+ ext: art
+ ext: bmc
+ ext: bro
+ ext: cnd
+ ext: col
+ ext: csd
+ ext: dat
+ ext: dem
+ ext: dsb
+ ext: dst
+ ext: dsz
+ ext: dxf
+ ext: edr
+ ext: emd
+ ext: exp
+ ext: exy
+ ext: eys
+ ext: fxy
+ ext: gnc
+ ext: gt
+ ext: hus
+ ext: inb
+ ext: jef
+ ext: ksm
+ ext: pcd
+ ext: pcm
+ ext: pcq
+ ext: pcs
+ ext: pec
+ ext: pel
+ ext: pem
+ ext: pes
+ ext: phb
+ ext: phc
+ ext: rgb
+ ext: sew
+ ext: shv
+ ext: sst
+ ext: stx
+ ext: svg
+ ext: t09
+ ext: tap
+ ext: u00
+ ext: u01
+ ext: vip
+ ext: vp3
+ ext: xxx
+ ext: zsk
diff --git a/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/mime/application/x-embroidermodder.xml b/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/mime/application/x-embroidermodder.xml
new file mode 100644
index 000000000..94271def9
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/mime/application/x-embroidermodder.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<mime-type xmlns="http://www.freedesktop.org/standards/shared-mime-info" type="application/x-embroidermodder">
+ <comment>Embroidery File</comment>
+ <icon name="/usr/share/pixmaps/embroidermodder2.png"/>
+ <glob-deleteall/>
+ <glob pattern="*.100"/>
+ <glob pattern="*.10o"/>
+ <glob pattern="*.art"/>
+ <glob pattern="*.bmc"/>
+ <glob pattern="*.bro"/>
+ <glob pattern="*.cnd"/>
+ <glob pattern="*.col"/>
+ <glob pattern="*.csd"/>
+ <glob pattern="*.dat"/>
+ <glob pattern="*.dem"/>
+ <glob pattern="*.dsb"/>
+ <glob pattern="*.dst"/>
+ <glob pattern="*.dsz"/>
+ <glob pattern="*.dxf"/>
+ <glob pattern="*.edr"/>
+ <glob pattern="*.emd"/>
+ <glob pattern="*.exp"/>
+ <glob pattern="*.exy"/>
+ <glob pattern="*.eys"/>
+ <glob pattern="*.fxy"/>
+ <glob pattern="*.gnc"/>
+ <glob pattern="*.gt"/>
+ <glob pattern="*.hus"/>
+ <glob pattern="*.inb"/>
+ <glob pattern="*.jef"/>
+ <glob pattern="*.ksm"/>
+ <glob pattern="*.pcd"/>
+ <glob pattern="*.pcm"/>
+ <glob pattern="*.pcq"/>
+ <glob pattern="*.pcs"/>
+ <glob pattern="*.pec"/>
+ <glob pattern="*.pel"/>
+ <glob pattern="*.pem"/>
+ <glob pattern="*.pes"/>
+ <glob pattern="*.phb"/>
+ <glob pattern="*.phc"/>
+ <glob pattern="*.rgb"/>
+ <glob pattern="*.sew"/>
+ <glob pattern="*.shv"/>
+ <glob pattern="*.sst"/>
+ <glob pattern="*.stx"/>
+ <glob pattern="*.svg"/>
+ <glob pattern="*.t09"/>
+ <glob pattern="*.tap"/>
+ <glob pattern="*.u00"/>
+ <glob pattern="*.u01"/>
+ <glob pattern="*.vip"/>
+ <glob pattern="*.vp3"/>
+ <glob pattern="*.xxx"/>
+ <glob pattern="*.zsk"/>
+</mime-type>
diff --git a/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/pixmaps/embroidermodder2.png b/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/pixmaps/embroidermodder2.png
new file mode 100644
index 000000000..1d7731b8e
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/debian/data/usr/share/pixmaps/embroidermodder2.png
Binary files differ
diff --git a/Software/Visual_Studio/Embroidery/project-files/format-progress.txt b/Software/Visual_Studio/Embroidery/project-files/format-progress.txt
new file mode 100644
index 000000000..a7ad5d9e3
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/format-progress.txt
@@ -0,0 +1,67 @@
+/* TODO: Josh, Review this file and move any info still valid or needing work into TODO comments in the actual
+ * libembroidery code. Many items in this list are out of date and do not reflect the current status of
+ * libembroidery. When finished, delete this file.
+ */
+
+- Test that all formats read data in correct scale (format details should match other programs)
+- Add which formats to work with to preferences.
+- Check for memory leaks
+- Update all formats without color to check for edr or rgb files
+- Fix issues with DST (VERY important that DST work well)
+
+--------------------------------
+libembroidery C formats
+--------------------------------
+FORMAT | READ | WRITE | NOTES
+--------------------------------
+10o | YES | | read (need to fix external color loading) (maybe find out what ctrl code flags of 0x10, 0x08, 0x04, and 0x02 mean)
+100 | | | none (4 byte codes) 61 00 10 09 (type, type2, x, y ?) x & y (signed char)
+art | | | none
+bro | YES | | read (complete)(maybe figure out detail of header)
+cnd | | | none
+col | | | (color file no design) read(final) write(final)
+csd | YES | | read (complete)
+dat | | | read ()
+dem | | | none (looks like just encrypted cnd)
+dsb | YES | | read (unknown how well) (stitch data looks same as 10o)
+dst | YES | | read (complete) / write(unknown)
+dsz | YES | | read (unknown)
+dxf | | | read (Port to C. needs refactored)
+edr | | | read (C version is broken) / write (complete)
+emd | | | read (unknown)
+exp | YES | | read (unknown) / write(unknown)
+exy | YES | | read (need to fix external color loading)
+fxy | YES | | read (need to fix external color loading)
+gnc | | | none
+gt | | | read (need to fix external color loading)
+hus | YES | | read (unknown) / write (C version is broken)
+inb | YES | | read (buggy?)
+jef | YES | | write (need to fix the offsets when it is moving to another spot)
+ksm | YES | | read (unknown) / write (unknown)
+pcd | | |
+pcm | | |
+pcq | | | read (Port to C)
+pcs | BUGGY | | read (buggy / colors are not correct / after reading, writing any other format is messed up)
+pec | | | read / write (without embedded images, sometimes overlooks some stitches leaving a gap)
+pel | | | none
+pem | | | none
+pes | YES | |
+phb | | |
+phc | | |
+rgb | | |
+sew | YES | |
+shv | | | read (C version is broken)
+sst | | | none
+svg | | YES |
+tap | YES | | read (unknown)
+u01 | | |
+vip | YES | |
+vp3 | YES | |
+xxx | YES | |
+zsk | | | read (complete)
+
+
+Support for Singer FHE, CHE (Compucon) formats?
+
+
+
diff --git a/Software/Visual_Studio/Embroidery/project-files/nsis/LICENSE b/Software/Visual_Studio/Embroidery/project-files/nsis/LICENSE
new file mode 100644
index 000000000..99210fe9f
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/nsis/LICENSE
@@ -0,0 +1,11 @@
+Copyright (c) 2011 Embroidermodder Team
+
+This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+
+ 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+
+ 3. This notice may not be removed or altered from any source distribution.
diff --git a/Software/Visual_Studio/Embroidery/project-files/nsis/checkboxes.bmp b/Software/Visual_Studio/Embroidery/project-files/nsis/checkboxes.bmp
new file mode 100644
index 000000000..7713942e0
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/nsis/checkboxes.bmp
Binary files differ
diff --git a/Software/Visual_Studio/Embroidery/project-files/nsis/embroidermodder2-installer.nsi b/Software/Visual_Studio/Embroidery/project-files/nsis/embroidermodder2-installer.nsi
new file mode 100644
index 000000000..5ad13f154
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/nsis/embroidermodder2-installer.nsi
@@ -0,0 +1,157 @@
+#NSIS Modern User Interface
+#Welcome/Finish Page Example Script
+#Written by Joost Verburg
+#Modified for Embroidermodder2
+
+SetCompressor /SOLID lzma
+
+!include "MUI2.nsh"
+
+#--------------------------------
+#Variables
+
+ Var STARTMENUFOLDER
+
+#Constants
+!define _APP_VERSION_ "2.0"
+!define _APP_NAME_ "Embroidermodder2"
+
+!define MUI_ICON "embroidermodder2.ico"
+!define MUI_UNICON "embroidermodder2.ico"
+!define MUI_COMPONENTSPAGE_CHECKBITMAP "checkboxes.bmp"
+
+!define MUI_WELCOMEFINISHPAGE_BITMAP "install.bmp"
+!define MUI_UNWELCOMEFINISHPAGE_BITMAP "uninstall.bmp"
+
+#This displays the header image at the top strip rather than the icon on the right
+!define MUI_HEADERIMAGE
+!define MUI_HEADERIMAGE_BITMAP "header-install.bmp"
+
+BrandingText "Embroidermodder Team"
+
+!define MUI_FINISHPAGE_RUN "embroidermodder2.exe"
+!define MUI_FINISHPAGE_RUN_TEXT "Run Embroidermodder2"
+!define MUI_FINISHPAGE_SHOWREADME "C:\Program Files\Embroidermodder2\help\index.html"
+!define MUI_FINISHPAGE_SHOWREADME_TEXT "View Help"
+!define MUI_FINISHPAGE_LINK "Embroidermodder Home Page"
+!define MUI_FINISHPAGE_LINK_LOCATION "http://embroidermodder.sourceforge.net/"
+
+#--------------------------------
+#General
+
+ #Name and file
+ Name "Embroidermodder2"
+ OutFile "embroidermodder2-installer.exe"
+
+ #Default installation folder
+ InstallDir "$PROGRAMFILES\Embroidermodder2"
+
+ #Get installation folder from registry if available
+ InstallDirRegKey HKCU "Software\Embroidermodder2" ""
+
+ #Request application privileges for Windows Vista
+ RequestExecutionLevel user
+
+#--------------------------------
+#Interface Settings
+
+ !define MUI_ABORTWARNING
+ !define MUI_UNABORTWARNING
+
+#--------------------------------
+#Pages
+
+ !insertmacro MUI_PAGE_WELCOME
+ !insertmacro MUI_PAGE_LICENSE "LICENSE"
+ !insertmacro MUI_PAGE_COMPONENTS
+ !insertmacro MUI_PAGE_DIRECTORY
+
+ #Start Menu Folder Page Configuration
+ !define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKCU"
+ !define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\Embroidermodder2"
+ !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
+ !insertmacro MUI_PAGE_STARTMENU Application $STARTMENUFOLDER
+
+ !insertmacro MUI_PAGE_INSTFILES
+ !insertmacro MUI_PAGE_FINISH
+
+ !insertmacro MUI_UNPAGE_WELCOME
+ !insertmacro MUI_UNPAGE_CONFIRM
+ !insertmacro MUI_UNPAGE_INSTFILES
+ !insertmacro MUI_UNPAGE_FINISH
+
+#--------------------------------
+#Languages
+
+ !insertmacro MUI_LANGUAGE "English"
+
+#--------------------------------
+#Installer Sections
+
+Section "Embroidermodder2" SecEmbMod
+
+ SetOutPath "$INSTDIR"
+
+ #ProgramFiles
+ File "..\..\embroidermodder2\embroidermodder2.exe"
+ File "..\..\embroidermodder2\*.dll"
+ File /r /x *.svn "..\..\embroidermodder2\help"
+ File /r /x *.svn "..\..\embroidermodder2\icons"
+ File /r /x *.svn "..\..\embroidermodder2\images"
+
+ #StartMenu
+ !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
+ CreateDirectory "$SMPROGRAMS\$STARTMENUFOLDER"
+ CreateShortCut "$SMPROGRAMS\$STARTMENUFOLDER\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
+ !insertmacro MUI_STARTMENU_WRITE_END
+
+ #Registry
+ WriteRegStr HKCU "Software\Embroidermodder2" "" $INSTDIR
+
+ #Create uninstaller
+ WriteUninstaller "$INSTDIR\Uninstall.exe"
+
+SectionEnd
+
+Section "Sample Files" SecSample
+
+ SetOutPath "$INSTDIR"
+
+ #ProgramFiles
+ #File /r /x *.svn "..\..\embroidermodder2\samples" #TODO: Add sample files created with Embroidermodder2
+
+SectionEnd
+
+#--------------------------------
+#Descriptions
+
+ #Language strings
+ LangString DESC_SecEmbMod ${LANG_ENGLISH} "The Main Application"
+ LangString DESC_SecSample ${LANG_ENGLISH} "Sample Embroidery Files"
+
+ #Assign language strings to sections
+ !insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
+ !insertmacro MUI_DESCRIPTION_TEXT ${SecEmbMod} $(DESC_SecEmbMod)
+ !insertmacro MUI_DESCRIPTION_TEXT ${SecSample} $(DESC_SecSample)
+ !insertmacro MUI_FUNCTION_DESCRIPTION_END
+
+#--------------------------------
+#Uninstaller Section
+
+Section "Uninstall"
+
+ #ADD YOUR OWN FILES HERE...
+
+ #ProgramFiles
+ Delete "$INSTDIR\Uninstall.exe"
+ RMDir /r "$INSTDIR"
+
+ #StartMenu
+ !insertmacro MUI_STARTMENU_GETFOLDER Application $STARTMENUFOLDER
+ Delete "$SMPROGRAMS\$STARTMENUFOLDER\Uninstall.lnk"
+ RMDir "$SMPROGRAMS\$STARTMENUFOLDER"
+
+ #Registry
+ DeleteRegKey /ifempty HKCU "Software\Embroidermodder2"
+
+SectionEnd
diff --git a/Software/Visual_Studio/Embroidery/project-files/nsis/embroidermodder2.ico b/Software/Visual_Studio/Embroidery/project-files/nsis/embroidermodder2.ico
new file mode 100644
index 000000000..dac5d27b1
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/nsis/embroidermodder2.ico
Binary files differ
diff --git a/Software/Visual_Studio/Embroidery/project-files/nsis/header-install.bmp b/Software/Visual_Studio/Embroidery/project-files/nsis/header-install.bmp
new file mode 100644
index 000000000..4ac1413b3
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/nsis/header-install.bmp
Binary files differ
diff --git a/Software/Visual_Studio/Embroidery/project-files/nsis/header-uninstall.bmp b/Software/Visual_Studio/Embroidery/project-files/nsis/header-uninstall.bmp
new file mode 100644
index 000000000..97be6746e
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/nsis/header-uninstall.bmp
Binary files differ
diff --git a/Software/Visual_Studio/Embroidery/project-files/nsis/install.bmp b/Software/Visual_Studio/Embroidery/project-files/nsis/install.bmp
new file mode 100644
index 000000000..196a5b7a7
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/nsis/install.bmp
Binary files differ
diff --git a/Software/Visual_Studio/Embroidery/project-files/nsis/uninstall.bmp b/Software/Visual_Studio/Embroidery/project-files/nsis/uninstall.bmp
new file mode 100644
index 000000000..097d09429
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/nsis/uninstall.bmp
Binary files differ
diff --git a/Software/Visual_Studio/Embroidery/project-files/osx/README.md b/Software/Visual_Studio/Embroidery/project-files/osx/README.md
new file mode 100644
index 000000000..c38cc5ed7
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/osx/README.md
@@ -0,0 +1,14 @@
+OSX project files
+-----------------
+
+OSX 10.8 Mountain Lion and newer should work.
+
+We do not maintain XCode project files.
+You can compile qmake .pro files via terminal using homebrew
+or alternatively by using QtCreator.
+
+Troubleshooting
+---------------
+
+GCC/G++ is currently used. If you wish to use Clang and have issues,
+please open a bug report, pull request or patch and we will look into the issue.
diff --git a/Software/Visual_Studio/Embroidery/project-files/qmake/README.md b/Software/Visual_Studio/Embroidery/project-files/qmake/README.md
new file mode 100644
index 000000000..61c3bbee6
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/qmake/README.md
@@ -0,0 +1,32 @@
+Master project file
+-------------------
+
+This folder contains a file called everything.pro that is used with qmake.
+It builds Embroidermodder 2 (gui binary), libembroidery-convert (console binary),
+a KDE4 thumbnailer (on linux/unix platforms only).
+
+You will need to refer to the README files in the respective folders for further instructions on usage.
+
+Building
+-----------
+
+Open a terminal and type:
+```
+qmake && make
+```
+
+Other files
+-----------
+
+This folder also contains linux/unix shell scripts so that after building,
+you can easily run them from this folder easily. For example:
+
+To run Embroidermodder 2:
+```
+./embroidermodder2
+```
+
+To run our command line file conversion tool:
+```
+./libembroidery-convert
+```
diff --git a/Software/Visual_Studio/Embroidery/project-files/qmake/embroidermodder2 b/Software/Visual_Studio/Embroidery/project-files/qmake/embroidermodder2
new file mode 100644
index 000000000..e5b73f466
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/qmake/embroidermodder2
@@ -0,0 +1,3 @@
+#!/bin/sh
+cd ../../embroidermodder2
+./embroidermodder2 $@
diff --git a/Software/Visual_Studio/Embroidery/project-files/qmake/everything.pro b/Software/Visual_Studio/Embroidery/project-files/qmake/everything.pro
new file mode 100644
index 000000000..bfee5f849
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/qmake/everything.pro
@@ -0,0 +1,44 @@
+########################
+# everything.pro #
+########################
+# This Qt4/5 project #
+# file will build all #
+# applications #
+########################
+
+TEMPLATE = subdirs
+CONFIG += ordered
+
+##########################
+# Linux/Unix #
+##########################
+
+unix:!macx {
+SUBDIRS = \
+../../thumbnailer-kde4 \
+../../libembroidery-convert \
+../../embroidermodder2 \
+
+}
+
+##########################
+# Windows #
+##########################
+
+win32 {
+SUBDIRS = \
+../../libembroidery-convert \
+../../embroidermodder2 \
+
+}
+
+##########################
+# Mac OSX #
+##########################
+
+macx {
+SUBDIRS = \
+../../libembroidery-convert \
+../../embroidermodder2 \
+
+}
diff --git a/Software/Visual_Studio/Embroidery/project-files/qmake/libembroidery-convert b/Software/Visual_Studio/Embroidery/project-files/qmake/libembroidery-convert
new file mode 100644
index 000000000..094b0ed24
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/qmake/libembroidery-convert
@@ -0,0 +1,3 @@
+#!/bin/sh
+cd ../../libembroidery-convert
+./libembroidery-convert $@
diff --git a/Software/Visual_Studio/Embroidery/project-files/version/MAJOR.txt b/Software/Visual_Studio/Embroidery/project-files/version/MAJOR.txt
new file mode 100644
index 000000000..37bcc8b8c
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/version/MAJOR.txt
@@ -0,0 +1 @@
+1
diff --git a/Software/Visual_Studio/Embroidery/project-files/version/MINOR.txt b/Software/Visual_Studio/Embroidery/project-files/version/MINOR.txt
new file mode 100644
index 000000000..47e0b6a4c
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/version/MINOR.txt
@@ -0,0 +1 @@
+90
diff --git a/Software/Visual_Studio/Embroidery/project-files/version/PATCH.txt b/Software/Visual_Studio/Embroidery/project-files/version/PATCH.txt
new file mode 100644
index 000000000..ff95acde3
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/version/PATCH.txt
@@ -0,0 +1 @@
+0
diff --git a/Software/Visual_Studio/Embroidery/project-files/version/README.md b/Software/Visual_Studio/Embroidery/project-files/version/README.md
new file mode 100644
index 000000000..2f4802d3a
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/version/README.md
@@ -0,0 +1,17 @@
+Version Info
+------------
+
+* MAJOR.txt - Contains the major release version number.
+This will be updated to 2 when Embroidermodder 2 is final.
+Until then, it is set to 1 while Embroidermodder 2 is in development.
+
+* MINOR.txt - Contains the minor release version number.
+This file will be updated frequently when minor releases happen.
+It will be set to zero when Embroidermodder 2 is final.
+Until then, it is set to 90+ while Embroidermodder 2 is in development.
+The number shall be 2 digits, padded with a zero for single digit numbers.
+
+* PATCH.txt - Contains the patch release version number.
+This file will always be zero. Nightly builds will not use this file and
+will use the build unix date as such: ```date +%Y%m%d%H%M%S```
+This ensures that the latest build is always the highest number.
diff --git a/Software/Visual_Studio/Embroidery/project-files/visualstudio/.gitignore b/Software/Visual_Studio/Embroidery/project-files/visualstudio/.gitignore
new file mode 100644
index 000000000..57a1574c4
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/visualstudio/.gitignore
@@ -0,0 +1,196 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+build/
+bld/
+[Bb]in/
+[Oo]bj/
+
+# Visual Studo 2015 cache/options directory
+.vs/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opensdf
+*.sdf
+*.cachefile
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding addin-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+
+# Windows Azure Build Output
+csx/
+*.build.csdef
+
+# Windows Store app package directory
+AppPackages/
+
+# Others
+*.[Cc]ache
+ClientBin/
+[Ss]tyle[Cc]op.*
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.pfx
+*.publishsettings
+node_modules/
+bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
diff --git a/Software/Visual_Studio/Embroidery/project-files/visualstudio/README.md b/Software/Visual_Studio/Embroidery/project-files/visualstudio/README.md
new file mode 100644
index 000000000..774a9737c
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/visualstudio/README.md
@@ -0,0 +1,19 @@
+Visual Studio project files
+---------------------------
+
+We recommend using Visual Studio 2010 or newer.
+
+Troubleshooting
+---------------
+
+If for some reason you cannot build with Visual Studio, try this:
+
+1) There may be an error in our code. If this is the case and you can
+ easily spot and fix the error, please send us a bug report, pull request
+ or patch and as we are likely not aware of the problem.
+
+2) Maintaining multiple build configurations for different operating systems
+ and compilers is quite tedious. We use Qt's qmake as our primary build
+ system because it is cross-platform. Try building with those files instead
+ and if they work, the file you are using here may be out of sync with the
+ latest .pro file needed for a particular component.
diff --git a/Software/Visual_Studio/Embroidery/project-files/visualstudio/libEmbroideryVS2008.sln b/Software/Visual_Studio/Embroidery/project-files/visualstudio/libEmbroideryVS2008.sln
new file mode 100644
index 000000000..bc796953c
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/visualstudio/libEmbroideryVS2008.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual C++ Express 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libEmbroidery", "libEmbroideryVS2008.vcproj", "{BD30C7BD-9230-4ED7-B581-11F14041909D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {BD30C7BD-9230-4ED7-B581-11F14041909D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {BD30C7BD-9230-4ED7-B581-11F14041909D}.Debug|Win32.Build.0 = Debug|Win32
+ {BD30C7BD-9230-4ED7-B581-11F14041909D}.Release|Win32.ActiveCfg = Release|Win32
+ {BD30C7BD-9230-4ED7-B581-11F14041909D}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Software/Visual_Studio/Embroidery/project-files/visualstudio/libEmbroideryVS2008.vcproj b/Software/Visual_Studio/Embroidery/project-files/visualstudio/libEmbroideryVS2008.vcproj
new file mode 100644
index 000000000..6e5d16999
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/visualstudio/libEmbroideryVS2008.vcproj
@@ -0,0 +1,982 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="libEmbroidery"
+ ProjectGUID="{BD30C7BD-9230-4ED7-B581-11F14041909D}"
+ RootNamespace="libEmbroidery"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\libgeometry"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBEMBROIDERY_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="2"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBEMBROIDERY_EXPORTS"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\libembroidery\compound-file-difat.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\compound-file-directory.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\compound-file-fat.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\compound-file-header.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\compound-file.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-arc.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-circle.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-color.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-compress.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-ellipse.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-file.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-flag.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-hash.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-hoop.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-layer.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-line.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-logging.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-path.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-pattern.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-point.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-polygon.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-polyline.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-reader-writer.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-rect.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-satin-line.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-settings.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-spline.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-stitch.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-thread.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-time.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-vector.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-100.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-10o.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-art.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-bmc.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-bro.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-cnd.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-col.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-csd.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-csv.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-dat.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-dem.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-dsb.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-dst.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-dsz.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-dxf.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-edr.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-emd.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-exp.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-exy.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-eys.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-fxy.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-gnc.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-gt.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-hus.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-inb.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-inf.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-jef.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-ksm.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-max.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-mit.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-new.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-ofm.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-pcd.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-pcm.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-pcq.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-pcs.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-pec.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-pel.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-pem.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-pes.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-phb.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-phc.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-plt.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-rgb.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-sew.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-shv.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-sst.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-stx.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-svg.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-t09.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-tap.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-thr.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-txt.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-u00.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-u01.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-vip.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-vp3.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-xxx.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-zsk.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\formats.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libgeometry\geom-arc.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libgeometry\geom-circle.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libgeometry\geom-line.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\hashtable.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\helpers-binary.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\helpers-misc.c"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\thread-color.c"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\libembroidery\compound-file-common.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\compound-file-difat.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\compound-file-directory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\compound-file-fat.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\compound-file-header.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\compound-file.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-arc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-circle.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-color.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-compress.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-ellipse.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-file.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-flag.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-hash.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-hoop.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-layer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-line.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-logging.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-path.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-pattern.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-point.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-polygon.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-polyline.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-reader-writer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-rect.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-satin-line.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-settings.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-spline.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-stitch.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-thread.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-time.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\emb-vector.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-100.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-10o.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-art.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-bmc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-bro.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-cnd.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-col.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-csd.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-csv.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-dat.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-dem.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-dsb.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-dst.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-dsz.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-dxf.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-edr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-emd.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-exp.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-exy.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-eys.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-fxy.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-gnc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-gt.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-hus.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-inb.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-inf.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-jef.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-ksm.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-max.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-mit.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-new.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-ofm.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-pcd.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-pcm.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-pcq.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-pcs.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-pec.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-pel.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-pem.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-pes.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-phb.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-phc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-plt.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-rgb.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-sew.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-shv.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-sst.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-stx.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-svg.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-t09.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-tap.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-thr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-txt.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-u00.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-u01.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-vip.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-vp3.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-xxx.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\format-zsk.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\formats.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libgeometry\geom-arc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libgeometry\geom-circle.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libgeometry\geom-line.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\hashtable.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\helpers-binary.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\helpers-misc.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\helpers-unused.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\libembroidery\thread-color.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/Software/Visual_Studio/Embroidery/project-files/visualstudio/libEmbroideryVS2008.vcxproj b/Software/Visual_Studio/Embroidery/project-files/visualstudio/libEmbroideryVS2008.vcxproj
new file mode 100644
index 000000000..5582f9322
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/visualstudio/libEmbroideryVS2008.vcxproj
@@ -0,0 +1,299 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectName>libEmbroidery</ProjectName>
+ <ProjectGuid>{BD30C7BD-9230-4ED7-B581-11F14041909D}</ProjectGuid>
+ <RootNamespace>libEmbroidery</RootNamespace>
+ <Keyword>Win32Proj</Keyword>
+ <WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <_ProjectFileVersion>14.0.25123.0</_ProjectFileVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
+ <IntDir>$(Configuration)\</IntDir>
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(SolutionDir)$(Configuration)\</OutDir>
+ <IntDir>$(Configuration)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\libgeometry;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBEMBROIDERY_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>true</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MaxSpeed</Optimization>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBEMBROIDERY_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <PrecompiledHeader />
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <Link>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <TargetMachine>MachineX86</TargetMachine>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\libembroidery\compound-file-difat.c" />
+ <ClCompile Include="..\..\libembroidery\compound-file-directory.c" />
+ <ClCompile Include="..\..\libembroidery\compound-file-fat.c" />
+ <ClCompile Include="..\..\libembroidery\compound-file-header.c" />
+ <ClCompile Include="..\..\libembroidery\compound-file.c" />
+ <ClCompile Include="..\..\libembroidery\emb-arc.c" />
+ <ClCompile Include="..\..\libembroidery\emb-circle.c" />
+ <ClCompile Include="..\..\libembroidery\emb-color.c" />
+ <ClCompile Include="..\..\libembroidery\emb-compress.c" />
+ <ClCompile Include="..\..\libembroidery\emb-ellipse.c" />
+ <ClCompile Include="..\..\libembroidery\emb-file.c" />
+ <ClCompile Include="..\..\libembroidery\emb-flag.c" />
+ <ClCompile Include="..\..\libembroidery\emb-hash.c" />
+ <ClCompile Include="..\..\libembroidery\emb-hoop.c" />
+ <ClCompile Include="..\..\libembroidery\emb-layer.c" />
+ <ClCompile Include="..\..\libembroidery\emb-line.c" />
+ <ClCompile Include="..\..\libembroidery\emb-logging.c" />
+ <ClCompile Include="..\..\libembroidery\emb-path.c" />
+ <ClCompile Include="..\..\libembroidery\emb-pattern.c" />
+ <ClCompile Include="..\..\libembroidery\emb-point.c" />
+ <ClCompile Include="..\..\libembroidery\emb-polygon.c" />
+ <ClCompile Include="..\..\libembroidery\emb-polyline.c" />
+ <ClCompile Include="..\..\libembroidery\emb-reader-writer.c" />
+ <ClCompile Include="..\..\libembroidery\emb-rect.c" />
+ <ClCompile Include="..\..\libembroidery\emb-satin-line.c" />
+ <ClCompile Include="..\..\libembroidery\emb-settings.c" />
+ <ClCompile Include="..\..\libembroidery\emb-spline.c" />
+ <ClCompile Include="..\..\libembroidery\emb-stitch.c" />
+ <ClCompile Include="..\..\libembroidery\emb-thread.c" />
+ <ClCompile Include="..\..\libembroidery\emb-time.c" />
+ <ClCompile Include="..\..\libembroidery\emb-vector.c" />
+ <ClCompile Include="..\..\libembroidery\format-100.c" />
+ <ClCompile Include="..\..\libembroidery\format-10o.c" />
+ <ClCompile Include="..\..\libembroidery\format-art.c" />
+ <ClCompile Include="..\..\libembroidery\format-bmc.c" />
+ <ClCompile Include="..\..\libembroidery\format-bro.c" />
+ <ClCompile Include="..\..\libembroidery\format-cnd.c" />
+ <ClCompile Include="..\..\libembroidery\format-col.c" />
+ <ClCompile Include="..\..\libembroidery\format-csd.c" />
+ <ClCompile Include="..\..\libembroidery\format-csv.c" />
+ <ClCompile Include="..\..\libembroidery\format-dat.c" />
+ <ClCompile Include="..\..\libembroidery\format-dem.c" />
+ <ClCompile Include="..\..\libembroidery\format-dsb.c" />
+ <ClCompile Include="..\..\libembroidery\format-dst.c" />
+ <ClCompile Include="..\..\libembroidery\format-dsz.c" />
+ <ClCompile Include="..\..\libembroidery\format-dxf.c" />
+ <ClCompile Include="..\..\libembroidery\format-edr.c" />
+ <ClCompile Include="..\..\libembroidery\format-emd.c" />
+ <ClCompile Include="..\..\libembroidery\format-exp.c" />
+ <ClCompile Include="..\..\libembroidery\format-exy.c" />
+ <ClCompile Include="..\..\libembroidery\format-eys.c" />
+ <ClCompile Include="..\..\libembroidery\format-fxy.c" />
+ <ClCompile Include="..\..\libembroidery\format-gc.c" />
+ <ClCompile Include="..\..\libembroidery\format-gnc.c" />
+ <ClCompile Include="..\..\libembroidery\format-gt.c" />
+ <ClCompile Include="..\..\libembroidery\format-hus.c" />
+ <ClCompile Include="..\..\libembroidery\format-inb.c" />
+ <ClCompile Include="..\..\libembroidery\format-inf.c" />
+ <ClCompile Include="..\..\libembroidery\format-jef.c" />
+ <ClCompile Include="..\..\libembroidery\format-ksm.c" />
+ <ClCompile Include="..\..\libembroidery\format-max.c" />
+ <ClCompile Include="..\..\libembroidery\format-mit.c" />
+ <ClCompile Include="..\..\libembroidery\format-new.c" />
+ <ClCompile Include="..\..\libembroidery\format-ofm.c" />
+ <ClCompile Include="..\..\libembroidery\format-pcd.c" />
+ <ClCompile Include="..\..\libembroidery\format-pcm.c" />
+ <ClCompile Include="..\..\libembroidery\format-pcq.c" />
+ <ClCompile Include="..\..\libembroidery\format-pcs.c" />
+ <ClCompile Include="..\..\libembroidery\format-pec.c" />
+ <ClCompile Include="..\..\libembroidery\format-pel.c" />
+ <ClCompile Include="..\..\libembroidery\format-pem.c" />
+ <ClCompile Include="..\..\libembroidery\format-pes.c" />
+ <ClCompile Include="..\..\libembroidery\format-phb.c" />
+ <ClCompile Include="..\..\libembroidery\format-phc.c" />
+ <ClCompile Include="..\..\libembroidery\format-plt.c" />
+ <ClCompile Include="..\..\libembroidery\format-rgb.c" />
+ <ClCompile Include="..\..\libembroidery\format-sew.c" />
+ <ClCompile Include="..\..\libembroidery\format-shv.c" />
+ <ClCompile Include="..\..\libembroidery\format-sst.c" />
+ <ClCompile Include="..\..\libembroidery\format-stx.c" />
+ <ClCompile Include="..\..\libembroidery\format-svg.c" />
+ <ClCompile Include="..\..\libembroidery\format-t01.c" />
+ <ClCompile Include="..\..\libembroidery\format-t09.c" />
+ <ClCompile Include="..\..\libembroidery\format-tap.c" />
+ <ClCompile Include="..\..\libembroidery\format-thr.c" />
+ <ClCompile Include="..\..\libembroidery\format-txt.c" />
+ <ClCompile Include="..\..\libembroidery\format-u00.c" />
+ <ClCompile Include="..\..\libembroidery\format-u01.c" />
+ <ClCompile Include="..\..\libembroidery\format-vip.c" />
+ <ClCompile Include="..\..\libembroidery\format-vp3.c" />
+ <ClCompile Include="..\..\libembroidery\format-xxx.c" />
+ <ClCompile Include="..\..\libembroidery\format-zsk.c" />
+ <ClCompile Include="..\..\libembroidery\hashtable.c" />
+ <ClCompile Include="..\..\libembroidery\helpers-binary.c" />
+ <ClCompile Include="..\..\libembroidery\helpers-misc.c" />
+ <ClCompile Include="..\..\libembroidery\thread-color.c" />
+ <ClCompile Include="..\..\libembroidery\geom-arc.c" />
+ <ClCompile Include="..\..\libembroidery\geom-circle.c" />
+ <ClCompile Include="..\..\libembroidery\geom-line.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\libembroidery\compound-file-common.h" />
+ <ClInclude Include="..\..\libembroidery\compound-file-difat.h" />
+ <ClInclude Include="..\..\libembroidery\compound-file-directory.h" />
+ <ClInclude Include="..\..\libembroidery\compound-file-fat.h" />
+ <ClInclude Include="..\..\libembroidery\compound-file-header.h" />
+ <ClInclude Include="..\..\libembroidery\compound-file.h" />
+ <ClInclude Include="..\..\libembroidery\emb-arc.h" />
+ <ClInclude Include="..\..\libembroidery\emb-circle.h" />
+ <ClInclude Include="..\..\libembroidery\emb-color.h" />
+ <ClInclude Include="..\..\libembroidery\emb-compress.h" />
+ <ClInclude Include="..\..\libembroidery\emb-ellipse.h" />
+ <ClInclude Include="..\..\libembroidery\emb-file.h" />
+ <ClInclude Include="..\..\libembroidery\emb-flag.h" />
+ <ClInclude Include="..\..\libembroidery\emb-hash.h" />
+ <ClInclude Include="..\..\libembroidery\emb-hoop.h" />
+ <ClInclude Include="..\..\libembroidery\emb-layer.h" />
+ <ClInclude Include="..\..\libembroidery\emb-line.h" />
+ <ClInclude Include="..\..\libembroidery\emb-logging.h" />
+ <ClInclude Include="..\..\libembroidery\emb-path.h" />
+ <ClInclude Include="..\..\libembroidery\emb-pattern.h" />
+ <ClInclude Include="..\..\libembroidery\emb-point.h" />
+ <ClInclude Include="..\..\libembroidery\emb-polygon.h" />
+ <ClInclude Include="..\..\libembroidery\emb-polyline.h" />
+ <ClInclude Include="..\..\libembroidery\emb-reader-writer.h" />
+ <ClInclude Include="..\..\libembroidery\emb-rect.h" />
+ <ClInclude Include="..\..\libembroidery\emb-satin-line.h" />
+ <ClInclude Include="..\..\libembroidery\emb-settings.h" />
+ <ClInclude Include="..\..\libembroidery\emb-spline.h" />
+ <ClInclude Include="..\..\libembroidery\emb-stitch.h" />
+ <ClInclude Include="..\..\libembroidery\emb-thread.h" />
+ <ClInclude Include="..\..\libembroidery\emb-time.h" />
+ <ClInclude Include="..\..\libembroidery\emb-vector.h" />
+ <ClInclude Include="..\..\libembroidery\format-100.h" />
+ <ClInclude Include="..\..\libembroidery\format-10o.h" />
+ <ClInclude Include="..\..\libembroidery\format-art.h" />
+ <ClInclude Include="..\..\libembroidery\format-bmc.h" />
+ <ClInclude Include="..\..\libembroidery\format-bro.h" />
+ <ClInclude Include="..\..\libembroidery\format-cnd.h" />
+ <ClInclude Include="..\..\libembroidery\format-col.h" />
+ <ClInclude Include="..\..\libembroidery\format-csd.h" />
+ <ClInclude Include="..\..\libembroidery\format-csv.h" />
+ <ClInclude Include="..\..\libembroidery\format-dat.h" />
+ <ClInclude Include="..\..\libembroidery\format-dem.h" />
+ <ClInclude Include="..\..\libembroidery\format-dsb.h" />
+ <ClInclude Include="..\..\libembroidery\format-dst.h" />
+ <ClInclude Include="..\..\libembroidery\format-dsz.h" />
+ <ClInclude Include="..\..\libembroidery\format-dxf.h" />
+ <ClInclude Include="..\..\libembroidery\format-edr.h" />
+ <ClInclude Include="..\..\libembroidery\format-emd.h" />
+ <ClInclude Include="..\..\libembroidery\format-exp.h" />
+ <ClInclude Include="..\..\libembroidery\format-exy.h" />
+ <ClInclude Include="..\..\libembroidery\format-eys.h" />
+ <ClInclude Include="..\..\libembroidery\format-fxy.h" />
+ <ClInclude Include="..\..\libembroidery\format-gnc.h" />
+ <ClInclude Include="..\..\libembroidery\format-gt.h" />
+ <ClInclude Include="..\..\libembroidery\format-hus.h" />
+ <ClInclude Include="..\..\libembroidery\format-inb.h" />
+ <ClInclude Include="..\..\libembroidery\format-inf.h" />
+ <ClInclude Include="..\..\libembroidery\format-jef.h" />
+ <ClInclude Include="..\..\libembroidery\format-ksm.h" />
+ <ClInclude Include="..\..\libembroidery\format-max.h" />
+ <ClInclude Include="..\..\libembroidery\format-mit.h" />
+ <ClInclude Include="..\..\libembroidery\format-new.h" />
+ <ClInclude Include="..\..\libembroidery\format-ofm.h" />
+ <ClInclude Include="..\..\libembroidery\format-pcd.h" />
+ <ClInclude Include="..\..\libembroidery\format-pcm.h" />
+ <ClInclude Include="..\..\libembroidery\format-pcq.h" />
+ <ClInclude Include="..\..\libembroidery\format-pcs.h" />
+ <ClInclude Include="..\..\libembroidery\format-pec.h" />
+ <ClInclude Include="..\..\libembroidery\format-pel.h" />
+ <ClInclude Include="..\..\libembroidery\format-pem.h" />
+ <ClInclude Include="..\..\libembroidery\format-pes.h" />
+ <ClInclude Include="..\..\libembroidery\format-phb.h" />
+ <ClInclude Include="..\..\libembroidery\format-phc.h" />
+ <ClInclude Include="..\..\libembroidery\format-plt.h" />
+ <ClInclude Include="..\..\libembroidery\format-rgb.h" />
+ <ClInclude Include="..\..\libembroidery\format-sew.h" />
+ <ClInclude Include="..\..\libembroidery\format-shv.h" />
+ <ClInclude Include="..\..\libembroidery\format-sst.h" />
+ <ClInclude Include="..\..\libembroidery\format-stx.h" />
+ <ClInclude Include="..\..\libembroidery\format-svg.h" />
+ <ClInclude Include="..\..\libembroidery\format-t01.h" />
+ <ClInclude Include="..\..\libembroidery\format-t09.h" />
+ <ClInclude Include="..\..\libembroidery\format-tap.h" />
+ <ClInclude Include="..\..\libembroidery\format-thr.h" />
+ <ClInclude Include="..\..\libembroidery\format-txt.h" />
+ <ClInclude Include="..\..\libembroidery\format-u00.h" />
+ <ClInclude Include="..\..\libembroidery\format-u01.h" />
+ <ClInclude Include="..\..\libembroidery\format-vip.h" />
+ <ClInclude Include="..\..\libembroidery\format-vp3.h" />
+ <ClInclude Include="..\..\libembroidery\format-xxx.h" />
+ <ClInclude Include="..\..\libembroidery\format-zsk.h" />
+ <ClInclude Include="..\..\libembroidery\formats.h" />
+ <ClInclude Include="..\..\libembroidery\hashtable.h" />
+ <ClInclude Include="..\..\libembroidery\helpers-binary.h" />
+ <ClInclude Include="..\..\libembroidery\helpers-misc.h" />
+ <ClInclude Include="..\..\libembroidery\helpers-unused.h" />
+ <ClInclude Include="..\..\libembroidery\thread-color.h" />
+ <ClInclude Include="..\..\libgeometry\geom-arc.h" />
+ <ClInclude Include="..\..\libgeometry\geom-circle.h" />
+ <ClInclude Include="..\..\libgeometry\geom-line.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/Embroidery/project-files/visualstudio/libEmbroideryVS2008.vcxproj.filters b/Software/Visual_Studio/Embroidery/project-files/visualstudio/libEmbroideryVS2008.vcxproj.filters
new file mode 100644
index 000000000..3a249cc5a
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/visualstudio/libEmbroideryVS2008.vcxproj.filters
@@ -0,0 +1,612 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\libembroidery\compound-file-difat.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\compound-file-directory.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\compound-file-fat.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\compound-file-header.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\compound-file.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-arc.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-circle.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-color.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-compress.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-ellipse.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-file.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-flag.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-hash.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-hoop.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-layer.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-line.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-logging.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-path.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-pattern.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-point.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-polygon.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-polyline.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-reader-writer.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-rect.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-satin-line.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-settings.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-spline.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-stitch.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-thread.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-time.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\emb-vector.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-100.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-10o.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-art.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-bmc.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-bro.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-cnd.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-col.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-csd.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-csv.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-dat.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-dem.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-dsb.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-dst.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-dsz.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-dxf.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-edr.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-emd.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-exp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-exy.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-eys.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-fxy.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-gnc.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-gt.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-hus.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-inb.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-inf.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-jef.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-ksm.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-max.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-mit.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-new.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-ofm.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-pcd.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-pcm.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-pcq.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-pcs.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-pec.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-pel.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-pem.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-pes.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-phb.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-phc.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-plt.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-rgb.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-sew.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-shv.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-sst.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-stx.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-svg.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-t09.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-tap.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-thr.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-txt.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-u00.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-u01.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-vip.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-vp3.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-xxx.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\format-zsk.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\hashtable.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\helpers-binary.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\helpers-misc.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\thread-color.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\geom-arc.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\geom-circle.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\libembroidery\geom-line.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\libembroidery\compound-file-common.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\compound-file-difat.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\compound-file-directory.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\compound-file-fat.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\compound-file-header.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\compound-file.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-arc.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-circle.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-color.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-compress.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-ellipse.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-file.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-flag.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-hash.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-hoop.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-layer.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-line.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-logging.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-path.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-pattern.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-point.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-polygon.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-polyline.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-reader-writer.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-rect.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-satin-line.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-settings.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-spline.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-stitch.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-thread.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-time.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\emb-vector.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-100.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-10o.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-art.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-bmc.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-bro.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-cnd.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-col.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-csd.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-csv.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-dat.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-dem.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-dsb.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-dst.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-dsz.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-dxf.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-edr.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-emd.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-exp.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-exy.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-eys.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-fxy.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-gnc.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-gt.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-hus.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-inb.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-inf.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-jef.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-ksm.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-max.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-mit.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-new.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-ofm.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-pcd.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-pcm.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-pcq.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-pcs.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-pec.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-pel.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-pem.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-pes.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-phb.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-phc.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-plt.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-rgb.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-sew.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-shv.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-sst.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-stx.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-svg.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-t09.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-tap.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-thr.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-txt.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-u00.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-u01.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-vip.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-vp3.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-xxx.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\format-zsk.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\formats.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\hashtable.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\helpers-binary.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\helpers-misc.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\helpers-unused.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\thread-color.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\geom-arc.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\geom-circle.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\libembroidery\geom-line.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/Embroidery/project-files/visualstudio/libEmbroideryVS2013.sln b/Software/Visual_Studio/Embroidery/project-files/visualstudio/libEmbroideryVS2013.sln
new file mode 100644
index 000000000..03586913a
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/visualstudio/libEmbroideryVS2013.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.31101.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libEmbroidery", "libEmbroideryVS2008.vcxproj", "{BD30C7BD-9230-4ED7-B581-11F14041909D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {BD30C7BD-9230-4ED7-B581-11F14041909D}.Debug|Win32.ActiveCfg = Debug|Win32
+ {BD30C7BD-9230-4ED7-B581-11F14041909D}.Debug|Win32.Build.0 = Debug|Win32
+ {BD30C7BD-9230-4ED7-B581-11F14041909D}.Release|Win32.ActiveCfg = Release|Win32
+ {BD30C7BD-9230-4ED7-B581-11F14041909D}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Software/Visual_Studio/Embroidery/project-files/visualstudio/libembroidery-convert.sln b/Software/Visual_Studio/Embroidery/project-files/visualstudio/libembroidery-convert.sln
new file mode 100644
index 000000000..ccc0f553a
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/visualstudio/libembroidery-convert.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libembroidery-convert", "libembroidery-convert.vcxproj", "{6A3DDF09-228A-46EE-8DB1-1DA8760FCB1F}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {6A3DDF09-228A-46EE-8DB1-1DA8760FCB1F}.Debug|Win32.ActiveCfg = Debug|Win32
+ {6A3DDF09-228A-46EE-8DB1-1DA8760FCB1F}.Debug|Win32.Build.0 = Debug|Win32
+ {6A3DDF09-228A-46EE-8DB1-1DA8760FCB1F}.Release|Win32.ActiveCfg = Release|Win32
+ {6A3DDF09-228A-46EE-8DB1-1DA8760FCB1F}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Software/Visual_Studio/Embroidery/project-files/visualstudio/libembroidery-convert.vcxproj b/Software/Visual_Studio/Embroidery/project-files/visualstudio/libembroidery-convert.vcxproj
new file mode 100644
index 000000000..08358f2d5
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/visualstudio/libembroidery-convert.vcxproj
@@ -0,0 +1,290 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{6A3DDF09-228A-46EE-8DB1-1DA8760FCB1F}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>libembroidery</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <TargetExt>.exe</TargetExt>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BrowseInformation>true</BrowseInformation>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ <Bscmake>
+ <PreserveSbr>true</PreserveSbr>
+ </Bscmake>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\libembroidery-convert\libembroidery-convert-main.c" />
+ <ClCompile Include="..\..\libembroidery\compound-file-difat.c" />
+ <ClCompile Include="..\..\libembroidery\compound-file-directory.c" />
+ <ClCompile Include="..\..\libembroidery\compound-file-fat.c" />
+ <ClCompile Include="..\..\libembroidery\compound-file-header.c" />
+ <ClCompile Include="..\..\libembroidery\compound-file.c" />
+ <ClCompile Include="..\..\libembroidery\emb-arc.c" />
+ <ClCompile Include="..\..\libembroidery\emb-circle.c" />
+ <ClCompile Include="..\..\libembroidery\emb-color.c" />
+ <ClCompile Include="..\..\libembroidery\emb-compress.c" />
+ <ClCompile Include="..\..\libembroidery\emb-ellipse.c" />
+ <ClCompile Include="..\..\libembroidery\emb-file.c" />
+ <ClCompile Include="..\..\libembroidery\emb-flag.c" />
+ <ClCompile Include="..\..\libembroidery\emb-format.c" />
+ <ClCompile Include="..\..\libembroidery\emb-hash.c" />
+ <ClCompile Include="..\..\libembroidery\emb-line.c" />
+ <ClCompile Include="..\..\libembroidery\emb-logging.c" />
+ <ClCompile Include="..\..\libembroidery\emb-path.c" />
+ <ClCompile Include="..\..\libembroidery\emb-satin-line.c" />
+ <ClCompile Include="..\..\libembroidery\emb-settings.c" />
+ <ClCompile Include="..\..\libembroidery\emb-pattern.c" />
+ <ClCompile Include="..\..\libembroidery\emb-point.c" />
+ <ClCompile Include="..\..\libembroidery\emb-polygon.c" />
+ <ClCompile Include="..\..\libembroidery\emb-polyline.c" />
+ <ClCompile Include="..\..\libembroidery\emb-reader-writer.c" />
+ <ClCompile Include="..\..\libembroidery\emb-rect.c" />
+ <ClCompile Include="..\..\libembroidery\emb-spline.c" />
+ <ClCompile Include="..\..\libembroidery\emb-stitch.c" />
+ <ClCompile Include="..\..\libembroidery\emb-thread.c" />
+ <ClCompile Include="..\..\libembroidery\emb-time.c" />
+ <ClCompile Include="..\..\libembroidery\emb-vector.c" />
+ <ClCompile Include="..\..\libembroidery\format-100.c" />
+ <ClCompile Include="..\..\libembroidery\format-10o.c" />
+ <ClCompile Include="..\..\libembroidery\format-art.c" />
+ <ClCompile Include="..\..\libembroidery\format-bmc.c" />
+ <ClCompile Include="..\..\libembroidery\format-bro.c" />
+ <ClCompile Include="..\..\libembroidery\format-cnd.c" />
+ <ClCompile Include="..\..\libembroidery\format-col.c" />
+ <ClCompile Include="..\..\libembroidery\format-csd.c" />
+ <ClCompile Include="..\..\libembroidery\format-csv.c" />
+ <ClCompile Include="..\..\libembroidery\format-dat.c" />
+ <ClCompile Include="..\..\libembroidery\format-dem.c" />
+ <ClCompile Include="..\..\libembroidery\format-dsb.c" />
+ <ClCompile Include="..\..\libembroidery\format-dst.c" />
+ <ClCompile Include="..\..\libembroidery\format-dsz.c" />
+ <ClCompile Include="..\..\libembroidery\format-dxf.c" />
+ <ClCompile Include="..\..\libembroidery\format-edr.c" />
+ <ClCompile Include="..\..\libembroidery\format-emd.c" />
+ <ClCompile Include="..\..\libembroidery\format-exp.c" />
+ <ClCompile Include="..\..\libembroidery\format-exy.c" />
+ <ClCompile Include="..\..\libembroidery\format-eys.c" />
+ <ClCompile Include="..\..\libembroidery\format-fxy.c" />
+ <ClCompile Include="..\..\libembroidery\format-gc.c" />
+ <ClCompile Include="..\..\libembroidery\format-gnc.c" />
+ <ClCompile Include="..\..\libembroidery\format-gt.c" />
+ <ClCompile Include="..\..\libembroidery\format-hus.c" />
+ <ClCompile Include="..\..\libembroidery\format-inb.c" />
+ <ClCompile Include="..\..\libembroidery\format-inf.c" />
+ <ClCompile Include="..\..\libembroidery\format-jef.c" />
+ <ClCompile Include="..\..\libembroidery\format-ksm.c" />
+ <ClCompile Include="..\..\libembroidery\format-max.c" />
+ <ClCompile Include="..\..\libembroidery\format-mit.c" />
+ <ClCompile Include="..\..\libembroidery\format-new.c" />
+ <ClCompile Include="..\..\libembroidery\format-ofm.c" />
+ <ClCompile Include="..\..\libembroidery\format-pcd.c" />
+ <ClCompile Include="..\..\libembroidery\format-pcm.c" />
+ <ClCompile Include="..\..\libembroidery\format-pcq.c" />
+ <ClCompile Include="..\..\libembroidery\format-pcs.c" />
+ <ClCompile Include="..\..\libembroidery\format-pec.c" />
+ <ClCompile Include="..\..\libembroidery\format-pel.c" />
+ <ClCompile Include="..\..\libembroidery\format-pem.c" />
+ <ClCompile Include="..\..\libembroidery\format-pes.c" />
+ <ClCompile Include="..\..\libembroidery\format-phb.c" />
+ <ClCompile Include="..\..\libembroidery\format-phc.c" />
+ <ClCompile Include="..\..\libembroidery\format-plt.c" />
+ <ClCompile Include="..\..\libembroidery\format-rgb.c" />
+ <ClCompile Include="..\..\libembroidery\format-sew.c" />
+ <ClCompile Include="..\..\libembroidery\format-shv.c" />
+ <ClCompile Include="..\..\libembroidery\format-sst.c" />
+ <ClCompile Include="..\..\libembroidery\format-stx.c" />
+ <ClCompile Include="..\..\libembroidery\format-svg.c" />
+ <ClCompile Include="..\..\libembroidery\format-t01.c" />
+ <ClCompile Include="..\..\libembroidery\format-t09.c" />
+ <ClCompile Include="..\..\libembroidery\format-tap.c" />
+ <ClCompile Include="..\..\libembroidery\format-thr.c" />
+ <ClCompile Include="..\..\libembroidery\format-txt.c" />
+ <ClCompile Include="..\..\libembroidery\format-u00.c" />
+ <ClCompile Include="..\..\libembroidery\format-u01.c" />
+ <ClCompile Include="..\..\libembroidery\format-vip.c" />
+ <ClCompile Include="..\..\libembroidery\format-vp3.c" />
+ <ClCompile Include="..\..\libembroidery\format-xxx.c" />
+ <ClCompile Include="..\..\libembroidery\format-zsk.c" />
+ <ClCompile Include="..\..\libembroidery\geom-arc.c" />
+ <ClCompile Include="..\..\libembroidery\geom-circle.c" />
+ <ClCompile Include="..\..\libembroidery\geom-line.c" />
+ <ClCompile Include="..\..\libembroidery\hashtable.c" />
+ <ClCompile Include="..\..\libembroidery\helpers-binary.c" />
+ <ClCompile Include="..\..\libembroidery\helpers-misc.c" />
+ <ClCompile Include="..\..\libembroidery\thread-color.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\libembroidery\compound-file-common.h" />
+ <ClInclude Include="..\..\libembroidery\compound-file-difat.h" />
+ <ClInclude Include="..\..\libembroidery\compound-file-directory.h" />
+ <ClInclude Include="..\..\libembroidery\compound-file-fat.h" />
+ <ClInclude Include="..\..\libembroidery\compound-file-header.h" />
+ <ClInclude Include="..\..\libembroidery\compound-file.h" />
+ <ClInclude Include="..\..\libembroidery\emb-arc.h" />
+ <ClInclude Include="..\..\libembroidery\emb-circle.h" />
+ <ClInclude Include="..\..\libembroidery\emb-color.h" />
+ <ClInclude Include="..\..\libembroidery\emb-compress.h" />
+ <ClInclude Include="..\..\libembroidery\emb-ellipse.h" />
+ <ClInclude Include="..\..\libembroidery\emb-file.h" />
+ <ClInclude Include="..\..\libembroidery\emb-flag.h" />
+ <ClInclude Include="..\..\libembroidery\emb-format.h" />
+ <ClInclude Include="..\..\libembroidery\emb-hash.h" />
+ <ClInclude Include="..\..\libembroidery\emb-line.h" />
+ <ClInclude Include="..\..\libembroidery\emb-logging.h" />
+ <ClInclude Include="..\..\libembroidery\emb-path.h" />
+ <ClInclude Include="..\..\libembroidery\emb-satin-line.h" />
+ <ClInclude Include="..\..\libembroidery\emb-settings.h" />
+ <ClInclude Include="..\..\libembroidery\emb-pattern.h" />
+ <ClInclude Include="..\..\libembroidery\emb-point.h" />
+ <ClInclude Include="..\..\libembroidery\emb-polygon.h" />
+ <ClInclude Include="..\..\libembroidery\emb-polyline.h" />
+ <ClInclude Include="..\..\libembroidery\emb-reader-writer.h" />
+ <ClInclude Include="..\..\libembroidery\emb-rect.h" />
+ <ClInclude Include="..\..\libembroidery\emb-spline.h" />
+ <ClInclude Include="..\..\libembroidery\emb-stitch.h" />
+ <ClInclude Include="..\..\libembroidery\emb-thread.h" />
+ <ClInclude Include="..\..\libembroidery\emb-time.h" />
+ <ClInclude Include="..\..\libembroidery\emb-vector.h" />
+ <ClInclude Include="..\..\libembroidery\format-100.h" />
+ <ClInclude Include="..\..\libembroidery\format-10o.h" />
+ <ClInclude Include="..\..\libembroidery\format-art.h" />
+ <ClInclude Include="..\..\libembroidery\format-bmc.h" />
+ <ClInclude Include="..\..\libembroidery\format-bro.h" />
+ <ClInclude Include="..\..\libembroidery\format-cnd.h" />
+ <ClInclude Include="..\..\libembroidery\format-col.h" />
+ <ClInclude Include="..\..\libembroidery\format-csd.h" />
+ <ClInclude Include="..\..\libembroidery\format-csv.h" />
+ <ClInclude Include="..\..\libembroidery\format-dat.h" />
+ <ClInclude Include="..\..\libembroidery\format-dem.h" />
+ <ClInclude Include="..\..\libembroidery\format-dsb.h" />
+ <ClInclude Include="..\..\libembroidery\format-dst.h" />
+ <ClInclude Include="..\..\libembroidery\format-dsz.h" />
+ <ClInclude Include="..\..\libembroidery\format-dxf.h" />
+ <ClInclude Include="..\..\libembroidery\format-edr.h" />
+ <ClInclude Include="..\..\libembroidery\format-emd.h" />
+ <ClInclude Include="..\..\libembroidery\format-exp.h" />
+ <ClInclude Include="..\..\libembroidery\format-exy.h" />
+ <ClInclude Include="..\..\libembroidery\format-eys.h" />
+ <ClInclude Include="..\..\libembroidery\format-fxy.h" />
+ <ClInclude Include="..\..\libembroidery\format-gnc.h" />
+ <ClInclude Include="..\..\libembroidery\format-gt.h" />
+ <ClInclude Include="..\..\libembroidery\format-hus.h" />
+ <ClInclude Include="..\..\libembroidery\format-inb.h" />
+ <ClInclude Include="..\..\libembroidery\format-inf.h" />
+ <ClInclude Include="..\..\libembroidery\format-jef.h" />
+ <ClInclude Include="..\..\libembroidery\format-ksm.h" />
+ <ClInclude Include="..\..\libembroidery\format-max.h" />
+ <ClInclude Include="..\..\libembroidery\format-mit.h" />
+ <ClInclude Include="..\..\libembroidery\format-new.h" />
+ <ClInclude Include="..\..\libembroidery\format-ofm.h" />
+ <ClInclude Include="..\..\libembroidery\format-pcd.h" />
+ <ClInclude Include="..\..\libembroidery\format-pcm.h" />
+ <ClInclude Include="..\..\libembroidery\format-pcq.h" />
+ <ClInclude Include="..\..\libembroidery\format-pcs.h" />
+ <ClInclude Include="..\..\libembroidery\format-pec.h" />
+ <ClInclude Include="..\..\libembroidery\format-pel.h" />
+ <ClInclude Include="..\..\libembroidery\format-pem.h" />
+ <ClInclude Include="..\..\libembroidery\format-pes.h" />
+ <ClInclude Include="..\..\libembroidery\format-phb.h" />
+ <ClInclude Include="..\..\libembroidery\format-phc.h" />
+ <ClInclude Include="..\..\libembroidery\format-plt.h" />
+ <ClInclude Include="..\..\libembroidery\format-rgb.h" />
+ <ClInclude Include="..\..\libembroidery\format-sew.h" />
+ <ClInclude Include="..\..\libembroidery\format-shv.h" />
+ <ClInclude Include="..\..\libembroidery\format-sst.h" />
+ <ClInclude Include="..\..\libembroidery\format-stx.h" />
+ <ClInclude Include="..\..\libembroidery\format-svg.h" />
+ <ClInclude Include="..\..\libembroidery\format-t01.h" />
+ <ClInclude Include="..\..\libembroidery\format-t09.h" />
+ <ClInclude Include="..\..\libembroidery\format-tap.h" />
+ <ClInclude Include="..\..\libembroidery\format-thr.h" />
+ <ClInclude Include="..\..\libembroidery\format-txt.h" />
+ <ClInclude Include="..\..\libembroidery\format-u00.h" />
+ <ClInclude Include="..\..\libembroidery\format-u01.h" />
+ <ClInclude Include="..\..\libembroidery\format-vip.h" />
+ <ClInclude Include="..\..\libembroidery\format-vp3.h" />
+ <ClInclude Include="..\..\libembroidery\format-xxx.h" />
+ <ClInclude Include="..\..\libembroidery\format-zsk.h" />
+ <ClInclude Include="..\..\libembroidery\formats.h" />
+ <ClInclude Include="..\..\libembroidery\geom-arc.h" />
+ <ClInclude Include="..\..\libembroidery\geom-circle.h" />
+ <ClInclude Include="..\..\libembroidery\geom-line.h" />
+ <ClInclude Include="..\..\libembroidery\hashtable.h" />
+ <ClInclude Include="..\..\libembroidery\helpers-binary.h" />
+ <ClInclude Include="..\..\libembroidery\helpers-misc.h" />
+ <ClInclude Include="..\..\libembroidery\thread-color.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Software/Visual_Studio/Embroidery/project-files/visualstudio/libembroidery.sln b/Software/Visual_Studio/Embroidery/project-files/visualstudio/libembroidery.sln
new file mode 100644
index 000000000..6daa3175d
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/visualstudio/libembroidery.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libembroidery", "libembroidery.vcxproj", "{6A3DDF09-228A-46EE-8DB1-1DA8760FCB1F}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {6A3DDF09-228A-46EE-8DB1-1DA8760FCB1F}.Debug|Win32.ActiveCfg = Debug|Win32
+ {6A3DDF09-228A-46EE-8DB1-1DA8760FCB1F}.Debug|Win32.Build.0 = Debug|Win32
+ {6A3DDF09-228A-46EE-8DB1-1DA8760FCB1F}.Release|Win32.ActiveCfg = Release|Win32
+ {6A3DDF09-228A-46EE-8DB1-1DA8760FCB1F}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Software/Visual_Studio/Embroidery/project-files/visualstudio/libembroidery.vcxproj b/Software/Visual_Studio/Embroidery/project-files/visualstudio/libembroidery.vcxproj
new file mode 100644
index 000000000..8cd49230a
--- /dev/null
+++ b/Software/Visual_Studio/Embroidery/project-files/visualstudio/libembroidery.vcxproj
@@ -0,0 +1,287 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{6A3DDF09-228A-46EE-8DB1-1DA8760FCB1F}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>libembroidery</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v141</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+ <TargetExt>.dll</TargetExt>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level4</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <BrowseInformation>true</BrowseInformation>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ <Bscmake>
+ <PreserveSbr>true</PreserveSbr>
+ </Bscmake>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\libembroidery\compound-file-difat.c" />
+ <ClCompile Include="..\..\libembroidery\compound-file-directory.c" />
+ <ClCompile Include="..\..\libembroidery\compound-file-fat.c" />
+ <ClCompile Include="..\..\libembroidery\compound-file-header.c" />
+ <ClCompile Include="..\..\libembroidery\compound-file.c" />
+ <ClCompile Include="..\..\libembroidery\emb-arc.c" />
+ <ClCompile Include="..\..\libembroidery\emb-circle.c" />
+ <ClCompile Include="..\..\libembroidery\emb-color.c" />
+ <ClCompile Include="..\..\libembroidery\emb-compress.c" />
+ <ClCompile Include="..\..\libembroidery\emb-ellipse.c" />
+ <ClCompile Include="..\..\libembroidery\emb-file.c" />
+ <ClCompile Include="..\..\libembroidery\emb-flag.c" />
+ <ClCompile Include="..\..\libembroidery\emb-format.c" />
+ <ClCompile Include="..\..\libembroidery\emb-hash.c" />
+ <ClCompile Include="..\..\libembroidery\emb-line.c" />
+ <ClCompile Include="..\..\libembroidery\emb-logging.c" />
+ <ClCompile Include="..\..\libembroidery\emb-path.c" />
+ <ClCompile Include="..\..\libembroidery\emb-satin-line.c" />
+ <ClCompile Include="..\..\libembroidery\emb-settings.c" />
+ <ClCompile Include="..\..\libembroidery\emb-pattern.c" />
+ <ClCompile Include="..\..\libembroidery\emb-point.c" />
+ <ClCompile Include="..\..\libembroidery\emb-polygon.c" />
+ <ClCompile Include="..\..\libembroidery\emb-polyline.c" />
+ <ClCompile Include="..\..\libembroidery\emb-reader-writer.c" />
+ <ClCompile Include="..\..\libembroidery\emb-rect.c" />
+ <ClCompile Include="..\..\libembroidery\emb-spline.c" />
+ <ClCompile Include="..\..\libembroidery\emb-stitch.c" />
+ <ClCompile Include="..\..\libembroidery\emb-thread.c" />
+ <ClCompile Include="..\..\libembroidery\emb-time.c" />
+ <ClCompile Include="..\..\libembroidery\emb-vector.c" />
+ <ClCompile Include="..\..\libembroidery\format-100.c" />
+ <ClCompile Include="..\..\libembroidery\format-10o.c" />
+ <ClCompile Include="..\..\libembroidery\format-art.c" />
+ <ClCompile Include="..\..\libembroidery\format-bmc.c" />
+ <ClCompile Include="..\..\libembroidery\format-bro.c" />
+ <ClCompile Include="..\..\libembroidery\format-cnd.c" />
+ <ClCompile Include="..\..\libembroidery\format-col.c" />
+ <ClCompile Include="..\..\libembroidery\format-csd.c" />
+ <ClCompile Include="..\..\libembroidery\format-csv.c" />
+ <ClCompile Include="..\..\libembroidery\format-dat.c" />
+ <ClCompile Include="..\..\libembroidery\format-dem.c" />
+ <ClCompile Include="..\..\libembroidery\format-dsb.c" />
+ <ClCompile Include="..\..\libembroidery\format-dst.c" />
+ <ClCompile Include="..\..\libembroidery\format-dsz.c" />
+ <ClCompile Include="..\..\libembroidery\format-dxf.c" />
+ <ClCompile Include="..\..\libembroidery\format-edr.c" />
+ <ClCompile Include="..\..\libembroidery\format-emd.c" />
+ <ClCompile Include="..\..\libembroidery\format-exp.c" />
+ <ClCompile Include="..\..\libembroidery\format-exy.c" />
+ <ClCompile Include="..\..\libembroidery\format-eys.c" />
+ <ClCompile Include="..\..\libembroidery\format-fxy.c" />
+ <ClCompile Include="..\..\libembroidery\format-gc.c" />
+ <ClCompile Include="..\..\libembroidery\format-gnc.c" />
+ <ClCompile Include="..\..\libembroidery\format-gt.c" />
+ <ClCompile Include="..\..\libembroidery\format-hus.c" />
+ <ClCompile Include="..\..\libembroidery\format-inb.c" />
+ <ClCompile Include="..\..\libembroidery\format-inf.c" />
+ <ClCompile Include="..\..\libembroidery\format-jef.c" />
+ <ClCompile Include="..\..\libembroidery\format-ksm.c" />
+ <ClCompile Include="..\..\libembroidery\format-max.c" />
+ <ClCompile Include="..\..\libembroidery\format-mit.c" />
+ <ClCompile Include="..\..\libembroidery\format-new.c" />
+ <ClCompile Include="..\..\libembroidery\format-ofm.c" />
+ <ClCompile Include="..\..\libembroidery\format-pcd.c" />
+ <ClCompile Include="..\..\libembroidery\format-pcm.c" />
+ <ClCompile Include="..\..\libembroidery\format-pcq.c" />
+ <ClCompile Include="..\..\libembroidery\format-pcs.c" />
+ <ClCompile Include="..\..\libembroidery\format-pec.c" />
+ <ClCompile Include="..\..\libembroidery\format-pel.c" />
+ <ClCompile Include="..\..\libembroidery\format-pem.c" />
+ <ClCompile Include="..\..\libembroidery\format-pes.c" />
+ <ClCompile Include="..\..\libembroidery\format-phb.c" />
+ <ClCompile Include="..\..\libembroidery\format-phc.c" />
+ <ClCompile Include="..\..\libembroidery\format-plt.c" />
+ <ClCompile Include="..\..\libembroidery\format-rgb.c" />
+ <ClCompile Include="..\..\libembroidery\format-sew.c" />
+ <ClCompile Include="..\..\libembroidery\format-shv.c" />
+ <ClCompile Include="..\..\libembroidery\format-sst.c" />
+ <ClCompile Include="..\..\libembroidery\format-stx.c" />
+ <ClCompile Include="..\..\libembroidery\format-svg.c" />
+ <ClCompile Include="..\..\libembroidery\format-t09.c" />
+ <ClCompile Include="..\..\libembroidery\format-tap.c" />
+ <ClCompile Include="..\..\libembroidery\format-thr.c" />
+ <ClCompile Include="..\..\libembroidery\format-txt.c" />
+ <ClCompile Include="..\..\libembroidery\format-u00.c" />
+ <ClCompile Include="..\..\libembroidery\format-u01.c" />
+ <ClCompile Include="..\..\libembroidery\format-vip.c" />
+ <ClCompile Include="..\..\libembroidery\format-vp3.c" />
+ <ClCompile Include="..\..\libembroidery\format-xxx.c" />
+ <ClCompile Include="..\..\libembroidery\format-zsk.c" />
+ <ClCompile Include="..\..\libembroidery\geom-arc.c" />
+ <ClCompile Include="..\..\libembroidery\geom-circle.c" />
+ <ClCompile Include="..\..\libembroidery\geom-line.c" />
+ <ClCompile Include="..\..\libembroidery\hashtable.c" />
+ <ClCompile Include="..\..\libembroidery\helpers-binary.c" />
+ <ClCompile Include="..\..\libembroidery\helpers-misc.c" />
+ <ClCompile Include="..\..\libembroidery\thread-color.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\libembroidery\compound-file-common.h" />
+ <ClInclude Include="..\..\libembroidery\compound-file-difat.h" />
+ <ClInclude Include="..\..\libembroidery\compound-file-directory.h" />
+ <ClInclude Include="..\..\libembroidery\compound-file-fat.h" />
+ <ClInclude Include="..\..\libembroidery\compound-file-header.h" />
+ <ClInclude Include="..\..\libembroidery\compound-file.h" />
+ <ClInclude Include="..\..\libembroidery\emb-arc.h" />
+ <ClInclude Include="..\..\libembroidery\emb-circle.h" />
+ <ClInclude Include="..\..\libembroidery\emb-color.h" />
+ <ClInclude Include="..\..\libembroidery\emb-compress.h" />
+ <ClInclude Include="..\..\libembroidery\emb-ellipse.h" />
+ <ClInclude Include="..\..\libembroidery\emb-file.h" />
+ <ClInclude Include="..\..\libembroidery\emb-flag.h" />
+ <ClInclude Include="..\..\libembroidery\emb-format.h" />
+ <ClInclude Include="..\..\libembroidery\emb-hash.h" />
+ <ClInclude Include="..\..\libembroidery\emb-line.h" />
+ <ClInclude Include="..\..\libembroidery\emb-logging.h" />
+ <ClInclude Include="..\..\libembroidery\emb-path.h" />
+ <ClInclude Include="..\..\libembroidery\emb-satin-line.h" />
+ <ClInclude Include="..\..\libembroidery\emb-settings.h" />
+ <ClInclude Include="..\..\libembroidery\emb-pattern.h" />
+ <ClInclude Include="..\..\libembroidery\emb-point.h" />
+ <ClInclude Include="..\..\libembroidery\emb-polygon.h" />
+ <ClInclude Include="..\..\libembroidery\emb-polyline.h" />
+ <ClInclude Include="..\..\libembroidery\emb-reader-writer.h" />
+ <ClInclude Include="..\..\libembroidery\emb-rect.h" />
+ <ClInclude Include="..\..\libembroidery\emb-spline.h" />
+ <ClInclude Include="..\..\libembroidery\emb-stitch.h" />
+ <ClInclude Include="..\..\libembroidery\emb-thread.h" />
+ <ClInclude Include="..\..\libembroidery\emb-time.h" />
+ <ClInclude Include="..\..\libembroidery\emb-vector.h" />
+ <ClInclude Include="..\..\libembroidery\format-100.h" />
+ <ClInclude Include="..\..\libembroidery\format-10o.h" />
+ <ClInclude Include="..\..\libembroidery\format-art.h" />
+ <ClInclude Include="..\..\libembroidery\format-bmc.h" />
+ <ClInclude Include="..\..\libembroidery\format-bro.h" />
+ <ClInclude Include="..\..\libembroidery\format-cnd.h" />
+ <ClInclude Include="..\..\libembroidery\format-col.h" />
+ <ClInclude Include="..\..\libembroidery\format-csd.h" />
+ <ClInclude Include="..\..\libembroidery\format-csv.h" />
+ <ClInclude Include="..\..\libembroidery\format-dat.h" />
+ <ClInclude Include="..\..\libembroidery\format-dem.h" />
+ <ClInclude Include="..\..\libembroidery\format-dsb.h" />
+ <ClInclude Include="..\..\libembroidery\format-dst.h" />
+ <ClInclude Include="..\..\libembroidery\format-dsz.h" />
+ <ClInclude Include="..\..\libembroidery\format-dxf.h" />
+ <ClInclude Include="..\..\libembroidery\format-edr.h" />
+ <ClInclude Include="..\..\libembroidery\format-emd.h" />
+ <ClInclude Include="..\..\libembroidery\format-exp.h" />
+ <ClInclude Include="..\..\libembroidery\format-exy.h" />
+ <ClInclude Include="..\..\libembroidery\format-eys.h" />
+ <ClInclude Include="..\..\libembroidery\format-fxy.h" />
+ <ClInclude Include="..\..\libembroidery\format-gnc.h" />
+ <ClInclude Include="..\..\libembroidery\format-gt.h" />
+ <ClInclude Include="..\..\libembroidery\format-hus.h" />
+ <ClInclude Include="..\..\libembroidery\format-inb.h" />
+ <ClInclude Include="..\..\libembroidery\format-inf.h" />
+ <ClInclude Include="..\..\libembroidery\format-jef.h" />
+ <ClInclude Include="..\..\libembroidery\format-ksm.h" />
+ <ClInclude Include="..\..\libembroidery\format-max.h" />
+ <ClInclude Include="..\..\libembroidery\format-mit.h" />
+ <ClInclude Include="..\..\libembroidery\format-new.h" />
+ <ClInclude Include="..\..\libembroidery\format-ofm.h" />
+ <ClInclude Include="..\..\libembroidery\format-pcd.h" />
+ <ClInclude Include="..\..\libembroidery\format-pcm.h" />
+ <ClInclude Include="..\..\libembroidery\format-pcq.h" />
+ <ClInclude Include="..\..\libembroidery\format-pcs.h" />
+ <ClInclude Include="..\..\libembroidery\format-pec.h" />
+ <ClInclude Include="..\..\libembroidery\format-pel.h" />
+ <ClInclude Include="..\..\libembroidery\format-pem.h" />
+ <ClInclude Include="..\..\libembroidery\format-pes.h" />
+ <ClInclude Include="..\..\libembroidery\format-phb.h" />
+ <ClInclude Include="..\..\libembroidery\format-phc.h" />
+ <ClInclude Include="..\..\libembroidery\format-plt.h" />
+ <ClInclude Include="..\..\libembroidery\format-rgb.h" />
+ <ClInclude Include="..\..\libembroidery\format-sew.h" />
+ <ClInclude Include="..\..\libembroidery\format-shv.h" />
+ <ClInclude Include="..\..\libembroidery\format-sst.h" />
+ <ClInclude Include="..\..\libembroidery\format-stx.h" />
+ <ClInclude Include="..\..\libembroidery\format-svg.h" />
+ <ClInclude Include="..\..\libembroidery\format-t09.h" />
+ <ClInclude Include="..\..\libembroidery\format-tap.h" />
+ <ClInclude Include="..\..\libembroidery\format-thr.h" />
+ <ClInclude Include="..\..\libembroidery\format-txt.h" />
+ <ClInclude Include="..\..\libembroidery\format-u00.h" />
+ <ClInclude Include="..\..\libembroidery\format-u01.h" />
+ <ClInclude Include="..\..\libembroidery\format-vip.h" />
+ <ClInclude Include="..\..\libembroidery\format-vp3.h" />
+ <ClInclude Include="..\..\libembroidery\format-xxx.h" />
+ <ClInclude Include="..\..\libembroidery\format-zsk.h" />
+ <ClInclude Include="..\..\libembroidery\formats.h" />
+ <ClInclude Include="..\..\libembroidery\geom-arc.h" />
+ <ClInclude Include="..\..\libembroidery\geom-circle.h" />
+ <ClInclude Include="..\..\libembroidery\geom-line.h" />
+ <ClInclude Include="..\..\libembroidery\hashtable.h" />
+ <ClInclude Include="..\..\libembroidery\helpers-binary.h" />
+ <ClInclude Include="..\..\libembroidery\helpers-misc.h" />
+ <ClInclude Include="..\..\libembroidery\thread-color.h" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file