From 044e1091a3018d14d0df935b4e655c7e75eb2d04 Mon Sep 17 00:00:00 2001 From: Joe Da Silva Date: Wed, 1 Jul 2015 08:18:17 -0700 Subject: [PATCH] LibSpiro version 0.4 Collective fixes from tagpoint v0.3 (20150131) up to now v0.4 (20150701). --- AUTHORS | 3 +- ChangeLog | 30 ++++++----- Makefile.am | 4 +- config.guess | 29 ++++++++--- config.sub | 13 +++-- configure.ac | 47 +++++++++++++++-- spiro.c | 8 +-- tests/Makefile.am | 5 +- tests/call-test.c | 128 +++++++++++++++++++++++++++++++++++++++------- 9 files changed, 213 insertions(+), 54 deletions(-) diff --git a/AUTHORS b/AUTHORS index ed579b4..43e9f79 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,10 +1,11 @@ Authors: Raph Levien George Williams +Joe Da Silva, www.joescat.com Patent Grant and Copyright (C) 2007 Raph Levien -Extra edits, patches, updates... (2013...) +Extra edits, patches, updates... (2013,2014,2015...) Dave Crossland Shriramana Sharma Joe Da Silva diff --git a/ChangeLog b/ChangeLog index 90c4726..fbd86de 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,14 @@ -- 31-Jan-2015 +- 2015-Jul-1 + * Libspiro Version 0.4.20150701 + * Re-edit lib and tests to be more accommodating of older compilers. + * Many changes to call-test.c to run on bigger variety of platforms, + and some minor configure.ac tweaks done to resolve issues #9, #10. + as seen on https://github.com/fontforge/libspiro/issues (closed). + * Added developer/install test for cyclic spiros (without {} or z). + * Verify libspiro output data is correct for test curves {0,1,2,4}. + * User can overide default configure flags with LS_CFLAGS and LS_LIB + +- 2015-Jan-31 * Libspiro Version 0.3.20150131 * Allow Libspiro to be included using PKG_CHECK_MODULES(). * Bug fixes in configure.ac m4 calls that caused problems seen in: @@ -7,37 +17,33 @@ * Add TaggedSpiroCPsToBezier1() and SpiroCPsToBezier1() for programs that cannot use TaggedSpiroCPsToBezier0() or SpiroCPsToBezier0(). -- 30-Sep-2013 +- 2013-Sep-30 * Libspiro Version 0.2.20130930 - -- 29-Aug-2013 * Optional 'make check' runs 'call-test' to check libspiro functions. * Minor logic optimizations. Removed global 'n', passed 'n' instead. -- 22-Jul-2013 +- 2013-Jul-22 * Use 'make check' to run spiro.c UNIT_TEST internal main() routine. -- 28-Jun-2013 +- 2013-Jun-28 * Allow for setting VERBOSE during configure - helps with debugging. * Allow for setting CHECK_INPUT_FINITENESS during configure - to test input values for finiteness before doing calculations (optional). * Pass nmat variable to reduce repeatedly recomputing with count_vec(). -- 31-May-2013 +- 2013-May-31 * Convert build system to autotools method (configure.ac, Makefile.am). - -- 29-May-2013 * Backporting robustness patches from Inkscape. * Increase Spiro max iterations to 30 after finding convergences of 15. * If did not converge or encountered non-finite values, do not output spline. Only good splines will be output. -- 20-Apr-2013 +- 2013-Apr-20 * Initial commit to https://github.com/fontforge/libspiro.git * Add bezctx.md based on http://libspiro.sourceforge.net/bezctx.html -- 08-May-2009 +- 2009-May-08 * Add Java implementation. -- 28-Oct-2007 +- 2007-Oct-28 * Initial release. diff --git a/Makefile.am b/Makefile.am index 4027e5b..8bc4aac 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,8 +7,8 @@ pkgconfig_DATA = libspiro.pc ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} -AM_CFLAGS = $(WCFLAGS) -AM_LDFLAGS = $(WCFLAGS) -no-undefined --mode=link +AM_CFLAGS = $(WCFLAGS) $(LS_CFLAGS) +AM_LDFLAGS = $(WLSLIB) $(LS_LIB) -no-undefined --mode=link LIBTOOL_DEPS = @LIBTOOL_DEPS@ diff --git a/config.guess b/config.guess index dbfb978..e5bdb99 100644 --- a/config.guess +++ b/config.guess @@ -2,7 +2,7 @@ # Attempt to guess a canonical system name. # Copyright 1992-2015 Free Software Foundation, Inc. -timestamp='2015-01-01' +timestamp='2015-06-30' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -168,20 +168,27 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + /sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || \ + echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` + machine=${arch}${endian}-unknown + ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) + arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ @@ -197,6 +204,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in os=netbsd ;; esac + # Determine ABI tags. + case "${UNAME_MACHINE_ARCH}" in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` + ;; + esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need @@ -213,7 +227,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" + echo "${machine}-${os}${release}${abi}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` @@ -933,6 +947,9 @@ EOF crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; + e2k:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; @@ -1021,7 +1038,7 @@ EOF echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} diff --git a/config.sub b/config.sub index 6d2e94c..8f1229c 100644 --- a/config.sub +++ b/config.sub @@ -2,7 +2,7 @@ # Configuration validation subroutine script. # Copyright 1992-2015 Free Software Foundation, Inc. -timestamp='2015-01-01' +timestamp='2015-03-08' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -117,7 +117,7 @@ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os @@ -259,7 +259,7 @@ case $basic_machine in | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ - | epiphany \ + | e2k | epiphany \ | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ @@ -381,7 +381,7 @@ case $basic_machine in | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ + | e2k-* | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ @@ -518,6 +518,9 @@ case $basic_machine in basic_machine=i386-pc os=-aros ;; + asmjs) + basic_machine=asmjs-unknown + ;; aux) basic_machine=m68k-apple os=-aux @@ -1373,7 +1376,7 @@ case $os in | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* \ + | -aos* | -aros* | -cloudabi* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ diff --git a/configure.ac b/configure.ac index 5a0b14b..96d9334 100644 --- a/configure.ac +++ b/configure.ac @@ -1,12 +1,12 @@ # -*- Autoconf -*- dnl Process this file with autoconf to produce a configure script. -# Copyright (C) 2013, by Joe Da Silva +# Copyright (C) 2013,2014,2015 by Joe Da Silva AC_PREREQ([2.61]) #------------------------------------------- # PackageTimestamp version -m4_define([spiro_package_stamp], [20150131]) +m4_define([spiro_package_stamp], [20150701]) #------------------------------------------- # Making point releases: # spiro_major_version += 0; @@ -21,7 +21,7 @@ m4_define([spiro_package_stamp], [20150131]) # spiro_minor_version = 0; # m4_define([spiro_major_version], [0]) -m4_define([spiro_minor_version], [3]) +m4_define([spiro_minor_version], [4]) m4_define([spiro_version], [spiro_major_version.spiro_minor_version.spiro_package_stamp]) m4_define([spiro_info], @@ -144,8 +144,16 @@ AM_CONDITIONAL([WANTPTHREADS],[test x$havepthreads = xtrue]) # Platform specific stuff ($host) AC_CANONICAL_HOST +#------------------------------------------- +# Compiler and Linker flags to override auto +# detection and insertion. Use CFLAGS if you +# want to add more in addition to autodetect +AC_ARG_VAR([LS_CFLAGS],[C compiler flags for libspiro, overriding automatic detection]) +AC_ARG_VAR([LS_LIB],[Linker flags for libspiro, overriding automatic detection]) + #------------------------------------------- # Check for and add usable compiler warnings +# Skip if replacing with LS_CFLAGS instead. WCFLAGS="" AC_LANG_PUSH([C]) AX_CHECK_COMPILE_FLAG([-Wall],[WCFLAGS="$WCFLAGS -Wall"]) @@ -155,8 +163,30 @@ AX_CHECK_COMPILE_FLAG([-Wbad-function-cast],[WCFLAGS="$WCFLAGS -Wbad-function-ca AX_CHECK_COMPILE_FLAG([-Wc++-compat],[WCFLAGS="$WCFLAGS -Wc++-compat"]) AX_CHECK_COMPILE_FLAG([-Wmissing-prototypes],[WCFLAGS="$WCFLAGS -Wmissing-prototypes"]) AX_CHECK_COMPILE_FLAG([-Wunused],[WCFLAGS="$WCFLAGS -Wunused"]) + +dnl AX_CHECK_COMPILE_FLAG([-Wconversion],[WCFLAGS="$WCFLAGS -Wconversion"]) +dnl AX_CHECK_COMPILE_FLAG([-Wsign-conversion],[WCFLAGS="$WCFLAGS -Wsign-conversion"]) +dnl AX_CHECK_COMPILE_FLAG([-Wformat=2],[WCFLAGS="$WCFLAGS -Wformat=2"]) +dnl AX_CHECK_COMPILE_FLAG([-Wformat-security],[WCFLAGS="$WCFLAGS -Wformat-security"]) +dnl AX_CHECK_COMPILE_FLAG([-fno-common],[WCFLAGS="$WCFLAGS -fno-common"]) +dnl AX_CHECK_COMPILE_FLAG([-Wmissing-declarations],[WCFLAGS="$WCFLAGS -Wmissing-declarations"]) +dnl AX_CHECK_COMPILE_FLAG([-Wstrict-prototypes],[WCFLAGS="$WCFLAGS -Wstrict-prototypes"]) +dnl AX_CHECK_COMPILE_FLAG([-fPIC],[WCFLAGS="$WCFLAGS -fPIC"]) +dnl AX_CHECK_COMPILE_FLAG([-Wstrict-overflow],[WCFLAGS="$WCFLAGS -Wstrict-overflow"]) +dnl AX_CHECK_COMPILE_FLAG([-Wpointer-arith],[WCFLAGS="$WCFLAGS -Wpointer-arith"]) +dnl AX_CHECK_COMPILE_FLAG([-Wcast-qual],[WCFLAGS="$WCFLAGS -Wcast-qual"]) +dnl AX_CHECK_COMPILE_FLAG([-Wcast-align],[WCFLAGS="$WCFLAGS -Wcast-align"]) +dnl AX_CHECK_COMPILE_FLAG([-Wpadded],[WCFLAGS="$WCFLAGS -Wpadded"]) +dnl AX_CHECK_COMPILE_FLAG([-Woverlength-strings],[WCFLAGS="$WCFLAGS -Woverlength-strings"]) AC_LANG_POP -AC_SUBST([WCFLAGS]) +# Skip if replacing with LS_LIB instead. +WLSLIB="" +if test -z $LS_LIB ; then + WLSLIB="${WCFLAGS}" +fi +if test "${LS_CFLAGS}"x != x; then + WCFLAGS="" +fi #------------------------------------------- # Put ifdef wrapper around spiro-config.h so @@ -169,6 +199,10 @@ AH_BOTTOM([#endif]) # Pass variables to MAKEFILE.AM AC_SUBST([HOST],[host]) AC_SUBST([LIBSPIRO_VERSION],[spiro_info]) +AC_SUBST([LS_CFLAGS]) +AC_SUBST([LS_LIB]) +AC_SUBST([WCFLAGS]) +AC_SUBST([WLSLIB]) #------------------------------------------- AC_PROG_LIBTOOL @@ -188,8 +222,11 @@ Configuration: Build code location ${builddir} Destination prefix ${prefix} Compiler ${CC} - Config auto options "${WCFLAGS}" + Config auto WCFLAGS "${WCFLAGS}" + Config auto WLSLIB "${WLSLIB}" Config CFLAGS "${CFLAGS}" Config LDFLAGS "${LDFLAGS}" + Config LS_CFLAGS "${LS_CFLAGS}" + Config LS_LIB "${LS_LIB}" ]) diff --git a/spiro.c b/spiro.c index 7e1c205..a4102f9 100644 --- a/spiro.c +++ b/spiro.c @@ -662,9 +662,8 @@ static int count_vec(const spiro_seg *s, int nseg) } static void -add_mat_line(bandmat *m, double *v, - double derivs[4], double x, double y, int j, int jj, int jinc, - int nmat) +add_mat_line(bandmat *m, double *v,double derivs[4], + double x, double y, int j, int jj, int jinc, int nmat) { int joff, k; @@ -779,6 +778,9 @@ spiro_iter(spiro_seg *s, bandmat *m, int *perm, double *v, int n, int nmat) memcpy(v + 2 * nmat, v, sizeof(double) * nmat); n_invert = 3 * nmat; j = nmat; +#ifdef VERBOSE + printf("cyclic\n"); +#endif } else { n_invert = nmat; j = 0; diff --git a/tests/Makefile.am b/tests/Makefile.am index a19a727..5d79427 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -8,7 +8,7 @@ DEPS = $(top_builddir)/.libs/libspiro.la LDADDS = $(top_builddir)/.libs/libspiro.la # The tests -noinst_PROGRAMS = unit-test call-test0 call-test1 call-test2 call-test3 call-testm +noinst_PROGRAMS = unit-test call-test0 call-test1 call-test2 call-test3 call-test4 call-testm unit_test_SOURCES = unit-test.c @@ -24,6 +24,9 @@ call_test2_LDADD = $(LDADDS) call_test3_SOURCES = call-test3.c call_test3_LDADD = $(LDADDS) +call_test4_SOURCES = call-test4.c +call_test4_LDADD = $(LDADDS) + call_testm_SOURCES = call-testm.c call_testm_LDADD = $(LDADDS) if WANTPTHREADS diff --git a/tests/call-test.c b/tests/call-test.c index 3e60e4d..862672d 100644 --- a/tests/call-test.c +++ b/tests/call-test.c @@ -42,6 +42,51 @@ static double get_time (void) { return tb.time + 1e-3 * tb.millitm; } +#ifndef DO_CALL_TESTM +/* Expected run_spiro() test data results for path{0/1/2/4}[]. */ +typedef struct { + double b, ch, th; +} rs_check_vals; + +rs_check_vals verify_rs0[] = { /* iteration5 */ + {0.000000, 65.741920, 2.027641}, /* v, 34,117 */ + {0.000000, 99.020200, -2.791096}, /* v,305,176 */ + {-0.851164, 60.415230, 2.640925}, /* c,212,142 */ + {-1.847893, 92.633687, 0.793032}, /* c,159,171 */ + {-0.120277, 157.267288, 0.672755}, /* c,224,237 */ + {1.730337, 196.084166, 2.403091}, /* c,347,335 */ + {1.042797, 126.826653, -2.837297}, /* c,202,467 */ + {0.000000, 69.354164, -1.074902}, /* v, 81,429 */ + {0.000000, 93.407708, 0.372554}, /* v,114,368 */ + {-0.787061, 81.939002, -0.414507}, /* c,201,402 */ + {-1.916483, 84.172442, -2.330990}, /* c,276,369 */ + {-0.158341, 159.806133, -2.489331}, /* c,218,308 */ + {1.237282, 105.304321, -1.252049}, /* c, 91,211 */ + {0.982576, 108.931171, -0.269473}, /* c,124,111 */ + {-2.528266, 243.238566, -2.797739} /* c,229, 82 */ +}; /* z */ + +rs_check_vals verify_rs1[] = { /* iteration6 */ + {0.000000, 697.685459, -0.287750}, /* {, 80,738 */ + {-1.608688, 243.813453, -1.896438}, /* o,749,540 */ + {-1.770739, 173.404152, 2.616009}, /* o,671,309 */ + {0.937994, 157.178243, -2.729182}, /* o,521,396 */ + {1.881365, 136.029409, -0.847817} /* o,377,333 */ +}; /* },467,231 */ + +rs_check_vals verify_rs2[] = { /* iteration26 */ + {0.000000, 108.115679, -0.046263}, /* {,233,143 */ + {-0.926114, 79.881162, -0.972377}, /* o,341,138 */ + {1.844174, 90.138782, 0.871797} /* o,386, 72 */ +}; /* },444,141 */ + +rs_check_vals verify_rs4[] = { /* iteration2 */ + {-1.570796, 141.421356, 0.785398}, /* o,-100, 0 */ + {-1.570796, 141.421356, -0.785398}, /* o, 0, 100 */ + {-1.570796, 141.421356, -2.356194}, /* o,100, 0 */ +}; /* o, 0,-100 */ +#endif + void load_test_curve(spiro_cp *spiro, int *nextknot, int c) { /* load a test curve (and nextknot locations) into memory */ spiro_cp path0[] = { /* ...came with unit-test */ @@ -52,21 +97,21 @@ void load_test_curve(spiro_cp *spiro, int *nextknot, int c) { {224, 237, 'c'}, {347, 335, 'c'}, {202, 467, 'c'}, - {81, 429, 'v'}, + { 81, 429, 'v'}, {114, 368, 'v'}, {201, 402, 'c'}, {276, 369, 'c'}, {218, 308, 'c'}, - {91, 211, 'c'}, + { 91, 211, 'c'}, {124, 111, 'c'}, - {229, 82, 'c'}, + {229, 82, 'c'}, {0, 0, 'z'} }; int knot0[] = { 1, 1, 3, 3, 2, 3, 1, 1, 1, 3, 3, 2, 2, 2, 1, 1 }; spiro_cp path1[] = { /* do a test using "{"..."}" */ - {80, 738, '{'}, + { 80, 738, '{'}, {749, 540, 'o'}, {671, 309, 'o'}, {521, 396, 'o'}, @@ -79,7 +124,7 @@ void load_test_curve(spiro_cp *spiro, int *nextknot, int c) { spiro_cp path2[] = { /* this does many iterations */ {233, 143, '{'}, {341, 138, 'o'}, - {386, 72, 'o'}, + {386, 72, 'o'}, {444, 141, '}'} }; int knot2[] = { @@ -88,7 +133,7 @@ void load_test_curve(spiro_cp *spiro, int *nextknot, int c) { spiro_cp path3[] = { /* this will fail to converge */ {233, 144, '{'}, /* will not pass (on purpose) */ {341, 138, 'o'}, - {386, 72, 'o'}, + {386, 72, 'o'}, {443, 141, 'o'}, {467, 231, 'o'}, {377, 333, '}'} @@ -96,6 +141,15 @@ void load_test_curve(spiro_cp *spiro, int *nextknot, int c) { int knot3[] = { 2, 1, 9, 1, 1, 0 }; + spiro_cp path4[] = { /* test a cyclic calculation. */ + {-100, 0, SPIRO_G4}, + { 0, 100, SPIRO_G4}, + { 100, 0, SPIRO_G4}, + { 0, -100, SPIRO_G4}, + }; + int knot4[] = { + 2, 2, 2, 0 + }; int i; /* Load static variable tables into memory because */ @@ -117,14 +171,19 @@ void load_test_curve(spiro_cp *spiro, int *nextknot, int c) { spiro[i].y = path2[i].y; spiro[i].ty = path2[i].ty; nextknot[i] = knot2[i]; - } else for (i = 0; i < 6; i++) { + } else if ( c==3 ) for (i = 0; i < 6; i++) { spiro[i].x = path3[i].x; spiro[i].y = path3[i].y; spiro[i].ty = path3[i].ty; nextknot[i] = knot3[i]; + } else for (i = 0; i < 4; i++) { + spiro[i].x = path4[i].x; + spiro[i].y = path4[i].y; + spiro[i].ty = path4[i].ty; + nextknot[i] = knot4[i]; } } -int cl[] = {16, 6, 4, 6}; +int cl[] = {16, 6, 4, 6, 4}; #ifndef DO_CALL_TESTM /* Provide bare-bones do-nothing functions for testing. This only */ @@ -162,6 +221,7 @@ int test_curve(int c) { int nextknot[17]; spiro_seg *segs = NULL; bezctx *bc; + rs_check_vals *rsp; int i,done; /* Load sample data so that we can see if library is callable */ @@ -174,11 +234,30 @@ int test_curve(int c) { return -1; } + /* Load pointer to verification data to ensure it works right */ + if ( c==0 ) rsp = verify_rs0; + else if ( c==1 ) rsp = verify_rs1; + else if ( c==2 ) rsp = verify_rs2; + else if ( c==3 ) rsp = NULL; /* expecting failure to converge */ + else rsp = verify_rs4; + /* Quick visual check shows X,Y knots match with each pathN[] */ for (i=0; i < cl[c]-1; i++) { - printf("curve %d, line %d, x=%f y=%f t=%c bend=%f ch=%f th=%f \n",c,i,segs[i].x,segs[i].y,segs[i].ty,segs[i].bend_th,segs[i].seg_ch,segs[i].seg_th); + printf("curve %d, line %d x=%f y=%f t=%c bend=%f ch=%f th=%f ",c,i,segs[i].x,segs[i].y,segs[i].ty,segs[i].bend_th,segs[i].seg_ch,segs[i].seg_th); + /* Let computer verify that run_spiro() data is PASS/FAIL */ + if ( (fabs(segs[i].x - spiro[i].x) > 1e-5) || + (fabs(segs[i].y - spiro[i].y) > 1e-5) || + (segs[i].ty != spiro[i].ty) || + (fabs(segs[i].bend_th - rsp[i].b) > 1e-5) || + (fabs(segs[i].seg_ch - rsp[i].ch) > 1e-5) || + (fabs(segs[i].seg_th - rsp[i].th) > 1e-5) ) { + printf("FAIL\nerror found with run_spiro() data. Results are not the same.\n"); + printf("expected line %d x=%f y=%f t=%c bend=%f ch=%f th=%f \n",i,spiro[i].x,spiro[i].y,spiro[i].ty,rsp[i].b,rsp[i].ch,rsp[i].th); + return -2; + } else + printf("PASS\n"); } - printf("curve %d, line %d, x=%f y=%f t=%c\n",c,i,segs[i].x,segs[i].y,segs[i].ty); + printf("curve %d, line %d x=%f y=%f t=%c\n",c,i,segs[i].x,segs[i].y,segs[i].ty); /* Quick visual check shows X,Y knots match with each pathN[] */ printf("---\ntesting spiro_to_bpath() using data from run_spiro(data=path%d[],len=%d).\n",c,cl[c]); @@ -187,34 +266,38 @@ int test_curve(int c) { free(segs); +#ifndef DO_CALL_TEST4 /* Check if TaggedSpiroCPsToBezier0() works okay */ printf("---\ntesting TaggedSpiroCPsToBezier0() using data=path%d[].\n",c); if ( TaggedSpiroCPsToBezier0(spiro,bc)!=1 ) { printf("error with TaggedSpiroCPsToBezier0() using data=path%d[].\n",c); - return -2; + return -3; } +#endif /* Check if SpiroCPsToBezier0() works okay */ printf("---\ntesting SpiroCPsToBezier0() using data=path%d[].\n",c); if ( SpiroCPsToBezier0(spiro,cl[c],(c==0 ? 1 : 0),bc)!=1 ) { printf("error with SpiroCPsToBezier0() using data=path%d[].\n",c); - return -3; + return -4; } +#ifndef DO_CALL_TEST4 /* Check if TaggedSpiroCPsToBezier1() works okay */ printf("---\ntesting TaggedSpiroCPsToBezier1() using data=path%d[].\n",c); TaggedSpiroCPsToBezier1(spiro,bc,&done); if ( done!=1 ) { printf("error with TaggedSpiroCPsToBezier1() using data=path%d[].\n",c); - return -4; + return -5; } +#endif /* Check if SpiroCPsToBezier1() works okay */ printf("---\ntesting SpiroCPsToBezier1() using data=path%d[].\n",c); SpiroCPsToBezier1(spiro,cl[c],(c==0 ? 1 : 0),bc,&done); if ( done!=1 ) { printf("error with SpiroCPsToBezier1() using data=path%d[].\n",c); - return -5; + return -6; } free(bc); @@ -396,17 +479,17 @@ int test_multi_curves(void) { if ( (spiro[i]=malloc(cl[0]*sizeof(spiro_cp)))==NULL || \ (nextknot[i]=calloc(cl[0]+1,sizeof(int)))==NULL ) goto test_multi_curves_exit; - load_test_curve(spiro[i], nextknot[i], 0); + load_test_curve(spiro[i],nextknot[i],0); scl[i++]=cl[0]; if ( (spiro[i]=malloc(cl[1]*sizeof(spiro_cp)))==NULL || \ (nextknot[i]=calloc(cl[1],sizeof(int)))==NULL ) goto test_multi_curves_exit; - load_test_curve(spiro[i], nextknot[i], 1); + load_test_curve(spiro[i],nextknot[i],1); scl[i++]=cl[1]; if ( (spiro[i]=malloc(cl[2]*sizeof(spiro_cp)))==NULL || \ (nextknot[i]=calloc(cl[2],sizeof(int)))==NULL ) goto test_multi_curves_exit; - load_test_curve(spiro[i], nextknot[i], 2); + load_test_curve(spiro[i],nextknot[i],2); scl[i++]=cl[2]; } @@ -496,6 +579,10 @@ int test_multi_curves(void) { temp = spiro[i]; pk = nextknot[i]; k=0; +#ifdef VERBOSE + printf("test[%d], input spiro[0..%d], output bc->my_curve[0..%d]\n", \ + i, scl[i]-1, bc[i]->len-1); +#endif for (j=0; j < scl[i] && temp[j].ty!='z'; j++) { ty = bc[i]->my_curve[k].ty; x = bc[i]->my_curve[k].x1; @@ -509,8 +596,8 @@ int test_multi_curves(void) { y = bc[i]->my_curve[k].y3; } #ifdef VERBOSE - printf("len=%d s[%d].ty=%c x=%g y=%g, len=%d pk=%d mc[%d] x=%g y=%g\n", \ - scl[i],j,temp[j].ty,temp[j].x,temp[j].y, bc[i]->len,pk[j],k,x,y); + printf(" s[%d][ty=%c x=%g y=%g], pk=%d mc[%d][x=%g y=%g]\n", \ + j,temp[j].ty,temp[j].x,temp[j].y,pk[j],k,x,y); #endif if ( (fabs(temp[j].x - x) > 1e-8) || (fabs(temp[j].y - y) > 1e-8) ) { /* close-enough for testing 10x range of doubles. */ @@ -561,6 +648,9 @@ int main(int argc, char **argv) { else ret = 0; /* expected failure to converge */ #endif +#ifdef DO_CALL_TEST4 + ret=test_curve(4); +#endif #ifdef DO_CALL_TESTM ret=test_multi_curves(); #endif