Skip to content

Commit

Permalink
LibSpiro 20221101 - Version 1.3.0
Browse files Browse the repository at this point in the history
Fixed two bugs in spiro.c
1. Removed test code "if (xmax >= ymax) dm[0] = xmax; else dm[0] = ymax;"
This would be seen as problematic if drawing in the -x, -y area.
(This was test-code that I forgot to remove before making a release).
2. Moved NULL test to correct location (SPIRO_INTERNAL_BEZCTX=0).
Fixed minor numerical bug in call-test21.c
(This bug is not important to anyone, except maybe/not maintainers).

Little bit of a bonus...
Solved call-test10 and call-test11 by searching for the first available
'c' or 'o'. This is more of a kludge versus a true fix since a spiro
curve will need to contain one or more 'v', 'c' or 'o' somewhere.
call-test10 is basically the same curve as call-test7, but starts with
'ah', while call-test11 is a curve starting with '[]'. Basically KISS.
  • Loading branch information
JoesCat committed Nov 2, 2022
1 parent 6f0a617 commit 0d87bd2
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 62 deletions.
11 changes: 11 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
- 2022-Nov-01
* Libspiro Version 20221101 (1.3.0)
* Bugfix - removed forgotten if-then code used with scaling tests.
Majority of users won't notice a difference since most FontForge
fonts are created in the +x,+y quadrant. Users that might see a
change/difference are users drawing only in the -x, -y quadrant.
* Enhanced libspiro to allow closed-loop spiros starting with '['
or 'a' by seeking the first available 'v', 'c', or 'o' as start,
which may be found later in the spiro curve. This was the least
modification needed to allow call-test10 or call-test11 to pass.

- 2022-Jul-22
* Libspiro Version 20220722 (1.2.0)
* Due to confusion created when ppedit was also re-licensed as MIT
Expand Down
6 changes: 3 additions & 3 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_PREREQ([2.64])
#-------------------------------------------
# PackageTimestamp version
m4_define([spiro_package_stamp], [20220722])
m4_define([spiro_package_stamp], [20221101])
#-------------------------------------------
# Making point releases:
# spiro_major_version += 0;
Expand All @@ -21,7 +21,7 @@ m4_define([spiro_package_stamp], [20220722])
# spiro_minor_version = 0;
#
m4_define([spiro_major_version], [1])
m4_define([spiro_minor_version], [2])
m4_define([spiro_minor_version], [3])
m4_define([spiro_version],[spiro_major_version.spiro_minor_version])

#-------------------------------------------
Expand All @@ -45,7 +45,7 @@ m4_define([spiro_version],[spiro_major_version.spiro_minor_version])
# spiro_age = 0
#
m4_define([spiro_current], [1])
m4_define([spiro_revision],[2])
m4_define([spiro_revision],[3])
m4_define([spiro_age], [0])
m4_define([spiro_libver],[spiro_current:spiro_revision:spiro_age])

Expand Down
46 changes: 35 additions & 11 deletions spiro.c
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,6 @@ setup_path0(const spiro_cp *src, double *dm, int n)
dm[1] /* xoff */ = (xmin + xmax) / 2; xmax -= xmin;
dm[2] /* yoff */ = (ymin + ymax) / 2; ymax -= ymin;
dm[0] /* scale */ = fabs((fabs(xmax) >= fabs(ymax)) ? xmax : ymax);
if (xmax >= ymax) dm[0] = xmax; else dm[0] = ymax;
dm[0] /* scale */ /= 500.; /* ~ backward compatible */
}
#ifdef VERBOSE
Expand Down Expand Up @@ -786,6 +785,7 @@ add_mat_line(bandmat *m, double *v,double derivs[4],
int joff, k;

if (jj >= 0) {
jj %= nmat;
joff = (j + 5 - jj + nmat) % nmat;
if (nmat < 6) {
joff = j + 5 - jj;
Expand Down Expand Up @@ -819,14 +819,36 @@ spiro_iter(spiro_seg *s, bandmat *m, int *perm, double *v, int *jinca, int n, in
m[i].al[j] = 0.;
}

j = 0;
i = j = jj = 0;
if (s[0].ty == 'o')
jj = nmat - 2;
else if (s[0].ty == 'c')
jj = nmat - 1;
else
jj = 0;
for (i = 0; i < n; i++) {
else if (s[0].ty == '[' || s[0].ty == 'a') {
if (cyclic) {
/* start at v, c or o */
for (i = 0; i < n; i++) {
switch (s[i].ty) {
case 'o':
--jj;
case 'c':
--jj;
case 'v':
jj = (jj + nmat) % nmat;
j %= nmat;
goto spiro_iter_1;
break;
default:
jj += jinca[i];
j += jinca[i];
}
}
i = j = jj = 0;
spiro_iter_1: ;
}
}
for (k = 0; k < n; i++, k++) {
i %= n;
ty0 = s[i].ty;
ty1 = s[i + 1].ty;
jinc = jinca[i];
Expand All @@ -840,6 +862,7 @@ spiro_iter(spiro_seg *s, bandmat *m, int *perm, double *v, int *jinca, int n, in
if (ty0 == 'o' || ty0 == 'c' || ty0 == '[' || ty0 == ']' || \
ty0 == 'a' || ty0 == 'h') {
jthl = jj++;
jthl %= nmat;
jj %= nmat;
jk0l = jj++;
if (ty0 == 'o') {
Expand Down Expand Up @@ -869,6 +892,7 @@ spiro_iter(spiro_seg *s, bandmat *m, int *perm, double *v, int *jinca, int n, in
/* constraints crossing right */
if (ty1 == 'o' || ty1 == 'c' || ty1 == '[' || ty1 == ']' || \
ty1 == 'a' || ty1 == 'h') {
jj %= nmat;
jthr = jj;
jk0r = (jj + 1) % nmat;
if (ty1 == 'o') {
Expand All @@ -890,6 +914,7 @@ spiro_iter(spiro_seg *s, bandmat *m, int *perm, double *v, int *jinca, int n, in
if (jthr >= 0)
v[jthr] = mod_2pi(v[jthr]);
j += jinc;
j %= nmat;
}
if (cyclic) {
l = sizeof(bandmat) * (unsigned int)(nmat);
Expand Down Expand Up @@ -1299,13 +1324,12 @@ spiro_to_bpath0(const spiro_cp *src, const spiro_seg *s,
di[0] = 1.; /* default cubic to bezier bend */

lk = (ncq & SPIRO_INCLUDE_LAST_KNOT) && s[n - 1].ty == '}' ? 1 : 0;
if ( (ncq & SPIRO_INTERNAL_BEZCTX) ) {
if ( (ncq & SPIRO_INTERNAL_BEZCTX)==0 && \
(bc->moveto==NULL || bc->lineto==NULL || bc->quadto==NULL || \
bc->curveto==NULL || bc->mark_knot==NULL) )
return 0;
if ( (ncq & SPIRO_INTERNAL_BEZCTX) )
si = 1;
} else
else if ( (bc->moveto==NULL || bc->lineto==NULL || bc->quadto==NULL || \
bc->curveto==NULL || bc->mark_knot==NULL) )
return 0;
else
si = 0;

if ( (ncq &= SPIRO_ARC_CUB_QUAD_MASK)==0 ) {
Expand Down
58 changes: 18 additions & 40 deletions tests/call-test.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,7 @@ rs_check_vals verify_rs9[] = { /* iteration9 */
{-1.570796, 141.421356, 2.356194} /* o, 0,-100 */
};

/* test path10[] path11[] using '[]' instead of 'ah'. */
#define TEST_10_11 1
rs_check_vals verify_rs10[] = { /* iteration4 */
#ifndef TEST_10_11
{-0.233743, 50.000000, -1.570796}, /* a,100, 0 */
{-0.484478, 214.709106, -2.055274}, /* h,100, -50 */
{-0.986650, 50.249378, -3.041924}, /* a, 0,-190 */
Expand All @@ -155,39 +152,18 @@ rs_check_vals verify_rs10[] = { /* iteration4 */
{-0.522523, 219.317122, 1.147942}, /* h,-95, 50 */
{-0.950547, 50.990195, 0.197396}, /* o, 0, 200 */
{-1.534449, 215.870331, -1.337053} /* o, 50, 210 */
#else
{-0.256151, 50.000000, -1.570796}, /* [,100, 0 */
{-0.484478, 214.709106, -2.055274}, /* ],100, -50 */
{-0.986650, 50.249378, -3.041924}, /* a, 0,-240 */
{-1.228091, 210.237960, 2.013171}, /* h,-50,-245 */
{-0.342706, 50.249378, 1.670465}, /* [,-90, -50 */
{-0.522523, 219.317, 1.14794}, /* ],-95, 0 */
{-0.950547, 50.990195, 0.197396}, /* o, -5, 200 */
{-1.512041, 217.082933, -1.314645} /* o, 45, 210 */
#endif
};

rs_check_vals verify_rs11[] = { /* iteration4 */
#ifndef TEST_10_11
{-0.233743, 50.000000, -1.570796}, /* a,100, 0 */
{-0.484478, 214.709106, -2.055274}, /* h,100, -50 */
{-0.986650, 50.249378, -3.041924}, /* a, 0,-190 */
{-1.228091, 210.237960, 2.013171}, /* h,-50,-195 */
{-0.342706, 50.249378, 1.670465}, /* a,-90, 0 */
{-0.522523, 219.317122, 1.147942}, /* h,-95, 50 */
{-0.950547, 50.990195, 0.197396}, /* o, 0, 200 */
{-1.534449, 215.870331, -1.337053} /* o, 50, 210 */
#else
{-0.256151, 50.000000, -1.570796}, /* [,100, 0 */
{-0.484478, 214.709106, -2.055274}, /* ],100, -50 */
{-0.986650, 50.249378, -3.041924}, /* a, 0,-240 */
{-1.228091, 210.237960, 2.013171}, /* h,-50,-245 */
{-0.342706, 50.249378, 1.670465}, /* [,-90, -50 */
{-0.522523, 219.317122, 1.147942}, /* ],-95, 0 */
{-0.950547, 50.990195, 0.197396}, /* o, -5, 200 */
{-1.512041, 217.0829933, -1.314645} /* o, 45, 210 */
#endif
}; /* a,100, 0 */
{-1.512041, 217.082933, -1.314645} /* o, 45, 210 */
};

rs_check_vals verify_rs13[] = { /* iteration4 */
{ 0.000000, 50.000000, -1.570796}, /* {,100, 0 */
Expand Down Expand Up @@ -327,7 +303,6 @@ void load_test_curve(spiro_cp *spiro, int *nextknot, int c) {
1, 1, 5, 5, 6, 3, 0, 0, 0
};
spiro_cp path10[] = { /* start loop with ah curves */
#ifndef TEST_10_11
{100, 0, 'a'},
{100, -50, 'h'},
{ 0,-190, 'a'},
Expand All @@ -336,7 +311,11 @@ void load_test_curve(spiro_cp *spiro, int *nextknot, int c) {
{-95, 50, 'h'},
{ 0, 200, 'o'},
{ 50, 210, 'o'}
#else
};
int knot10[] = {
5, 6, 3, 1, 1, 5, 0, 0
};
spiro_cp path11[] = { /* start loop with [] curves */
{100, 0, '['},
{100, -50, ']'},
{ 0,-240, 'a'},
Expand All @@ -345,9 +324,8 @@ void load_test_curve(spiro_cp *spiro, int *nextknot, int c) {
{-95, 0, ']'},
{ -5, 200, 'o'},
{ 45, 210, 'o'}
#endif
};
int knot10[] = {
int knot11[] = {
5, 6, 3, 1, 1, 5, 0, 0
};
spiro_cp path13[] = { /* start open curve using {h */
Expand Down Expand Up @@ -428,12 +406,18 @@ void load_test_curve(spiro_cp *spiro, int *nextknot, int c) {
spiro[i].y = path4[i].y;
spiro[i].ty = path4[i].ty;
nextknot[i] = knot4[i];
} else if ( c==10 || c==11 ) for (i = 0; i < 8; i++) {
/* path10[]_co[10]=closedcurve, path11[]_co[10]=opencurve */
} else if ( c==10 ) for (i = 0; i < 8; i++) {
/* path10[] is a closed loop starting with ah */
spiro[i].x = path10[i].x;
spiro[i].y = path10[i].y;
spiro[i].ty = path10[i].ty;
nextknot[i] = knot10[i];
} else if ( c==11 ) for (i = 0; i < 8; i++) {
/* path11[] is an open curve starting with [] */
spiro[i].x = path11[i].x;
spiro[i].y = path11[i].y;
spiro[i].ty = path11[i].ty;
nextknot[i] = knot11[i];
} else if ( c==12 ) for (i = 0; i < 9; i++) {
/* call_test12 checks curve ending in ah with following z */
/* and declare cl[12] len=8 so run_spiro() can work okay. */
Expand Down Expand Up @@ -1181,16 +1165,10 @@ int main(int argc, char **argv) {
ret=test_curve(9); /* path4[] as a closed curve. */
#endif
#ifdef DO_CALL_TEST10
/* TODO: see why can start using c, o, but not [. */
/* TODO: see why can start using c, o, but not a. */
ret=test_curve(10); /* start loop with ah curves. */
ret = 0; /* ignore result for now until improved. */
#endif
#ifdef DO_CALL_TEST11
/* TODO: see why can start using c, o, but not [. */
/* TODO: see why can start using c, o, but not a. */
ret=test_curve(11); /* start open curve using ah. */
ret = 0; /* ignore result for now until improved. */
ret=test_curve(11); /* start open curve using []. */
#endif
#ifdef DO_CALL_TEST12
ret=test_curve(12); /* do path7[] with a z ending */
Expand All @@ -1208,7 +1186,7 @@ int main(int argc, char **argv) {
ret=test_curve(16); /* testing arc output path4[] */
#endif
#ifdef DO_CALL_TEST17
ret=test_curve(17); /* do arc closed curve outut. */
ret=test_curve(17); /* do arc closed curve output */
#endif
#ifdef DO_CALL_TEST18
ret=test_curve(18); /* do iterative as arc output */
Expand Down
2 changes: 1 addition & 1 deletion tests/call-test10.c
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
#define DO_CALL_TEST10 1
#define DO_CALL_TEST10
#include "call-test.c"
2 changes: 1 addition & 1 deletion tests/call-test11.c
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
#define DO_CALL_TEST11 1
#define DO_CALL_TEST11
#include "call-test.c"
12 changes: 6 additions & 6 deletions tests/call-test21.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,13 +259,13 @@ int main(int argc, char **argv) {
if ( ret ) {
printf("error: show_results() had wrong curve type.\n");
free_ls_bezctx(bc);
return -2;
return -3;
}
ret = verify_results(bc, 0);
if ( ret ) {
printf("error: verify_results() did not match with expected values.\n");
free_ls_bezctx(bc);
return -3;
return -4;
}

/* Resize/release/keep old array, or start a new array
Expand All @@ -283,25 +283,25 @@ int main(int argc, char **argv) {
if ( ret==0 ) {
printf("error: TaggedSpiroCPsToBezier2() failed to build quadratic curve.\n");
free_ls_bezctx(bc);
return -4;
return -5;
}
printf("show: resulting quadratic curve using test0 spiro array\n");
ret = show_results(bc);
if ( ret ) {
printf("error: show_results() had wrong curve type.\n");
free_ls_bezctx(bc);
return -5;
return -6;
}
ret = verify_results(bc, 1);
if ( ret ) {
printf("error: verify_results() did not match with expected values.\n");
free_ls_bezctx(bc);
return -6;
return -7;
}
printf("pass: results matches expected values\n");

free_ls_bezctx(bc);

printf("done.\n");
return 0;
}
}

0 comments on commit 0d87bd2

Please sign in to comment.