Coder Social home page Coder Social logo

fontforge / libspiro Goto Github PK

View Code? Open in Web Editor NEW
103.0 103.0 25.0 1 MB

Spiro is the creation of Raph Levien. It simplifies the drawing of beautiful curves. (Migrated here from libspiro.sourceforge.net on 2013-04-20)

License: GNU General Public License v3.0

C 71.56% Java 16.09% Makefile 2.36% M4 8.60% Roff 1.39%

libspiro's Introduction

FontForge CI Build status Coverity Scan Build Status

FontForge Logo

FontForge is a free (libre) font editor for Windows, Mac OS X and GNU+Linux. Use it to create, edit and convert fonts in OpenType, TrueType, UFO, CID-keyed, Multiple Master, and many other formats.

fontforge.org — homepage

designwithfontforge.com — font creation manual

Getting help

The bug tracker is for reporting bugs, not for asking questions. Please direct questions to one of the following:

Installation & contributing

INSTALL.md — developer instructions to build from source

setup_linux_deps.sh — a list of installation dependencies

CONTRIBUTING.md — contributing guidelines

libspiro's People

Contributors

artoria2e5 avatar davelab6 avatar jamadagni avatar joescat avatar jtanx avatar orbea avatar wieslawsoltes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libspiro's Issues

Segmentation fault in call-test20

Hi,

The issue can be reproduced out of the box when building and running the test suite on OpenBSD and FreeBSD.

It can be reproduced on Linux with GCC by enabling the Stack Smashing Protector (SSP):

./configure CFLAGS=-fstack-protector
make
tests/call-test20

Can't compile on xubuntu-12.04 32-bit

Trying to compile libspiro on a 32-bit xubuntu-12.04 I perform the following steps:
$autoreconf
$automake [have tried with and without --foreign -Wall]
$./configure

then make fails at CCLD call-test:

$make
make all-recursive
make[1]: Entering directory /home/slarty/CODE/source/fontforge/git_fontforge/libspiro' Making all in . make[2]: Entering directory/home/slarty/CODE/source/fontforge/git_fontforge/libspiro'
CC spiro.lo
CC bezctx.lo
CC spiroentrypoints.lo
CCLD libspiro.la
make[2]: Leaving directory /home/slarty/CODE/source/fontforge/git_fontforge/libspiro' Making all in tests make[2]: Entering directory/home/slarty/CODE/source/fontforge/git_fontforge/libspiro/tests'
CC unit-test.o
CCLD unit-test
CC call-test.o
CCLD call-test
../.libs/libspiro.so: undefined reference to sincos' ../.libs/libspiro.so: undefined reference toatan2'
../.libs/libspiro.so: undefined reference to hypot' collect2: ld returned 1 exit status make[2]: *** [call-test] Error 1 make[2]: Leaving directory/home/slarty/CODE/source/fontforge/git_fontforge/libspiro/tests'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/slarty/CODE/source/fontforge/git_fontforge/libspiro'
make: *** [all] Error 2


I assume there is a missing -lm somewhere but have not successfully found a solution.
I have however successfully compiled and installed libspiro from here:
http://libspiro.sourceforge.net

Have ported to Haxe

Hi just letting you know I have ported the code to Haxe so it should now be very cross platform ( haxe supports php7, c++, hashlink ( c and c vm ), neko vm, javascript, flash, c#, java, python, lua ).
https://lib.haxe.org/p/hxSpiro/0.0.1
The demo is still rather rough uses svg javascript but allows you to place points or move them, it should be fairly easy to rebuild for cross target Haxe libraries like NME/Openfl etc..
Feedback welcome, I need to check if enabling some of the commented out inlines would speed up further, but the js test seems fairly responsive. Let me know if a pull request might be suitable and what form it might take, but seems fine for it to be separate, but thought it might interest you.

Cannot compile using parallel make

There are issues when compiling with parallel make (e.g make -j4)

Without this option, it compiles fine.

make  all-recursive
make[1]: Entering directory '/home/jeremy/ff-build/work/libspiro'
Making all in .
make[2]: Entering directory '/home/jeremy/ff-build/work/libspiro'
  CC       bezctx.lo
  CC       spiro.lo
  CC       spiroentrypoints.lo
  CCLD     libspiro.la
make[2]: Leaving directory '/home/jeremy/ff-build/work/libspiro'
Making all in tests
make[2]: Entering directory '/home/jeremy/ff-build/work/libspiro/tests'
  CC       call-test.o
  CC       unit-test.o
  CCLD     call-test.exe
  CCLD     unit-test.exe
i686-w64-mingw32-gcc.exe: error: unrecognized command line option '--mode=link'
Makefile:553: recipe for target 'unit-test.exe' failed
make[2]: *** [unit-test.exe] Error 1
make[2]: *** Waiting for unfinished jobs....
i686-w64-mingw32-gcc.exe: error: unrecognized command line option '--mode=link'
Makefile:549: recipe for target 'call-test.exe' failed
make[2]: *** [call-test.exe] Error 1
make[2]: Leaving directory '/home/jeremy/ff-build/work/libspiro/tests'
Makefile:565: recipe for target 'all-recursive' failed
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory '/home/jeremy/ff-build/work/libspiro'
Makefile:403: recipe for target 'all' failed
make: *** [all] Error 2

Can't compile for x86_64

Git master head won't compile for me:

dcrossland-macbookpro4:libspiro dcrossland$ autoreconf -i
glibtoolize: putting auxiliary files in `.'.
glibtoolize: copying file `./ltmain.sh'
glibtoolize: putting macros in AC_CONFIG_MACRO_DIR, `m4'.
glibtoolize: copying file `m4/libtool.m4'
glibtoolize: copying file `m4/ltoptions.m4'
glibtoolize: copying file `m4/ltsugar.m4'
glibtoolize: copying file `m4/ltversion.m4'
glibtoolize: copying file `m4/lt~obsolete.m4'
configure.ac:35: warning: AM_INIT_AUTOMAKE: two- and three-arguments forms are deprecated.  For more info, see:
configure.ac:35: http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_005fINIT_005fAUTOMAKE-invocation
configure.ac:38: installing './compile'
configure.ac:35: installing './install-sh'
configure.ac:35: installing './missing'
Makefile.am: installing './depcomp'
parallel-tests: installing './test-driver'
dcrossland-macbookpro4:libspiro dcrossland$ automake --foreign -Wall
configure.ac:35: warning: AM_INIT_AUTOMAKE: two- and three-arguments forms are deprecated.  For more info, see:
configure.ac:35: http://www.gnu.org/software/automake/manual/automake.html#Modernize-AM_005fINIT_005fAUTOMAKE-invocation
/usr/local/Cellar/automake/1.14/share/automake-1.14/am/ltlibrary.am: warning: 'libspiro.la': linking libtool libraries using a non-POSIX
/usr/local/Cellar/automake/1.14/share/automake-1.14/am/ltlibrary.am: archiver requires 'AM_PROG_AR' in 'configure.ac'
Makefile.am:13:   while processing Libtool library 'libspiro.la'
dcrossland-macbookpro4:libspiro dcrossland$ ./configure 
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... ./install-sh -c -d
checking for gawk... no
checking for mawk... no
checking for nawk... no
checking for awk... awk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking build system type... x86_64-apple-darwin12.4.0
checking host system type... x86_64-apple-darwin12.4.0
checking how to print strings... printf
checking for style of include used by make... GNU
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking whether gcc understands -c and -o together... yes
checking dependency style of gcc... gcc3
checking for a sed that does not truncate output... /usr/bin/sed
checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
checking for fgrep... /usr/bin/grep -F
checking for ld used by gcc... /usr/llvm-gcc-4.2/libexec/gcc/i686-apple-darwin11/4.2.1/ld
checking if the linker (/usr/llvm-gcc-4.2/libexec/gcc/i686-apple-darwin11/4.2.1/ld) is GNU ld... no
checking for BSD- or MS-compatible name lister (nm)... /usr/bin/nm
checking the name lister (/usr/bin/nm) interface... BSD nm
checking whether ln -s works... yes
checking the maximum length of command line arguments... 196608
checking whether the shell understands some XSI constructs... yes
checking whether the shell understands "+="... yes
checking how to convert x86_64-apple-darwin12.4.0 file names to x86_64-apple-darwin12.4.0 format... func_convert_file_noop
checking how to convert x86_64-apple-darwin12.4.0 file names to toolchain format... func_convert_file_noop
checking for /usr/llvm-gcc-4.2/libexec/gcc/i686-apple-darwin11/4.2.1/ld option to reload object files... -r
checking for objdump... no
checking how to recognize dependent libraries... pass_all
checking for dlltool... no
checking how to associate runtime and link libraries... printf %s\n
checking for ar... ar
checking for archiver @FILE support... no
checking for strip... strip
checking for ranlib... ranlib
checking command to parse /usr/bin/nm output from gcc object... ok
checking for sysroot... no
checking for mt... no
checking if : is a manifest tool... no
checking for dsymutil... dsymutil
checking for nmedit... nmedit
checking for lipo... lipo
checking for otool... otool
checking for otool64... no
checking for -single_module linker flag... yes
checking for -exported_symbols_list linker flag... yes
checking for -force_load linker flag... yes
checking how to run the C preprocessor... gcc -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking for dlfcn.h... yes
checking for objdir... .libs
checking if gcc supports -fno-rtti -fno-exceptions... no
checking for gcc option to produce PIC... -fno-common -DPIC
checking if gcc PIC flag -fno-common -DPIC works... yes
checking if gcc static flag -static works... no
checking if gcc supports -c -o file.o... yes
checking if gcc supports -c -o file.o... (cached) yes
checking whether the gcc linker (/usr/llvm-gcc-4.2/libexec/gcc/i686-apple-darwin11/4.2.1/ld) supports shared libraries... yes
checking dynamic linker characteristics... darwin12.4.0 dyld
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... yes
checking for gcc... (cached) gcc
checking whether we are using the GNU C compiler... (cached) yes
checking whether gcc accepts -g... (cached) yes
checking for gcc option to accept ISO C89... (cached) none needed
checking whether gcc understands -c and -o together... (cached) yes
checking dependency style of gcc... (cached) gcc3
checking whether ln -s works... yes
checking whether make sets $(MAKE)... (cached) yes
checking for a sed that does not truncate output... (cached) /usr/bin/sed
checking for wget... /usr/local/bin/wget
checking whether make supports nested variables... (cached) yes
checking for finite... yes
checking pthread.h usability... yes
checking pthread.h presence... yes
checking for pthread.h... yes
checking whether C compiler accepts -Wall... yes
checking whether C compiler accepts -Wextra... yes
checking whether C compiler accepts -Wcast-align... yes
checking whether C compiler accepts -Wbad-function-cast... yes
checking whether C compiler accepts -Wc++-compat... yes
checking whether C compiler accepts -Wmissing-prototypes... yes
checking whether C compiler accepts -Wunused... yes
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating tests/Makefile
config.status: creating libspiro.pc
config.status: creating spiro-config.h
config.status: executing depfiles commands
config.status: executing libtool commands
dcrossland-macbookpro4:libspiro dcrossland$ make
make  all-recursive
Making all in .
  CC       spiro.lo
spiro.c: In function 'check_finiteness':
spiro.c:820: warning: implicit declaration of function '__finite'
  CC       bezctx.lo
  CC       spiroentrypoints.lo
  CCLD     libspiro.la
Undefined symbols for architecture x86_64:
  "___finite", referenced from:
      _run_spiro in spiro.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make[2]: *** [libspiro.la] Error 1
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2

Rust port

Hello Joe:

As part of my new font editor project (currently only a glyph editor 😉), I created a Spiro binding in Rust.

https://github.com/mfeq/spiro-sys

I'll also be making what Rust users call a "safe" version; basically, this is a version which wraps the memory-unsafe functions of libspiro to provide a (more) memory-safe API.

I noticed while doing this that the README's drawing of path 5 seems wrong. I got this instead:

Could very well be my fault, but wanted to ask you.

The code that generates that is here:

https://github.com/mfeq/spiro-sys/blob/22b9e1e9e85f4471910876cf4232edec4dbd8441/tests/spiro_to_beziers.rs#L27-L57

Stack-based buffer overflow in the spiro_to_bpath0() function

Hi,

When building libspiro 20190731 with AddressSanitizer enabled and running the test suite, I found a stack-based buffer overflow in spiro_to_bpath0() in spiro.c.

In the test suite, call-test14 to call-test19 all trigger the same issue.

The issue can be triggered as follow:

./configure CFLAGS="-fsanitize=address"
make
./tests/call-test14
=================================================================
==1829==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffcf5a2c938 at pc 0x7fdc1174d487 bp 0x7ffcf5a2c450 sp 0x7ffcf5a2c448
WRITE of size 8 at 0x7ffcf5a2c938 thread T0
    #0 0x7fdc1174d486 in spiro_to_bpath0 /home/fcambus/libspiro-20190731/spiro.c:1182:11
    #1 0x4c9ea0 in test_curve /home/fcambus/libspiro-20190731/tests/./call-test.c:666:5
    #2 0x4ca119 in main /home/fcambus/libspiro-20190731/tests/./call-test.c:1172:9
    #3 0x7fdc1152e1e2 in __libc_start_main /build/glibc-4WA41p/glibc-2.30/csu/../csu/libc-start.c:308:16
    #4 0x41b31d in _start (/home/fcambus/libspiro-20190731/tests/.libs/call-test14+0x41b31d)

Address 0x7ffcf5a2c938 is located in stack of thread T0 at offset 632 in frame
    #0 0x4c832f in test_curve /home/fcambus/libspiro-20190731/tests/./call-test.c:536

  This frame has 3 object(s):
    [32, 416) 'spiro' (line 537)
    [480, 548) 'nextknot' (line 538)
    [592, 632) 'd' (line 539) <== Memory access at offset 632 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /home/fcambus/libspiro-20190731/spiro.c:1182:11 in spiro_to_bpath0
Shadow bytes around the buggy address:
  0x10001eb3d8d0: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00 00
  0x10001eb3d8e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10001eb3d8f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10001eb3d900: 00 00 00 00 00 00 00 00 00 00 00 00 f2 f2 f2 f2
  0x10001eb3d910: f2 f2 f2 f2 00 00 00 00 00 00 00 00 04 f2 f2 f2
=>0x10001eb3d920: f2 f2 00 00 00 00 00[f3]f3 f3 f3 f3 00 00 00 00
  0x10001eb3d930: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10001eb3d940: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10001eb3d950: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10001eb3d960: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10001eb3d970: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==1829==ABORTING

Crash in git master

:)

$ ./fontforge.sh 
Script started, output file is /Users/dcrossland/FontForge-Debug-Output.txt
(lldb) Executing commands in 'debug-script.sh'.
(lldb)  #!/bin/sh
(lldb)  version
LLDB-179.5
(lldb)  settings set frame-format "frame #${frame.index}: ${frame.pc}{ ${module.file.basename}`${function.name-with-args}{${function.pc-offset}}}{ at ${line.file.basename}:${line.number}}\n"
(lldb)  target create /usr/local/bin/fontforge
Current executable set to '/usr/local/bin/fontforge' (x86_64).
(lldb)  target select 0
Current targets:
* target #0: /usr/local/bin/fontforge ( arch=x86_64-apple-macosx, platform=localhost )
(lldb)  run
Process 18877 launched: '/usr/local/bin/fontforge' (x86_64)
Command #6 'run' continued the target.
Copyright (c) 2000-2012 by George Williams.
 Executable based on sources from 14:57 GMT 31-Jul-2012-D.
 Library based on sources from 14:57 GMT 31-Jul-2012.
Recovering from /Users/dcrossland/.FontForge/autosave/auto003ec1-1.asfd...  Done
Recovering from /Users/dcrossland/.FontForge/autosave/auto0048b8-1.asfd...  Done
Recovering from /Users/dcrossland/.FontForge/autosave/auto0048cc-1.asfd...  Done
Recovering from /Users/dcrossland/.FontForge/autosave/auto0048d5-1.asfd...  Done
Process 18877 stopped
* thread #1: tid = 0x1c03, 0x00000001003a82df libfontforge.1.dylib`SpiroCP2SplineSet + 316, stop reason = EXC_BAD_ACCESS (code=1, address=0x18)
    "frame #0: 0x00000001003a82df libfontforge.1.dylib`SpiroCP2SplineSet + 316
"libfontforge.1.dylib`SpiroCP2SplineSet + 316:
-> 0x1003a82df:  movq   %r14, 24(%r15)
   0x1003a82e3:  incl   %ebx
   0x1003a82e5:  movw   %bx, 34(%r15)
   0x1003a82ea:  movw   %bx, 32(%r15)
(lldb) bt
* thread #1: tid = 0x1c03, 0x00000001003a82df libfontforge.1.dylib`SpiroCP2SplineSet + 316, stop reason = EXC_BAD_ACCESS (code=1, address=0x18)
    "frame #0: 0x00000001003a82df libfontforge.1.dylib`SpiroCP2SplineSet + 316
"    "frame #1: 0x00000001003a8678 libfontforge.1.dylib`SSRegenerateFromSpiros + 46
"    "frame #2: 0x000000010004de6c fontforge`CVMouseMoveSpiroPoint + 332
"    "frame #3: 0x0000000100034562 fontforge`CVMouseMove + 2278
"    "frame #4: 0x000000010003050c fontforge`v_e_h + 234
"    "frame #5: 0x00000001005b70f5 libgdraw.4.dylib`_GWidget_Container_eh + 1541
"    "frame #6: 0x000000010060328c libgdraw.4.dylib`dispatchEvent + 5518
"    "frame #7: 0x0000000100600c86 libgdraw.4.dylib`GXDrawEventLoop + 65
"    "frame #8: 0x0000000100126868 fontforge`main + 5982
"    "frame #9: 0x00007fff839227e1 libdyld.dylib`start + 1
"(lldb) q

'finite' is deprecated

When compiling on OS X, it reports a deprecation warning:

../spiro.c:896:11: warning: 'finite' is deprecated: first deprecated in macOS 10.9 - Use `isfinite((double)x)` instead.
      [-Wdeprecated-declarations]
            if ( IS_FINITE( segs[i].ks[j])==0 ) return -1;

The comment for finite says what should be done:

Legacy BSD API; use the C99 isfinite( ) macro instead.

Looks like the HAVE_FINITE macro detection needs to be tweaked for OS X.

Update license headers

According to COPYING, libspiro is released under the term of GPLv3+, but in the license headers on top of *.c, *.java and bezctx.md are still saying GPLv2+.

It seems necessary to update license headers too.

Output Bézier splines not deterministic enough

Hello @JoesCat, good day.

A problem I've been thinking about for a while is how we can increase the determinism† of the output Béziers from libspiro, at the cost of increased path complexity, and, perhaps, even some mathematical accuracy.

This would make it much easier for Spiro splines to be used in variable fonts, or in other cases where we'd want interpolation. Right now, Spiro users such as me usually have to redraw one or both splines to create an interpolation-compatible spline.

It's clearly quite the challenge. Before I give you my thoughts, what are yours?

† The type of determinism I'm specifically referring to is determinism in the number of points. So, for two Spiro splines with n points, assuming all point types are equal, and both splines have the same openness/closedness, we always get back a Bézier spline with N points, no matter the configuration of the Spiro points.

mipsel build issues

Hi,

there are some issues in the mipsel build at Debian.
Build log: https://buildd.debian.org/status/fetch.php?pkg=libspiro&arch=mipsel&ver=1%3A0.3.20150131-2&stamp=1430325106

The test-suite.log file:

==============================================
   spiro 0.3.20150131: tests/test-suite.log
==============================================

# TOTAL: 2
# PASS:  1
# SKIP:  0
# XFAIL: 0
# FAIL:  1
# XPASS: 0
# ERROR: 0

.. contents:: :depth: 2

FAIL: call-test
===============

testing run_spiro() using data=path0[].
curve 0, line 0, x=334.000000 y=117.000000 t=v bend=0.000000 ch=65.741920 th=2.027641 l=0.000000 
curve 0, line 1, x=305.000000 y=176.000000 t=v bend=0.000000 ch=99.020200 th=-2.791096 l=0.000000 
curve 0, line 2, x=212.000000 y=142.000000 t=c bend=-0.851164 ch=60.415230 th=2.640925 l=0.000000 
curve 0, line 3, x=159.000000 y=171.000000 t=c bend=-1.847893 ch=92.633687 th=0.793032 l=0.000000 
curve 0, line 4, x=224.000000 y=237.000000 t=c bend=-0.120277 ch=157.267288 th=0.672755 l=0.000000 
curve 0, line 5, x=347.000000 y=335.000000 t=c bend=1.730337 ch=196.084166 th=2.403091 l=0.000000 
curve 0, line 6, x=202.000000 y=467.000000 t=c bend=1.042797 ch=126.826653 th=-2.837297 l=0.000000 
curve 0, line 7, x=81.000000 y=429.000000 t=v bend=0.000000 ch=69.354164 th=-1.074902 l=0.000000 
curve 0, line 8, x=114.000000 y=368.000000 t=v bend=0.000000 ch=93.407708 th=0.372554 l=0.000000 
curve 0, line 9, x=201.000000 y=402.000000 t=c bend=-0.787061 ch=81.939002 th=-0.414507 l=0.000000 
curve 0, line 10, x=276.000000 y=369.000000 t=c bend=-1.916483 ch=84.172442 th=-2.330990 l=0.000000 
curve 0, line 11, x=218.000000 y=308.000000 t=c bend=-0.158341 ch=159.806133 th=-2.489331 l=0.000000 
curve 0, line 12, x=91.000000 y=211.000000 t=c bend=1.237282 ch=105.304321 th=-1.252049 l=0.000000 
curve 0, line 13, x=124.000000 y=111.000000 t=c bend=0.982576 ch=108.931171 th=-0.269473 l=0.000000 
curve 0, line 14, x=229.000000 y=82.000000 t=c bend=-2.528266 ch=243.238566 th=-2.797739 l=0.000000 
curve 0, line 15, x=0.000000 y=0.000000 t=z bend=3.134681 ch=353.899703 th=0.336942 l=0.000000 
testing spiro_to_bpath() using data from run_spiro(data=path0[],len=16).
test_moveto(334,117)_0
test_mark_knot()_0
test_lineto(305,176)
test_mark_knot()_1
test_curveto(278.711,155.106, 245.566,142.988, 212,142)
test_mark_knot()_2
test_curveto(201.253,142.281, 190.34,143.726, 180.596,148.267)
test_curveto(175.724,150.538, 171.185,153.578, 167.419,157.413)
test_curveto(163.652,161.248, 160.67,165.891, 159,171)
test_mark_knot()_3
test_curveto(156.308,179.236, 157.16,188.418, 160.551,196.391)
test_curveto(163.942,204.365, 169.745,211.173, 176.569,216.513)
test_curveto(190.217,227.191, 207.414,231.978, 224,237)
test_mark_knot()_4
test_curveto(250.342,244.977, 276.682,254.316, 299.357,269.917)
test_curveto(322.032,285.518, 340.938,308.152, 347,335)
test_mark_knot()_5
test_curveto(351.153,353.392, 349.045,373.004, 341.926,390.463)
test_curveto(334.806,407.923, 322.8,423.235, 308.112,435.059)
test_curveto(278.737,458.706, 239.7,467.886, 202,467)
test_mark_knot()_6
test_curveto(159.176,465.994, 116.711,452.658, 81,429)
test_mark_knot()_7
test_lineto(114,368)
test_mark_knot()_8
test_curveto(140.313,385.041, 170.105,396.684, 201,402)
test_mark_knot()_9
test_curveto(216.033,404.587, 231.809,405.634, 246.268,400.776)
test_curveto(253.497,398.347, 260.287,394.428, 265.629,388.985)
test_curveto(270.971,383.541, 274.812,376.534, 276,369)
test_mark_knot()_10
test_curveto(277.186,361.482, 275.702,353.665, 272.413,346.801)
test_curveto(269.124,339.938, 264.092,333.997, 258.267,329.099)
test_curveto(246.617,319.303, 232.105,313.721, 218,308)
test_mark_knot()_11
test_curveto(192.746,297.756, 167.726,286.443, 145.32,270.931)
test_curveto(122.913,255.419, 103.089,235.424, 91,211)
test_mark_knot()_12
test_curveto(81.9232,192.662, 77.4184,171.323, 82.5427,151.513)
test_curveto(85.1048,141.608, 90.0758,132.265, 97.2634,124.984)
test_curveto(104.451,117.703, 113.889,112.559, 124,111)
test_mark_knot()_13
test_curveto(137.228,108.96, 150.603,112.998, 163.11,117.762)
test_curveto(175.618,122.526, 188.071,128.128, 201.395,129.403)
test_curveto(208.057,130.041, 214.889,129.554, 221.213,127.364)
test_curveto(227.537,125.174, 233.332,121.213, 237.179,115.737)
test_curveto(241.025,110.261, 242.792,103.23, 241.403,96.6836)
test_curveto(240.708,93.4104, 239.243,90.2939, 237.104,87.7207)
test_curveto(234.965,85.1475, 232.15,83.128, 229,82)
test_mark_knot()_14
test_lineto(0,0)
test_mark_knot()_15
test_lineto(334,117)

---
testing TaggedSpiroCPsToBezier0() using data=path0[].
test_moveto(334,117)_0
test_mark_knot()_0
test_lineto(305,176)
test_mark_knot()_1
test_curveto(279.449,153.974, 245.733,141.648, 212,142)
test_mark_knot()_2
test_curveto(201.226,142.112, 190.267,143.529, 180.511,148.103)
test_curveto(175.633,150.39, 171.099,153.461, 167.348,157.327)
test_curveto(163.596,161.194, 160.641,165.869, 159,171)
test_mark_knot()_3
test_curveto(156.364,179.243, 157.251,188.403, 160.654,196.36)
test_curveto(164.057,204.316, 169.853,211.112, 176.664,216.45)
test_curveto(190.287,227.126, 207.444,231.953, 224,237)
test_mark_knot()_4
test_curveto(250.322,245.025, 276.649,254.369, 299.324,269.96)
test_curveto(321.998,285.551, 340.921,308.162, 347,335)
test_mark_knot()_5
test_curveto(351.166,353.392, 349.066,373.009, 341.95,390.473)
test_curveto(334.833,407.936, 322.824,423.251, 308.134,435.075)
test_curveto(278.752,458.724, 239.706,467.893, 202,467)
test_mark_knot()_6
test_curveto(159.176,465.986, 116.715,452.651, 81,429)
test_mark_knot()_7
test_lineto(114,368)
test_mark_knot()_8
test_curveto(140.251,385.152, 170.075,396.808, 201,402)
test_mark_knot()_9
test_curveto(216.006,404.519, 231.742,405.476, 246.158,400.607)
test_curveto(253.366,398.172, 260.137,394.269, 265.488,388.861)
test_curveto(270.839,383.452, 274.72,376.5, 276,369)
test_mark_knot()_10
test_curveto(277.287,361.46, 275.914,353.582, 272.701,346.641)
test_curveto(269.488,339.699, 264.498,333.665, 258.672,328.709)
test_curveto(247.02,318.796, 232.367,313.255, 218,308)
test_mark_knot()_11
test_curveto(191.978,298.481, 165.57,289.162, 142.279,274.152)
test_curveto(118.988,259.143, 98.7273,237.609, 91,211)
test_mark_knot()_12
test_curveto(85.821,193.166, 86.5807,173.749, 92.5866,156.176)
test_curveto(98.5925,138.603, 109.749,122.908, 124,111)
test_mark_knot()_13
test_curveto(138.28,99.0677, 155.539,90.9339, 173.578,86.3634)
test_curveto(191.617,81.7928, 210.435,80.7131, 229,82)
test_mark_knot()_14
test_curveto(266.199,84.5786, 302.694,96.7435, 334,117)

---
testing SpiroCPsToBezier0() using data=path0[].
test_moveto(334,117)_0
test_mark_knot()_0
test_lineto(305,176)
test_mark_knot()_1
test_curveto(278.711,155.106, 245.566,142.988, 212,142)
test_mark_knot()_2
test_curveto(201.253,142.281, 190.34,143.726, 180.596,148.267)
test_curveto(175.724,150.538, 171.185,153.578, 167.419,157.413)
test_curveto(163.652,161.248, 160.67,165.891, 159,171)
test_mark_knot()_3
test_curveto(156.308,179.236, 157.16,188.418, 160.551,196.391)
test_curveto(163.942,204.365, 169.745,211.173, 176.569,216.513)
test_curveto(190.217,227.191, 207.414,231.978, 224,237)
test_mark_knot()_4
test_curveto(250.342,244.977, 276.682,254.316, 299.357,269.917)
test_curveto(322.032,285.518, 340.938,308.152, 347,335)
test_mark_knot()_5
test_curveto(351.153,353.392, 349.045,373.004, 341.926,390.463)
test_curveto(334.806,407.923, 322.8,423.235, 308.112,435.059)
test_curveto(278.737,458.706, 239.7,467.886, 202,467)
test_mark_knot()_6
test_curveto(159.176,465.994, 116.711,452.658, 81,429)
test_mark_knot()_7
test_lineto(114,368)
test_mark_knot()_8
test_curveto(140.313,385.041, 170.105,396.684, 201,402)
test_mark_knot()_9
test_curveto(216.033,404.587, 231.809,405.634, 246.268,400.776)
test_curveto(253.497,398.347, 260.287,394.428, 265.629,388.985)
test_curveto(270.971,383.541, 274.812,376.534, 276,369)
test_mark_knot()_10
test_curveto(277.186,361.482, 275.702,353.665, 272.413,346.801)
test_curveto(269.124,339.938, 264.092,333.997, 258.267,329.099)
test_curveto(246.617,319.303, 232.105,313.721, 218,308)
test_mark_knot()_11
test_curveto(192.746,297.756, 167.726,286.443, 145.32,270.931)
test_curveto(122.913,255.419, 103.089,235.424, 91,211)
test_mark_knot()_12
test_curveto(81.9232,192.662, 77.4184,171.323, 82.5427,151.513)
test_curveto(85.1048,141.608, 90.0758,132.265, 97.2634,124.984)
test_curveto(104.451,117.703, 113.889,112.559, 124,111)
test_mark_knot()_13
test_curveto(137.228,108.96, 150.603,112.998, 163.11,117.762)
test_curveto(175.618,122.526, 188.071,128.128, 201.395,129.403)
test_curveto(208.057,130.041, 214.889,129.554, 221.213,127.364)
test_curveto(227.537,125.174, 233.332,121.213, 237.179,115.737)
test_curveto(241.025,110.261, 242.792,103.23, 241.403,96.6836)
test_curveto(240.708,93.4104, 239.243,90.2939, 237.104,87.7207)
test_curveto(234.965,85.1475, 232.15,83.128, 229,82)
test_mark_knot()_14
test_lineto(0,0)
test_mark_knot()_15
test_lineto(334,117)

---
testing TaggedSpiroCPsToBezier1() using data=path0[].
test_moveto(334,117)_0
test_mark_knot()_0
test_lineto(305,176)
test_mark_knot()_1
test_curveto(279.449,153.974, 245.733,141.648, 212,142)
test_mark_knot()_2
test_curveto(201.226,142.112, 190.267,143.529, 180.511,148.103)
test_curveto(175.633,150.39, 171.099,153.461, 167.348,157.327)
test_curveto(163.596,161.194, 160.641,165.869, 159,171)
test_mark_knot()_3
test_curveto(156.364,179.243, 157.251,188.403, 160.654,196.36)
test_curveto(164.057,204.316, 169.853,211.112, 176.664,216.45)
test_curveto(190.287,227.126, 207.444,231.953, 224,237)
test_mark_knot()_4
test_curveto(250.322,245.025, 276.649,254.369, 299.324,269.96)
test_curveto(321.998,285.551, 340.921,308.162, 347,335)
test_mark_knot()_5
test_curveto(351.166,353.392, 349.066,373.009, 341.95,390.473)
test_curveto(334.833,407.936, 322.824,423.251, 308.134,435.075)
test_curveto(278.752,458.724, 239.706,467.893, 202,467)
test_mark_knot()_6
test_curveto(159.176,465.986, 116.715,452.651, 81,429)
test_mark_knot()_7
test_lineto(114,368)
test_mark_knot()_8
test_curveto(140.251,385.152, 170.075,396.808, 201,402)
test_mark_knot()_9
test_curveto(216.006,404.519, 231.742,405.476, 246.158,400.607)
test_curveto(253.366,398.172, 260.137,394.269, 265.488,388.861)
test_curveto(270.839,383.452, 274.72,376.5, 276,369)
test_mark_knot()_10
test_curveto(277.287,361.46, 275.914,353.582, 272.701,346.641)
test_curveto(269.488,339.699, 264.498,333.665, 258.672,328.709)
test_curveto(247.02,318.796, 232.367,313.255, 218,308)
test_mark_knot()_11
test_curveto(191.978,298.481, 165.57,289.162, 142.279,274.152)
test_curveto(118.988,259.143, 98.7273,237.609, 91,211)
test_mark_knot()_12
test_curveto(85.821,193.166, 86.5807,173.749, 92.5866,156.176)
test_curveto(98.5925,138.603, 109.749,122.908, 124,111)
test_mark_knot()_13
test_curveto(138.28,99.0677, 155.539,90.9339, 173.578,86.3634)
test_curveto(191.617,81.7928, 210.435,80.7131, 229,82)
test_mark_knot()_14
test_curveto(266.199,84.5786, 302.694,96.7435, 334,117)

---
testing SpiroCPsToBezier1() using data=path0[].
test_moveto(334,117)_0
test_mark_knot()_0
test_lineto(305,176)
test_mark_knot()_1
test_curveto(278.711,155.106, 245.566,142.988, 212,142)
test_mark_knot()_2
test_curveto(201.253,142.281, 190.34,143.726, 180.596,148.267)
test_curveto(175.724,150.538, 171.185,153.578, 167.419,157.413)
test_curveto(163.652,161.248, 160.67,165.891, 159,171)
test_mark_knot()_3
test_curveto(156.308,179.236, 157.16,188.418, 160.551,196.391)
test_curveto(163.942,204.365, 169.745,211.173, 176.569,216.513)
test_curveto(190.217,227.191, 207.414,231.978, 224,237)
test_mark_knot()_4
test_curveto(250.342,244.977, 276.682,254.316, 299.357,269.917)
test_curveto(322.032,285.518, 340.938,308.152, 347,335)
test_mark_knot()_5
test_curveto(351.153,353.392, 349.045,373.004, 341.926,390.463)
test_curveto(334.806,407.923, 322.8,423.235, 308.112,435.059)
test_curveto(278.737,458.706, 239.7,467.886, 202,467)
test_mark_knot()_6
test_curveto(159.176,465.994, 116.711,452.658, 81,429)
test_mark_knot()_7
test_lineto(114,368)
test_mark_knot()_8
test_curveto(140.313,385.041, 170.105,396.684, 201,402)
test_mark_knot()_9
test_curveto(216.033,404.587, 231.809,405.634, 246.268,400.776)
test_curveto(253.497,398.347, 260.287,394.428, 265.629,388.985)
test_curveto(270.971,383.541, 274.812,376.534, 276,369)
test_mark_knot()_10
test_curveto(277.186,361.482, 275.702,353.665, 272.413,346.801)
test_curveto(269.124,339.938, 264.092,333.997, 258.267,329.099)
test_curveto(246.617,319.303, 232.105,313.721, 218,308)
test_mark_knot()_11
test_curveto(192.746,297.756, 167.726,286.443, 145.32,270.931)
test_curveto(122.913,255.419, 103.089,235.424, 91,211)
test_mark_knot()_12
test_curveto(81.9232,192.662, 77.4184,171.323, 82.5427,151.513)
test_curveto(85.1048,141.608, 90.0758,132.265, 97.2634,124.984)
test_curveto(104.451,117.703, 113.889,112.559, 124,111)
test_mark_knot()_13
test_curveto(137.228,108.96, 150.603,112.998, 163.11,117.762)
test_curveto(175.618,122.526, 188.071,128.128, 201.395,129.403)
test_curveto(208.057,130.041, 214.889,129.554, 221.213,127.364)
test_curveto(227.537,125.174, 233.332,121.213, 237.179,115.737)
test_curveto(241.025,110.261, 242.792,103.23, 241.403,96.6836)
test_curveto(240.708,93.4104, 239.243,90.2939, 237.104,87.7207)
test_curveto(234.965,85.1475, 232.15,83.128, 229,82)
test_mark_knot()_14
test_lineto(0,0)
test_mark_knot()_15
test_lineto(334,117)
testing run_spiro() using data=path1[].
curve 1, line 0, x=80.000000 y=738.000000 t={ bend=0.000000 ch=697.685459 th=-0.287750 l=0.000000 
curve 1, line 1, x=749.000000 y=540.000000 t=o bend=-1.608688 ch=243.813453 th=-1.896438 l=0.000000 
curve 1, line 2, x=671.000000 y=309.000000 t=o bend=-1.770739 ch=173.404152 th=2.616009 l=0.000000 
curve 1, line 3, x=521.000000 y=396.000000 t=o bend=0.937994 ch=157.178243 th=-2.729182 l=0.000000 
curve 1, line 4, x=377.000000 y=333.000000 t=o bend=1.881365 ch=136.029409 th=-0.847817 l=0.000000 
curve 1, line 5, x=467.000000 y=231.000000 t=} bend=1.730337 ch=196.084166 th=2.403091 l=0.000000 
testing spiro_to_bpath() using data from run_spiro(data=path1[],len=6).
test_moveto(80,738)_1
test_mark_knot()_0
test_curveto(172.314,664.426, 287.04,622.654, 403.914,606.06)
test_curveto(462.352,597.763, 521.42,594.908, 580.064,588.226)
test_curveto(638.708,581.543, 698.554,570.643, 749,540)
test_mark_knot()_1
test_curveto(776.321,523.404, 800.431,500.639, 815.305,472.344)
test_curveto(830.178,444.049, 835.075,410.104, 826.082,379.43)
test_curveto(817.089,348.755, 793.992,322.521, 764.639,309.862)
test_curveto(735.286,297.204, 701.137,298.343, 671,309)
test_mark_knot()_2
test_curveto(643.661,318.667, 619.475,335.4, 595.839,352.199)
test_curveto(572.203,368.998, 548.225,386.017, 521,396)
test_mark_knot()_3
test_curveto(493.059,406.245, 461.39,408.353, 433.721,397.395)
test_curveto(419.886,391.915, 407.262,383.305, 397.36,372.199)
test_curveto(387.457,361.092, 380.322,347.504, 377,333)
test_mark_knot()_4
test_curveto(371.073,307.121, 378.034,278.522, 395.545,258.566)
test_curveto(413.056,238.61, 440.626,227.952, 467,231)

---
testing TaggedSpiroCPsToBezier0() using data=path1[].
test_moveto(80,738)_1
test_mark_knot()_0
test_curveto(172.314,664.426, 287.04,622.654, 403.914,606.06)
test_curveto(462.352,597.763, 521.42,594.908, 580.064,588.226)
test_curveto(638.708,581.543, 698.554,570.643, 749,540)
test_mark_knot()_1
test_curveto(776.321,523.404, 800.431,500.639, 815.305,472.344)
test_curveto(830.178,444.049, 835.075,410.104, 826.082,379.43)
test_curveto(817.089,348.755, 793.992,322.521, 764.639,309.862)
test_curveto(735.286,297.204, 701.137,298.343, 671,309)
test_mark_knot()_2
test_curveto(643.661,318.667, 619.475,335.4, 595.839,352.199)
test_curveto(572.203,368.998, 548.225,386.017, 521,396)
test_mark_knot()_3
test_curveto(493.059,406.245, 461.39,408.353, 433.721,397.395)
test_curveto(419.886,391.915, 407.262,383.305, 397.36,372.199)
test_curveto(387.457,361.092, 380.322,347.504, 377,333)
test_mark_knot()_4
test_curveto(371.073,307.121, 378.034,278.522, 395.545,258.566)
test_curveto(413.056,238.61, 440.626,227.952, 467,231)

---
testing SpiroCPsToBezier0() using data=path1[].
test_moveto(80,738)_1
test_mark_knot()_0
test_curveto(172.314,664.426, 287.04,622.654, 403.914,606.06)
test_curveto(462.352,597.763, 521.42,594.908, 580.064,588.226)
test_curveto(638.708,581.543, 698.554,570.643, 749,540)
test_mark_knot()_1
test_curveto(776.321,523.404, 800.431,500.639, 815.305,472.344)
test_curveto(830.178,444.049, 835.075,410.104, 826.082,379.43)
test_curveto(817.089,348.755, 793.992,322.521, 764.639,309.862)
test_curveto(735.286,297.204, 701.137,298.343, 671,309)
test_mark_knot()_2
test_curveto(643.661,318.667, 619.475,335.4, 595.839,352.199)
test_curveto(572.203,368.998, 548.225,386.017, 521,396)
test_mark_knot()_3
test_curveto(493.059,406.245, 461.39,408.353, 433.721,397.395)
test_curveto(419.886,391.915, 407.262,383.305, 397.36,372.199)
test_curveto(387.457,361.092, 380.322,347.504, 377,333)
test_mark_knot()_4
test_curveto(371.073,307.121, 378.034,278.522, 395.545,258.566)
test_curveto(413.056,238.61, 440.626,227.952, 467,231)

---
testing TaggedSpiroCPsToBezier1() using data=path1[].
test_moveto(80,738)_1
test_mark_knot()_0
test_curveto(172.314,664.426, 287.04,622.654, 403.914,606.06)
test_curveto(462.352,597.763, 521.42,594.908, 580.064,588.226)
test_curveto(638.708,581.543, 698.554,570.643, 749,540)
test_mark_knot()_1
test_curveto(776.321,523.404, 800.431,500.639, 815.305,472.344)
test_curveto(830.178,444.049, 835.075,410.104, 826.082,379.43)
test_curveto(817.089,348.755, 793.992,322.521, 764.639,309.862)
test_curveto(735.286,297.204, 701.137,298.343, 671,309)
test_mark_knot()_2
test_curveto(643.661,318.667, 619.475,335.4, 595.839,352.199)
test_curveto(572.203,368.998, 548.225,386.017, 521,396)
test_mark_knot()_3
test_curveto(493.059,406.245, 461.39,408.353, 433.721,397.395)
test_curveto(419.886,391.915, 407.262,383.305, 397.36,372.199)
test_curveto(387.457,361.092, 380.322,347.504, 377,333)
test_mark_knot()_4
test_curveto(371.073,307.121, 378.034,278.522, 395.545,258.566)
test_curveto(413.056,238.61, 440.626,227.952, 467,231)

---
testing SpiroCPsToBezier1() using data=path1[].
test_moveto(80,738)_1
test_mark_knot()_0
test_curveto(172.314,664.426, 287.04,622.654, 403.914,606.06)
test_curveto(462.352,597.763, 521.42,594.908, 580.064,588.226)
test_curveto(638.708,581.543, 698.554,570.643, 749,540)
test_mark_knot()_1
test_curveto(776.321,523.404, 800.431,500.639, 815.305,472.344)
test_curveto(830.178,444.049, 835.075,410.104, 826.082,379.43)
test_curveto(817.089,348.755, 793.992,322.521, 764.639,309.862)
test_curveto(735.286,297.204, 701.137,298.343, 671,309)
test_mark_knot()_2
test_curveto(643.661,318.667, 619.475,335.4, 595.839,352.199)
test_curveto(572.203,368.998, 548.225,386.017, 521,396)
test_mark_knot()_3
test_curveto(493.059,406.245, 461.39,408.353, 433.721,397.395)
test_curveto(419.886,391.915, 407.262,383.305, 397.36,372.199)
test_curveto(387.457,361.092, 380.322,347.504, 377,333)
test_mark_knot()_4
test_curveto(371.073,307.121, 378.034,278.522, 395.545,258.566)
test_curveto(413.056,238.61, 440.626,227.952, 467,231)
testing run_spiro() using data=path2[].
curve 2, line 0, x=233.000000 y=143.000000 t={ bend=0.000000 ch=108.115679 th=-0.046263 l=0.000000 
curve 2, line 1, x=341.000000 y=138.000000 t=o bend=-0.926114 ch=79.881162 th=-0.972377 l=0.000000 
curve 2, line 2, x=386.000000 y=72.000000 t=o bend=1.844174 ch=90.138782 th=0.871797 l=0.000000 
curve 2, line 3, x=444.000000 y=141.000000 t=} bend=0.937994 ch=157.178243 th=-2.729182 l=0.000000 
testing spiro_to_bpath() using data from run_spiro(data=path2[],len=4).
test_moveto(233,143)_1
test_mark_knot()_0
test_curveto(249.592,152.178, 268.758,156.639, 287.698,155.745)
test_curveto(306.638,154.851, 325.283,148.607, 341,138)
test_mark_knot()_1
test_curveto(363.594,122.753, 379.786,98.5395, 386,72)
test_mark_knot()_2
test_curveto(390.58,52.4395, 389.897,31.7133, 384.352,12.4039)
test_curveto(378.808,-6.90551, 368.441,-24.7755, 354.638,-39.3726)
test_curveto(327.032,-68.5668, 285.794,-83.7957, 245.694,-81.2662)
test_curveto(205.595,-78.7367, 167.108,-58.898, 140.822,-28.5107)
test_curveto(114.535,1.87655, 100.493,42.3853, 101.481,82.5524)
test_curveto(102.469,122.719, 118.343,162.269, 145.013,192.321)
test_curveto(171.682,222.373, 208.93,242.787, 248.567,249.365)
test_curveto(288.204,255.942, 329.988,248.669, 365.12,229.172)
test_curveto(400.251,209.674, 428.514,178.075, 444,141)

---
testing TaggedSpiroCPsToBezier0() using data=path2[].
test_moveto(233,143)_1
test_mark_knot()_0
test_curveto(249.592,152.178, 268.758,156.639, 287.698,155.745)
test_curveto(306.638,154.851, 325.283,148.607, 341,138)
test_mark_knot()_1
test_curveto(363.594,122.753, 379.786,98.5395, 386,72)
test_mark_knot()_2
test_curveto(390.58,52.4395, 389.897,31.7133, 384.352,12.4039)
test_curveto(378.808,-6.90551, 368.441,-24.7755, 354.638,-39.3726)
test_curveto(327.032,-68.5668, 285.794,-83.7957, 245.694,-81.2662)
test_curveto(205.595,-78.7367, 167.108,-58.898, 140.822,-28.5107)
test_curveto(114.535,1.87655, 100.493,42.3853, 101.481,82.5524)
test_curveto(102.469,122.719, 118.343,162.269, 145.013,192.321)
test_curveto(171.682,222.373, 208.93,242.787, 248.567,249.365)
test_curveto(288.204,255.942, 329.988,248.669, 365.12,229.172)
test_curveto(400.251,209.674, 428.514,178.075, 444,141)

---
testing SpiroCPsToBezier0() using data=path2[].
test_moveto(233,143)_1
test_mark_knot()_0
test_curveto(249.592,152.178, 268.758,156.639, 287.698,155.745)
test_curveto(306.638,154.851, 325.283,148.607, 341,138)
test_mark_knot()_1
test_curveto(363.594,122.753, 379.786,98.5395, 386,72)
test_mark_knot()_2
test_curveto(390.58,52.4395, 389.897,31.7133, 384.352,12.4039)
test_curveto(378.808,-6.90551, 368.441,-24.7755, 354.638,-39.3726)
test_curveto(327.032,-68.5668, 285.794,-83.7957, 245.694,-81.2662)
test_curveto(205.595,-78.7367, 167.108,-58.898, 140.822,-28.5107)
test_curveto(114.535,1.87655, 100.493,42.3853, 101.481,82.5524)
test_curveto(102.469,122.719, 118.343,162.269, 145.013,192.321)
test_curveto(171.682,222.373, 208.93,242.787, 248.567,249.365)
test_curveto(288.204,255.942, 329.988,248.669, 365.12,229.172)
test_curveto(400.251,209.674, 428.514,178.075, 444,141)

---
testing TaggedSpiroCPsToBezier1() using data=path2[].
test_moveto(233,143)_1
test_mark_knot()_0
test_curveto(249.592,152.178, 268.758,156.639, 287.698,155.745)
test_curveto(306.638,154.851, 325.283,148.607, 341,138)
test_mark_knot()_1
test_curveto(363.594,122.753, 379.786,98.5395, 386,72)
test_mark_knot()_2
test_curveto(390.58,52.4395, 389.897,31.7133, 384.352,12.4039)
test_curveto(378.808,-6.90551, 368.441,-24.7755, 354.638,-39.3726)
test_curveto(327.032,-68.5668, 285.794,-83.7957, 245.694,-81.2662)
test_curveto(205.595,-78.7367, 167.108,-58.898, 140.822,-28.5107)
test_curveto(114.535,1.87655, 100.493,42.3853, 101.481,82.5524)
test_curveto(102.469,122.719, 118.343,162.269, 145.013,192.321)
test_curveto(171.682,222.373, 208.93,242.787, 248.567,249.365)
test_curveto(288.204,255.942, 329.988,248.669, 365.12,229.172)
test_curveto(400.251,209.674, 428.514,178.075, 444,141)

---
testing SpiroCPsToBezier1() using data=path2[].
test_moveto(233,143)_1
test_mark_knot()_0
test_curveto(249.592,152.178, 268.758,156.639, 287.698,155.745)
test_curveto(306.638,154.851, 325.283,148.607, 341,138)
test_mark_knot()_1
test_curveto(363.594,122.753, 379.786,98.5395, 386,72)
test_mark_knot()_2
test_curveto(390.58,52.4395, 389.897,31.7133, 384.352,12.4039)
test_curveto(378.808,-6.90551, 368.441,-24.7755, 354.638,-39.3726)
test_curveto(327.032,-68.5668, 285.794,-83.7957, 245.694,-81.2662)
test_curveto(205.595,-78.7367, 167.108,-58.898, 140.822,-28.5107)
test_curveto(114.535,1.87655, 100.493,42.3853, 101.481,82.5524)
test_curveto(102.469,122.719, 118.343,162.269, 145.013,192.321)
test_curveto(171.682,222.373, 208.93,242.787, 248.567,249.365)
test_curveto(288.204,255.942, 329.988,248.669, 365.12,229.172)
test_curveto(400.251,209.674, 428.514,178.075, 444,141)
testing run_spiro() using data=path3[].
error with run_spiro() using data=path3[].

---
Multi-thread testing of libspiro.
bad pthread_create[167]
time 0.747777

Release?

@JoesCat are you happy to cut a new release? I'm planning on switching the Windows builds of FontForge to just use the main msys2 package repo instead of having to maintain my own for libspiro/libuninameslist, but this will mean going back to the last tagged version of libspiro.

Please consider changing bezctx* to void* most places

(Copied from MFEK/libspiro@772785b README.md, which assumes this was already done. Of course it's open for discussion, I'm just too lazy to retype. 😄)

Before 20200918, the Bézier context was of type bezctx*, meaning, a pointer to a _bezctx struct. (typedef struct _bezctx bezctx;)

Afterwards, it was changed to a void*, meaning, any pointer. As C is not object oriented and does not have classes, there is no better alternative.

The main reasons this was done is that Rust's bindgen was applying Rust's type checking to the struct, thinking it was really supposed to be a bezctx and nothing else.

However, void* is also more correct. As stated above, in almost all applications (any application that needs to store the produced Bézier and not just immediately write it out), a typecast is going to be needed to silence compiler warnings. In almost all applications, it makes no sense, therefore, for the type to be bezctx*, as the programmer will be typecasting. Instead of defining a concrete type, then, allowing any type is better.

Of course, though, to prevent segmentation faults, the type you use must contain all of the fields, in the same order, as a bezctx*, whether directly in your subordinate struct, or else in a base item.

If you were not already typecasting for some reason (perhaps you made, for example, an SVG writer), you can fix your callback code to link with the new version of the library by changing the first argument in the signatures of all your custom callback functions (i.e. bezctx_moveto, bezctx_lineto, etc.) from bezctx *bc to void* _bc. Then, on the first one of each callback function, do:

    bezctx* bc = (bezctx*)_bc;

Example:

diff --git a/bezctx.c b/bezctx.c
index 94979ff..9f55eef 100644
--- a/bezctx.c
+++ b/bezctx.c
@@ -25,41 +25,46 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA

 #include "bezctx.h"

-void bezctx_moveto(bezctx *bc, double x, double y, int is_open)
+void bezctx_moveto(void *_bc, double x, double y, int is_open)
 {
+    bezctx* bc = (bezctx*)_bc;
 #ifdef VERBOSE
     printf("moveto(%g,%g)_%d\n",x,y,is_open);
 #endif
     bc->moveto(bc, x, y, is_open);
 }

Patch: MFEK@772785b

Please consider using `static const`'s for SPIRO_CORNER, SPIRO_G4, SPIRO_G2, etc.

Let me begin by saying, this is not really your problem, but rather bindgen's problem. (bindgen does the C interop for Rust, one of the main reasons I think Rust is worth using; without bindgen giving C ABI access it's not that great.)

But, I think it would be good to consider changing it anyway. 🥺😉

Having these as symbols in the library is better than just #define's and makes it easier for bindings to "see" them and work with them. There is also the issue that bindgen really cannot know if 'v' is a signed char or an unsigned char; it is ambiguous. In C this is not a problem. In Rust, it is a headache to convert i8 (c_char) to u8 ('v', etc.).

If you agree @JoesCat, I'm happy to PR this.

Patch: MFEK@bb20451

configure error

wget -O libspiro-20221101.tar.gz https://github.com/fontforge/libspiro/archive/refs/tags/20221101.tar.gz
tar xvf libspiro-20221101.tar.gz
autoreconf -fvi

error line 14517: syntax error near unexpected token `done', where I see two cycles "for ac_func in " for inside each other
where uses the same var ac_func
except this, in first cycle:
else
case e in
e)

and in nested if again
else
case e in
e)

in whole, syntax is correct, I don't understand where is a mistake
but the same time, code too comple to find bug

checking whether the gcc linker (/usr/local/bin/ld -m elf_x86_64) supports shared libraries... yes
checking whether -lc should be explicitly linked in... no
checking dynamic linker characteristics... GNU/Linux ld.so
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... no
checking for gcc... (cached) gcc
checking whether the compiler supports GNU C... (cached) yes
checking whether gcc accepts -g... (cached) yes
checking for gcc option to enable C11 features... (cached) none needed
checking whether gcc understands -c and -o together... (cached) yes
checking dependency style of gcc... (cached) gcc3
checking whether ln -s works... yes
checking whether make sets $(MAKE)... (cached) yes
checking for a sed that does not truncate output... (cached) /usr/local/bin/sed
checking for valgrind... valgrind
checking for strip... (cached) strip
checking whether make supports nested variables... (cached) yes
checking for math.h... yes
./configure: line 14517: syntax error near unexpected token done' ./configure: line 14517: done'

Linux Mint 20.3 Cinnamon
x86_64 - kernel 5.15

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.