You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1554 lines
38 KiB

  1. /* Copyright (C) 2001-2017 Peter Selinger.
  2. * This file is part of Potrace. It is free software and it is covered
  3. * by the GNU General Public License. See the file COPYING for details. */
  4. /* transform jaggy paths into smooth curves */
  5. #ifdef HAVE_CONFIG_H
  6. #include <config.h>
  7. #endif
  8. #include <math.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include "auxiliary.h"
  13. #include "curve.h"
  14. #include "lists.h"
  15. #include "potracelib.h"
  16. #include "progress.h"
  17. #include "trace.h"
  18. #define INFTY \
  19. 10000000 /* it suffices that this is longer than any
  20. * path; it need not be really infinite */
  21. #define COS179 -0.999847695156 /* the cosine of 179 degrees */
  22. /* ---------------------------------------------------------------------- */
  23. #define SAFE_CALLOC( var, n, typ ) \
  24. if( ( var = (typ*) calloc( n, sizeof( typ ) ) ) == NULL ) \
  25. goto calloc_error
  26. /* ---------------------------------------------------------------------- */
  27. /* auxiliary functions */
  28. /* return a direction that is 90 degrees counterclockwise from p2-p0,
  29. * but then restricted to one of the major wind directions (n, nw, w, etc) */
  30. static inline point_t dorth_infty( dpoint_t p0, dpoint_t p2 )
  31. {
  32. point_t r;
  33. r.y = sign( p2.x - p0.x );
  34. r.x = -sign( p2.y - p0.y );
  35. return r;
  36. }
  37. /* return (p1-p0)x(p2-p0), the area of the parallelogram */
  38. static inline double dpara( dpoint_t p0, dpoint_t p1, dpoint_t p2 )
  39. {
  40. double x1, y1, x2, y2;
  41. x1 = p1.x - p0.x;
  42. y1 = p1.y - p0.y;
  43. x2 = p2.x - p0.x;
  44. y2 = p2.y - p0.y;
  45. return x1 * y2 - x2 * y1;
  46. }
  47. /* ddenom/dpara have the property that the square of radius 1 centered
  48. * at p1 intersects the line p0p2 iff |dpara(p0,p1,p2)| <= ddenom(p0,p2) */
  49. static inline double ddenom( dpoint_t p0, dpoint_t p2 )
  50. {
  51. point_t r = dorth_infty( p0, p2 );
  52. return r.y * ( p2.x - p0.x ) - r.x * ( p2.y - p0.y );
  53. }
  54. /* return 1 if a <= b < c < a, in a cyclic sense (mod n) */
  55. static inline int cyclic( int a, int b, int c )
  56. {
  57. if( a <= c )
  58. {
  59. return a <= b && b < c;
  60. }
  61. else
  62. {
  63. return a <= b || b < c;
  64. }
  65. }
  66. /* determine the center and slope of the line i..j. Assume i<j. Needs
  67. * "sum" components of p to be set. */
  68. static void pointslope( privpath_t* pp, int i, int j, dpoint_t* ctr, dpoint_t* dir )
  69. {
  70. /* assume i<j */
  71. int n = pp->len;
  72. sums_t* sums = pp->sums;
  73. double x, y, x2, xy, y2;
  74. double k;
  75. double a, b, c, lambda2, l;
  76. int r = 0; /* rotations from i to j */
  77. while( j >= n )
  78. {
  79. j -= n;
  80. r += 1;
  81. }
  82. while( i >= n )
  83. {
  84. i -= n;
  85. r -= 1;
  86. }
  87. while( j < 0 )
  88. {
  89. j += n;
  90. r -= 1;
  91. }
  92. while( i < 0 )
  93. {
  94. i += n;
  95. r += 1;
  96. }
  97. x = sums[j + 1].x - sums[i].x + r * sums[n].x;
  98. y = sums[j + 1].y - sums[i].y + r * sums[n].y;
  99. x2 = sums[j + 1].x2 - sums[i].x2 + r * sums[n].x2;
  100. xy = sums[j + 1].xy - sums[i].xy + r * sums[n].xy;
  101. y2 = sums[j + 1].y2 - sums[i].y2 + r * sums[n].y2;
  102. k = j + 1 - i + r * n;
  103. ctr->x = x / k;
  104. ctr->y = y / k;
  105. a = ( x2 - (double) x * x / k ) / k;
  106. b = ( xy - (double) x * y / k ) / k;
  107. c = ( y2 - (double) y * y / k ) / k;
  108. lambda2 = ( a + c + sqrt( ( a - c ) * ( a - c ) + 4 * b * b ) ) / 2; /* larger e.value */
  109. /* now find e.vector for lambda2 */
  110. a -= lambda2;
  111. c -= lambda2;
  112. if( fabs( a ) >= fabs( c ) )
  113. {
  114. l = sqrt( a * a + b * b );
  115. if( l != 0 )
  116. {
  117. dir->x = -b / l;
  118. dir->y = a / l;
  119. }
  120. }
  121. else
  122. {
  123. l = sqrt( c * c + b * b );
  124. if( l != 0 )
  125. {
  126. dir->x = -c / l;
  127. dir->y = b / l;
  128. }
  129. }
  130. if( l == 0 )
  131. {
  132. dir->x = dir->y = 0; /* sometimes this can happen when k=4:
  133. * the two eigenvalues coincide */
  134. }
  135. }
  136. /* the type of (affine) quadratic forms, represented as symmetric 3x3
  137. * matrices. The value of the quadratic form at a vector (x,y) is v^t
  138. * Q v, where v = (x,y,1)^t. */
  139. typedef double quadform_t[3][3];
  140. /* Apply quadratic form Q to vector w = (w.x,w.y) */
  141. static inline double quadform( quadform_t Q, dpoint_t w )
  142. {
  143. double v[3];
  144. int i, j;
  145. double sum;
  146. v[0] = w.x;
  147. v[1] = w.y;
  148. v[2] = 1;
  149. sum = 0.0;
  150. for( i = 0; i < 3; i++ )
  151. {
  152. for( j = 0; j < 3; j++ )
  153. {
  154. sum += v[i] * Q[i][j] * v[j];
  155. }
  156. }
  157. return sum;
  158. }
  159. /* calculate p1 x p2 */
  160. static inline int xprod( point_t p1, point_t p2 )
  161. {
  162. return p1.x * p2.y - p1.y * p2.x;
  163. }
  164. /* calculate (p1-p0)x(p3-p2) */
  165. static inline double cprod( dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3 )
  166. {
  167. double x1, y1, x2, y2;
  168. x1 = p1.x - p0.x;
  169. y1 = p1.y - p0.y;
  170. x2 = p3.x - p2.x;
  171. y2 = p3.y - p2.y;
  172. return x1 * y2 - x2 * y1;
  173. }
  174. /* calculate (p1-p0)*(p2-p0) */
  175. static inline double iprod( dpoint_t p0, dpoint_t p1, dpoint_t p2 )
  176. {
  177. double x1, y1, x2, y2;
  178. x1 = p1.x - p0.x;
  179. y1 = p1.y - p0.y;
  180. x2 = p2.x - p0.x;
  181. y2 = p2.y - p0.y;
  182. return x1 * x2 + y1 * y2;
  183. }
  184. /* calculate (p1-p0)*(p3-p2) */
  185. static inline double iprod1( dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3 )
  186. {
  187. double x1, y1, x2, y2;
  188. x1 = p1.x - p0.x;
  189. y1 = p1.y - p0.y;
  190. x2 = p3.x - p2.x;
  191. y2 = p3.y - p2.y;
  192. return x1 * x2 + y1 * y2;
  193. }
  194. /* calculate distance between two points */
  195. static inline double ddist( dpoint_t p, dpoint_t q )
  196. {
  197. return sqrt( sq( p.x - q.x ) + sq( p.y - q.y ) );
  198. }
  199. /* calculate point of a bezier curve */
  200. static inline dpoint_t bezier( double t, dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3 )
  201. {
  202. double s = 1 - t;
  203. dpoint_t res;
  204. /* Note: a good optimizing compiler (such as gcc-3) reduces the
  205. * following to 16 multiplications, using common subexpression
  206. * elimination. */
  207. res.x = s * s * s * p0.x + 3 * ( s * s * t ) * p1.x + 3 * ( t * t * s ) * p2.x
  208. + t * t * t * p3.x;
  209. res.y = s * s * s * p0.y + 3 * ( s * s * t ) * p1.y + 3 * ( t * t * s ) * p2.y
  210. + t * t * t * p3.y;
  211. return res;
  212. }
  213. /* calculate the point t in [0..1] on the (convex) bezier curve
  214. * (p0,p1,p2,p3) which is tangent to q1-q0. Return -1.0 if there is no
  215. * solution in [0..1]. */
  216. static double tangent( dpoint_t p0, dpoint_t p1, dpoint_t p2, dpoint_t p3, dpoint_t q0,
  217. dpoint_t q1 )
  218. {
  219. double A, B, C; /* (1-t)^2 A + 2(1-t)t B + t^2 C = 0 */
  220. double a, b, c; /* a t^2 + b t + c = 0 */
  221. double d, s, r1, r2;
  222. A = cprod( p0, p1, q0, q1 );
  223. B = cprod( p1, p2, q0, q1 );
  224. C = cprod( p2, p3, q0, q1 );
  225. a = A - 2 * B + C;
  226. b = -2 * A + 2 * B;
  227. c = A;
  228. d = b * b - 4 * a * c;
  229. if( a == 0 || d < 0 )
  230. {
  231. return -1.0;
  232. }
  233. s = sqrt( d );
  234. r1 = ( -b + s ) / ( 2 * a );
  235. r2 = ( -b - s ) / ( 2 * a );
  236. if( r1 >= 0 && r1 <= 1 )
  237. {
  238. return r1;
  239. }
  240. else if( r2 >= 0 && r2 <= 1 )
  241. {
  242. return r2;
  243. }
  244. else
  245. {
  246. return -1.0;
  247. }
  248. }
  249. /* ---------------------------------------------------------------------- */
  250. /* Preparation: fill in the sum* fields of a path (used for later
  251. * rapid summing). Return 0 on success, 1 with errno set on
  252. * failure. */
  253. static int calc_sums( privpath_t* pp )
  254. {
  255. int i, x, y;
  256. int n = pp->len;
  257. SAFE_CALLOC( pp->sums, pp->len + 1, sums_t );
  258. /* origin */
  259. pp->x0 = pp->pt[0].x;
  260. pp->y0 = pp->pt[0].y;
  261. /* preparatory computation for later fast summing */
  262. pp->sums[0].x2 = pp->sums[0].xy = pp->sums[0].y2 = pp->sums[0].x = pp->sums[0].y = 0;
  263. for( i = 0; i < n; i++ )
  264. {
  265. x = pp->pt[i].x - pp->x0;
  266. y = pp->pt[i].y - pp->y0;
  267. pp->sums[i + 1].x = pp->sums[i].x + x;
  268. pp->sums[i + 1].y = pp->sums[i].y + y;
  269. pp->sums[i + 1].x2 = pp->sums[i].x2 + (double) x * x;
  270. pp->sums[i + 1].xy = pp->sums[i].xy + (double) x * y;
  271. pp->sums[i + 1].y2 = pp->sums[i].y2 + (double) y * y;
  272. }
  273. return 0;
  274. calloc_error:
  275. return 1;
  276. }
  277. /* ---------------------------------------------------------------------- */
  278. /* Stage 1: determine the straight subpaths (Sec. 2.2.1). Fill in the
  279. * "lon" component of a path object (based on pt/len). For each i,
  280. * lon[i] is the furthest index such that a straight line can be drawn
  281. * from i to lon[i]. Return 1 on error with errno set, else 0. */
  282. /* this algorithm depends on the fact that the existence of straight
  283. * subpaths is a triplewise property. I.e., there exists a straight
  284. * line through squares i0,...,in iff there exists a straight line
  285. * through i,j,k, for all i0<=i<j<k<=in. (Proof?) */
  286. /* this implementation of calc_lon is O(n^2). It replaces an older
  287. * O(n^3) version. A "constraint" means that future points must
  288. * satisfy xprod(constraint[0], cur) >= 0 and xprod(constraint[1],
  289. * cur) <= 0. */
  290. /* Remark for Potrace 1.1: the current implementation of calc_lon is
  291. * more complex than the implementation found in Potrace 1.0, but it
  292. * is considerably faster. The introduction of the "nc" data structure
  293. * means that we only have to test the constraints for "corner"
  294. * points. On a typical input file, this speeds up the calc_lon
  295. * function by a factor of 31.2, thereby decreasing its time share
  296. * within the overall Potrace algorithm from 72.6% to 7.82%, and
  297. * speeding up the overall algorithm by a factor of 3.36. On another
  298. * input file, calc_lon was sped up by a factor of 6.7, decreasing its
  299. * time share from 51.4% to 13.61%, and speeding up the overall
  300. * algorithm by a factor of 1.78. In any case, the savings are
  301. * substantial. */
  302. /* returns 0 on success, 1 on error with errno set */
  303. static int calc_lon( privpath_t* pp )
  304. {
  305. point_t* pt = pp->pt;
  306. int n = pp->len;
  307. int i, j, k, k1;
  308. int ct[4], dir;
  309. point_t constraint[2];
  310. point_t cur;
  311. point_t off;
  312. int* pivk = NULL; /* pivk[n] */
  313. int* nc = NULL; /* nc[n]: next corner */
  314. point_t dk; /* direction of k-k1 */
  315. int a, b, c, d;
  316. SAFE_CALLOC( pivk, n, int );
  317. SAFE_CALLOC( nc, n, int );
  318. /* initialize the nc data structure. Point from each point to the
  319. * furthest future point to which it is connected by a vertical or
  320. * horizontal segment. We take advantage of the fact that there is
  321. * always a direction change at 0 (due to the path decomposition
  322. * algorithm). But even if this were not so, there is no harm, as
  323. * in practice, correctness does not depend on the word "furthest"
  324. * above. */
  325. k = 0;
  326. for( i = n - 1; i >= 0; i-- )
  327. {
  328. if( pt[i].x != pt[k].x && pt[i].y != pt[k].y )
  329. {
  330. k = i + 1; /* necessarily i<n-1 in this case */
  331. }
  332. nc[i] = k;
  333. }
  334. SAFE_CALLOC( pp->lon, n, int );
  335. /* determine pivot points: for each i, let pivk[i] be the furthest k
  336. * such that all j with i<j<k lie on a line connecting i,k. */
  337. for( i = n - 1; i >= 0; i-- )
  338. {
  339. ct[0] = ct[1] = ct[2] = ct[3] = 0;
  340. /* keep track of "directions" that have occurred */
  341. dir = ( 3 + 3 * ( pt[mod( i + 1, n )].x - pt[i].x ) + ( pt[mod( i + 1, n )].y - pt[i].y ) )
  342. / 2;
  343. ct[dir]++;
  344. constraint[0].x = 0;
  345. constraint[0].y = 0;
  346. constraint[1].x = 0;
  347. constraint[1].y = 0;
  348. /* find the next k such that no straight line from i to k */
  349. k = nc[i];
  350. k1 = i;
  351. while( 1 )
  352. {
  353. dir = ( 3 + 3 * sign( pt[k].x - pt[k1].x ) + sign( pt[k].y - pt[k1].y ) ) / 2;
  354. ct[dir]++;
  355. /* if all four "directions" have occurred, cut this path */
  356. if( ct[0] && ct[1] && ct[2] && ct[3] )
  357. {
  358. pivk[i] = k1;
  359. goto foundk;
  360. }
  361. cur.x = pt[k].x - pt[i].x;
  362. cur.y = pt[k].y - pt[i].y;
  363. /* see if current constraint is violated */
  364. if( xprod( constraint[0], cur ) < 0 || xprod( constraint[1], cur ) > 0 )
  365. {
  366. goto constraint_viol;
  367. }
  368. /* else, update constraint */
  369. if( abs( cur.x ) <= 1 && abs( cur.y ) <= 1 )
  370. {
  371. /* no constraint */
  372. }
  373. else
  374. {
  375. off.x = cur.x + ( ( cur.y >= 0 && ( cur.y > 0 || cur.x < 0 ) ) ? 1 : -1 );
  376. off.y = cur.y + ( ( cur.x <= 0 && ( cur.x < 0 || cur.y < 0 ) ) ? 1 : -1 );
  377. if( xprod( constraint[0], off ) >= 0 )
  378. {
  379. constraint[0] = off;
  380. }
  381. off.x = cur.x + ( ( cur.y <= 0 && ( cur.y < 0 || cur.x < 0 ) ) ? 1 : -1 );
  382. off.y = cur.y + ( ( cur.x >= 0 && ( cur.x > 0 || cur.y < 0 ) ) ? 1 : -1 );
  383. if( xprod( constraint[1], off ) <= 0 )
  384. {
  385. constraint[1] = off;
  386. }
  387. }
  388. k1 = k;
  389. k = nc[k1];
  390. if( !cyclic( k, i, k1 ) )
  391. {
  392. break;
  393. }
  394. }
  395. constraint_viol:
  396. /* k1 was the last "corner" satisfying the current constraint, and
  397. * k is the first one violating it. We now need to find the last
  398. * point along k1..k which satisfied the constraint. */
  399. dk.x = sign( pt[k].x - pt[k1].x );
  400. dk.y = sign( pt[k].y - pt[k1].y );
  401. cur.x = pt[k1].x - pt[i].x;
  402. cur.y = pt[k1].y - pt[i].y;
  403. /* find largest integer j such that xprod(constraint[0], cur+j*dk)
  404. * >= 0 and xprod(constraint[1], cur+j*dk) <= 0. Use bilinearity
  405. * of xprod. */
  406. a = xprod( constraint[0], cur );
  407. b = xprod( constraint[0], dk );
  408. c = xprod( constraint[1], cur );
  409. d = xprod( constraint[1], dk );
  410. /* find largest integer j such that a+j*b>=0 and c+j*d<=0. This
  411. * can be solved with integer arithmetic. */
  412. j = INFTY;
  413. if( b < 0 )
  414. {
  415. j = floordiv( a, -b );
  416. }
  417. if( d > 0 )
  418. {
  419. j = min( j, floordiv( -c, d ) );
  420. }
  421. pivk[i] = mod( k1 + j, n );
  422. foundk:;
  423. } /* for i */
  424. /* clean up: for each i, let lon[i] be the largest k such that for
  425. * all i' with i<=i'<k, i'<k<=pivk[i']. */
  426. j = pivk[n - 1];
  427. pp->lon[n - 1] = j;
  428. for( i = n - 2; i >= 0; i-- )
  429. {
  430. if( cyclic( i + 1, pivk[i], j ) )
  431. {
  432. j = pivk[i];
  433. }
  434. pp->lon[i] = j;
  435. }
  436. for( i = n - 1; cyclic( mod( i + 1, n ), j, pp->lon[i] ); i-- )
  437. {
  438. pp->lon[i] = j;
  439. }
  440. free( pivk );
  441. free( nc );
  442. return 0;
  443. calloc_error:
  444. free( pivk );
  445. free( nc );
  446. return 1;
  447. }
  448. /* ---------------------------------------------------------------------- */
  449. /* Stage 2: calculate the optimal polygon (Sec. 2.2.2-2.2.4). */
  450. /* Auxiliary function: calculate the penalty of an edge from i to j in
  451. * the given path. This needs the "lon" and "sum*" data. */
  452. static double penalty3( privpath_t* pp, int i, int j )
  453. {
  454. int n = pp->len;
  455. point_t* pt = pp->pt;
  456. sums_t* sums = pp->sums;
  457. /* assume 0<=i<j<=n */
  458. double x, y, x2, xy, y2;
  459. double k;
  460. double a, b, c, s;
  461. double px, py, ex, ey;
  462. int r = 0; /* rotations from i to j */
  463. if( j >= n )
  464. {
  465. j -= n;
  466. r = 1;
  467. }
  468. /* critical inner loop: the "if" gives a 4.6 percent speedup */
  469. if( r == 0 )
  470. {
  471. x = sums[j + 1].x - sums[i].x;
  472. y = sums[j + 1].y - sums[i].y;
  473. x2 = sums[j + 1].x2 - sums[i].x2;
  474. xy = sums[j + 1].xy - sums[i].xy;
  475. y2 = sums[j + 1].y2 - sums[i].y2;
  476. k = j + 1 - i;
  477. }
  478. else
  479. {
  480. x = sums[j + 1].x - sums[i].x + sums[n].x;
  481. y = sums[j + 1].y - sums[i].y + sums[n].y;
  482. x2 = sums[j + 1].x2 - sums[i].x2 + sums[n].x2;
  483. xy = sums[j + 1].xy - sums[i].xy + sums[n].xy;
  484. y2 = sums[j + 1].y2 - sums[i].y2 + sums[n].y2;
  485. k = j + 1 - i + n;
  486. }
  487. px = ( pt[i].x + pt[j].x ) / 2.0 - pt[0].x;
  488. py = ( pt[i].y + pt[j].y ) / 2.0 - pt[0].y;
  489. ey = ( pt[j].x - pt[i].x );
  490. ex = -( pt[j].y - pt[i].y );
  491. a = ( ( x2 - 2 * x * px ) / k + px * px );
  492. b = ( ( xy - x * py - y * px ) / k + px * py );
  493. c = ( ( y2 - 2 * y * py ) / k + py * py );
  494. s = ex * ex * a + 2 * ex * ey * b + ey * ey * c;
  495. return sqrt( s );
  496. }
  497. /* find the optimal polygon. Fill in the m and po components. Return 1
  498. * on failure with errno set, else 0. Non-cyclic version: assumes i=0
  499. * is in the polygon. Fixme: implement cyclic version. */
  500. static int bestpolygon( privpath_t* pp )
  501. {
  502. int i, j, m, k;
  503. int n = pp->len;
  504. double* pen = NULL; /* pen[n+1]: penalty vector */
  505. int* prev = NULL; /* prev[n+1]: best path pointer vector */
  506. int* clip0 = NULL; /* clip0[n]: longest segment pointer, non-cyclic */
  507. int* clip1 = NULL; /* clip1[n+1]: backwards segment pointer, non-cyclic */
  508. int* seg0 = NULL; /* seg0[m+1]: forward segment bounds, m<=n */
  509. int* seg1 = NULL; /* seg1[m+1]: backward segment bounds, m<=n */
  510. double thispen;
  511. double best;
  512. int c;
  513. SAFE_CALLOC( pen, n + 1, double );
  514. SAFE_CALLOC( prev, n + 1, int );
  515. SAFE_CALLOC( clip0, n, int );
  516. SAFE_CALLOC( clip1, n + 1, int );
  517. SAFE_CALLOC( seg0, n + 1, int );
  518. SAFE_CALLOC( seg1, n + 1, int );
  519. /* calculate clipped paths */
  520. for( i = 0; i < n; i++ )
  521. {
  522. c = mod( pp->lon[mod( i - 1, n )] - 1, n );
  523. if( c == i )
  524. {
  525. c = mod( i + 1, n );
  526. }
  527. if( c < i )
  528. {
  529. clip0[i] = n;
  530. }
  531. else
  532. {
  533. clip0[i] = c;
  534. }
  535. }
  536. /* calculate backwards path clipping, non-cyclic. j <= clip0[i] iff
  537. * clip1[j] <= i, for i,j=0..n. */
  538. j = 1;
  539. for( i = 0; i < n; i++ )
  540. {
  541. while( j <= clip0[i] )
  542. {
  543. clip1[j] = i;
  544. j++;
  545. }
  546. }
  547. /* calculate seg0[j] = longest path from 0 with j segments */
  548. i = 0;
  549. for( j = 0; i < n; j++ )
  550. {
  551. seg0[j] = i;
  552. i = clip0[i];
  553. }
  554. seg0[j] = n;
  555. m = j;
  556. /* calculate seg1[j] = longest path to n with m-j segments */
  557. i = n;
  558. for( j = m; j > 0; j-- )
  559. {
  560. seg1[j] = i;
  561. i = clip1[i];
  562. }
  563. seg1[0] = 0;
  564. /* now find the shortest path with m segments, based on penalty3 */
  565. /* note: the outer 2 loops jointly have at most n iterations, thus
  566. * the worst-case behavior here is quadratic. In practice, it is
  567. * close to linear since the inner loop tends to be short. */
  568. pen[0] = 0;
  569. for( j = 1; j <= m; j++ )
  570. {
  571. for( i = seg1[j]; i <= seg0[j]; i++ )
  572. {
  573. best = -1;
  574. for( k = seg0[j - 1]; k >= clip1[i]; k-- )
  575. {
  576. thispen = penalty3( pp, k, i ) + pen[k];
  577. if( best < 0 || thispen < best )
  578. {
  579. prev[i] = k;
  580. best = thispen;
  581. }
  582. }
  583. pen[i] = best;
  584. }
  585. }
  586. pp->m = m;
  587. SAFE_CALLOC( pp->po, m, int );
  588. /* read off shortest path */
  589. for( i = n, j = m - 1; i > 0; j-- )
  590. {
  591. i = prev[i];
  592. pp->po[j] = i;
  593. }
  594. free( pen );
  595. free( prev );
  596. free( clip0 );
  597. free( clip1 );
  598. free( seg0 );
  599. free( seg1 );
  600. return 0;
  601. calloc_error:
  602. free( pen );
  603. free( prev );
  604. free( clip0 );
  605. free( clip1 );
  606. free( seg0 );
  607. free( seg1 );
  608. return 1;
  609. }
  610. /* ---------------------------------------------------------------------- */
  611. /* Stage 3: vertex adjustment (Sec. 2.3.1). */
  612. /* Adjust vertices of optimal polygon: calculate the intersection of
  613. * the two "optimal" line segments, then move it into the unit square
  614. * if it lies outside. Return 1 with errno set on error; 0 on
  615. * success. */
  616. static int adjust_vertices( privpath_t* pp )
  617. {
  618. int m = pp->m;
  619. int* po = pp->po;
  620. int n = pp->len;
  621. point_t* pt = pp->pt;
  622. int x0 = pp->x0;
  623. int y0 = pp->y0;
  624. dpoint_t* ctr = NULL; /* ctr[m] */
  625. dpoint_t* dir = NULL; /* dir[m] */
  626. quadform_t* q = NULL; /* q[m] */
  627. double v[3];
  628. double d;
  629. int i, j, k, l;
  630. dpoint_t s;
  631. int r;
  632. SAFE_CALLOC( ctr, m, dpoint_t );
  633. SAFE_CALLOC( dir, m, dpoint_t );
  634. SAFE_CALLOC( q, m, quadform_t );
  635. r = privcurve_init( &pp->curve, m );
  636. if( r )
  637. {
  638. goto calloc_error;
  639. }
  640. /* calculate "optimal" point-slope representation for each line
  641. * segment */
  642. for( i = 0; i < m; i++ )
  643. {
  644. j = po[mod( i + 1, m )];
  645. j = mod( j - po[i], n ) + po[i];
  646. pointslope( pp, po[i], j, &ctr[i], &dir[i] );
  647. }
  648. /* represent each line segment as a singular quadratic form; the
  649. * distance of a point (x,y) from the line segment will be
  650. * (x,y,1)Q(x,y,1)^t, where Q=q[i]. */
  651. for( i = 0; i < m; i++ )
  652. {
  653. d = sq( dir[i].x ) + sq( dir[i].y );
  654. if( d == 0.0 )
  655. {
  656. for( j = 0; j < 3; j++ )
  657. {
  658. for( k = 0; k < 3; k++ )
  659. {
  660. q[i][j][k] = 0;
  661. }
  662. }
  663. }
  664. else
  665. {
  666. v[0] = dir[i].y;
  667. v[1] = -dir[i].x;
  668. v[2] = -v[1] * ctr[i].y - v[0] * ctr[i].x;
  669. for( l = 0; l < 3; l++ )
  670. {
  671. for( k = 0; k < 3; k++ )
  672. {
  673. q[i][l][k] = v[l] * v[k] / d;
  674. }
  675. }
  676. }
  677. }
  678. /* now calculate the "intersections" of consecutive segments.
  679. * Instead of using the actual intersection, we find the point
  680. * within a given unit square which minimizes the square distance to
  681. * the two lines. */
  682. for( i = 0; i < m; i++ )
  683. {
  684. quadform_t Q;
  685. dpoint_t w;
  686. double dx, dy;
  687. double det;
  688. double min, cand; /* minimum and candidate for minimum of quad. form */
  689. double xmin, ymin; /* coordinates of minimum */
  690. int z;
  691. /* let s be the vertex, in coordinates relative to x0/y0 */
  692. s.x = pt[po[i]].x - x0;
  693. s.y = pt[po[i]].y - y0;
  694. /* intersect segments i-1 and i */
  695. j = mod( i - 1, m );
  696. /* add quadratic forms */
  697. for( l = 0; l < 3; l++ )
  698. {
  699. for( k = 0; k < 3; k++ )
  700. {
  701. Q[l][k] = q[j][l][k] + q[i][l][k];
  702. }
  703. }
  704. while( 1 )
  705. {
  706. /* minimize the quadratic form Q on the unit square */
  707. /* find intersection */
  708. #ifdef HAVE_GCC_LOOP_BUG
  709. /* work around gcc bug #12243 */
  710. free( NULL );
  711. #endif
  712. det = Q[0][0] * Q[1][1] - Q[0][1] * Q[1][0];
  713. if( det != 0.0 )
  714. {
  715. w.x = ( -Q[0][2] * Q[1][1] + Q[1][2] * Q[0][1] ) / det;
  716. w.y = ( Q[0][2] * Q[1][0] - Q[1][2] * Q[0][0] ) / det;
  717. break;
  718. }
  719. /* matrix is singular - lines are parallel. Add another,
  720. * orthogonal axis, through the center of the unit square */
  721. if( Q[0][0] > Q[1][1] )
  722. {
  723. v[0] = -Q[0][1];
  724. v[1] = Q[0][0];
  725. }
  726. else if( Q[1][1] )
  727. {
  728. v[0] = -Q[1][1];
  729. v[1] = Q[1][0];
  730. }
  731. else
  732. {
  733. v[0] = 1;
  734. v[1] = 0;
  735. }
  736. d = sq( v[0] ) + sq( v[1] );
  737. v[2] = -v[1] * s.y - v[0] * s.x;
  738. for( l = 0; l < 3; l++ )
  739. {
  740. for( k = 0; k < 3; k++ )
  741. {
  742. Q[l][k] += v[l] * v[k] / d;
  743. }
  744. }
  745. }
  746. dx = fabs( w.x - s.x );
  747. dy = fabs( w.y - s.y );
  748. if( dx <= .5 && dy <= .5 )
  749. {
  750. pp->curve.vertex[i].x = w.x + x0;
  751. pp->curve.vertex[i].y = w.y + y0;
  752. continue;
  753. }
  754. /* the minimum was not in the unit square; now minimize quadratic
  755. * on boundary of square */
  756. min = quadform( Q, s );
  757. xmin = s.x;
  758. ymin = s.y;
  759. if( Q[0][0] == 0.0 )
  760. {
  761. goto fixx;
  762. }
  763. for( z = 0; z < 2; z++ )
  764. {
  765. /* value of the y-coordinate */
  766. w.y = s.y - 0.5 + z;
  767. w.x = -( Q[0][1] * w.y + Q[0][2] ) / Q[0][0];
  768. dx = fabs( w.x - s.x );
  769. cand = quadform( Q, w );
  770. if( dx <= .5 && cand < min )
  771. {
  772. min = cand;
  773. xmin = w.x;
  774. ymin = w.y;
  775. }
  776. }
  777. fixx:
  778. if( Q[1][1] == 0.0 )
  779. {
  780. goto corners;
  781. }
  782. for( z = 0; z < 2; z++ )
  783. {
  784. /* value of the x-coordinate */
  785. w.x = s.x - 0.5 + z;
  786. w.y = -( Q[1][0] * w.x + Q[1][2] ) / Q[1][1];
  787. dy = fabs( w.y - s.y );
  788. cand = quadform( Q, w );
  789. if( dy <= .5 && cand < min )
  790. {
  791. min = cand;
  792. xmin = w.x;
  793. ymin = w.y;
  794. }
  795. }
  796. corners:
  797. /* check four corners */
  798. for( l = 0; l < 2; l++ )
  799. {
  800. for( k = 0; k < 2; k++ )
  801. {
  802. w.x = s.x - 0.5 + l;
  803. w.y = s.y - 0.5 + k;
  804. cand = quadform( Q, w );
  805. if( cand < min )
  806. {
  807. min = cand;
  808. xmin = w.x;
  809. ymin = w.y;
  810. }
  811. }
  812. }
  813. pp->curve.vertex[i].x = xmin + x0;
  814. pp->curve.vertex[i].y = ymin + y0;
  815. continue;
  816. }
  817. free( ctr );
  818. free( dir );
  819. free( q );
  820. return 0;
  821. calloc_error:
  822. free( ctr );
  823. free( dir );
  824. free( q );
  825. return 1;
  826. }
  827. /* ---------------------------------------------------------------------- */
  828. /* Stage 4: smoothing and corner analysis (Sec. 2.3.3) */
  829. /* reverse orientation of a path */
  830. static void reverse( privcurve_t* curve )
  831. {
  832. int m = curve->n;
  833. int i, j;
  834. dpoint_t tmp;
  835. for( i = 0, j = m - 1; i < j; i++, j-- )
  836. {
  837. tmp = curve->vertex[i];
  838. curve->vertex[i] = curve->vertex[j];
  839. curve->vertex[j] = tmp;
  840. }
  841. }
  842. /* Always succeeds */
  843. static void smooth( privcurve_t* curve, double alphamax )
  844. {
  845. int m = curve->n;
  846. int i, j, k;
  847. double dd, denom, alpha;
  848. dpoint_t p2, p3, p4;
  849. /* examine each vertex and find its best fit */
  850. for( i = 0; i < m; i++ )
  851. {
  852. j = mod( i + 1, m );
  853. k = mod( i + 2, m );
  854. p4 = interval( 1 / 2.0, curve->vertex[k], curve->vertex[j] );
  855. denom = ddenom( curve->vertex[i], curve->vertex[k] );
  856. if( denom != 0.0 )
  857. {
  858. dd = dpara( curve->vertex[i], curve->vertex[j], curve->vertex[k] ) / denom;
  859. dd = fabs( dd );
  860. alpha = dd > 1 ? ( 1 - 1.0 / dd ) : 0;
  861. alpha = alpha / 0.75;
  862. }
  863. else
  864. {
  865. alpha = 4 / 3.0;
  866. }
  867. curve->alpha0[j] = alpha; /* remember "original" value of alpha */
  868. if( alpha >= alphamax )
  869. {
  870. /* pointed corner */
  871. curve->tag[j] = POTRACE_CORNER;
  872. curve->c[j][1] = curve->vertex[j];
  873. curve->c[j][2] = p4;
  874. }
  875. else
  876. {
  877. if( alpha < 0.55 )
  878. {
  879. alpha = 0.55;
  880. }
  881. else if( alpha > 1 )
  882. {
  883. alpha = 1;
  884. }
  885. p2 = interval( .5 + .5 * alpha, curve->vertex[i], curve->vertex[j] );
  886. p3 = interval( .5 + .5 * alpha, curve->vertex[k], curve->vertex[j] );
  887. curve->tag[j] = POTRACE_CURVETO;
  888. curve->c[j][0] = p2;
  889. curve->c[j][1] = p3;
  890. curve->c[j][2] = p4;
  891. }
  892. curve->alpha[j] = alpha; /* store the "cropped" value of alpha */
  893. curve->beta[j] = 0.5;
  894. }
  895. curve->alphacurve = 1;
  896. }
  897. /* ---------------------------------------------------------------------- */
  898. /* Stage 5: Curve optimization (Sec. 2.4) */
  899. /* a private type for the result of opti_penalty */
  900. struct opti_s
  901. {
  902. double pen; /* penalty */
  903. dpoint_t c[2]; /* curve parameters */
  904. double t, s; /* curve parameters */
  905. double alpha; /* curve parameter */
  906. };
  907. typedef struct opti_s opti_t;
  908. /* calculate best fit from i+.5 to j+.5. Assume i<j (cyclically).
  909. * Return 0 and set badness and parameters (alpha, beta), if
  910. * possible. Return 1 if impossible. */
  911. static int opti_penalty( privpath_t* pp,
  912. int i,
  913. int j,
  914. opti_t* res,
  915. double opttolerance,
  916. int* convc,
  917. double* areac )
  918. {
  919. int m = pp->curve.n;
  920. int k, k1, k2, conv, i1;
  921. double area, alpha, d, d1, d2;
  922. dpoint_t p0, p1, p2, p3, pt;
  923. double A, R, A1, A2, A3, A4;
  924. double s, t;
  925. /* check convexity, corner-freeness, and maximum bend < 179 degrees */
  926. if( i == j )
  927. {
  928. /* sanity - a full loop can never be an opticurve */
  929. return 1;
  930. }
  931. k = i;
  932. i1 = mod( i + 1, m );
  933. k1 = mod( k + 1, m );
  934. conv = convc[k1];
  935. if( conv == 0 )
  936. {
  937. return 1;
  938. }
  939. d = ddist( pp->curve.vertex[i], pp->curve.vertex[i1] );
  940. for( k = k1; k != j; k = k1 )
  941. {
  942. k1 = mod( k + 1, m );
  943. k2 = mod( k + 2, m );
  944. if( convc[k1] != conv )
  945. {
  946. return 1;
  947. }
  948. if( sign( cprod( pp->curve.vertex[i], pp->curve.vertex[i1], pp->curve.vertex[k1],
  949. pp->curve.vertex[k2] ) )
  950. != conv )
  951. {
  952. return 1;
  953. }
  954. if( iprod1( pp->curve.vertex[i], pp->curve.vertex[i1], pp->curve.vertex[k1],
  955. pp->curve.vertex[k2] )
  956. < d * ddist( pp->curve.vertex[k1], pp->curve.vertex[k2] ) * COS179 )
  957. {
  958. return 1;
  959. }
  960. }
  961. /* the curve we're working in: */
  962. p0 = pp->curve.c[mod( i, m )][2];
  963. p1 = pp->curve.vertex[mod( i + 1, m )];
  964. p2 = pp->curve.vertex[mod( j, m )];
  965. p3 = pp->curve.c[mod( j, m )][2];
  966. /* determine its area */
  967. area = areac[j] - areac[i];
  968. area -= dpara( pp->curve.vertex[0], pp->curve.c[i][2], pp->curve.c[j][2] ) / 2;
  969. if( i >= j )
  970. {
  971. area += areac[m];
  972. }
  973. /* find intersection o of p0p1 and p2p3. Let t,s such that o =
  974. * interval(t,p0,p1) = interval(s,p3,p2). Let A be the area of the
  975. * triangle (p0,o,p3). */
  976. A1 = dpara( p0, p1, p2 );
  977. A2 = dpara( p0, p1, p3 );
  978. A3 = dpara( p0, p2, p3 );
  979. /* A4 = dpara(p1, p2, p3); */
  980. A4 = A1 + A3 - A2;
  981. if( A2 == A1 )
  982. {
  983. /* this should never happen */
  984. return 1;
  985. }
  986. t = A3 / ( A3 - A4 );
  987. s = A2 / ( A2 - A1 );
  988. A = A2 * t / 2.0;
  989. if( A == 0.0 )
  990. {
  991. /* this should never happen */
  992. return 1;
  993. }
  994. R = area / A; /* relative area */
  995. alpha = 2 - sqrt( 4 - R / 0.3 ); /* overall alpha for p0-o-p3 curve */
  996. res->c[0] = interval( t * alpha, p0, p1 );
  997. res->c[1] = interval( s * alpha, p3, p2 );
  998. res->alpha = alpha;
  999. res->t = t;
  1000. res->s = s;
  1001. p1 = res->c[0];
  1002. p2 = res->c[1]; /* the proposed curve is now (p0,p1,p2,p3) */
  1003. res->pen = 0;
  1004. /* calculate penalty */
  1005. /* check tangency with edges */
  1006. for( k = mod( i + 1, m ); k != j; k = k1 )
  1007. {
  1008. k1 = mod( k + 1, m );
  1009. t = tangent( p0, p1, p2, p3, pp->curve.vertex[k], pp->curve.vertex[k1] );
  1010. if( t < -.5 )
  1011. {
  1012. return 1;
  1013. }
  1014. pt = bezier( t, p0, p1, p2, p3 );
  1015. d = ddist( pp->curve.vertex[k], pp->curve.vertex[k1] );
  1016. if( d == 0.0 )
  1017. {
  1018. /* this should never happen */
  1019. return 1;
  1020. }
  1021. d1 = dpara( pp->curve.vertex[k], pp->curve.vertex[k1], pt ) / d;
  1022. if( fabs( d1 ) > opttolerance )
  1023. {
  1024. return 1;
  1025. }
  1026. if( iprod( pp->curve.vertex[k], pp->curve.vertex[k1], pt ) < 0
  1027. || iprod( pp->curve.vertex[k1], pp->curve.vertex[k], pt ) < 0 )
  1028. {
  1029. return 1;
  1030. }
  1031. res->pen += sq( d1 );
  1032. }
  1033. /* check corners */
  1034. for( k = i; k != j; k = k1 )
  1035. {
  1036. k1 = mod( k + 1, m );
  1037. t = tangent( p0, p1, p2, p3, pp->curve.c[k][2], pp->curve.c[k1][2] );
  1038. if( t < -.5 )
  1039. {
  1040. return 1;
  1041. }
  1042. pt = bezier( t, p0, p1, p2, p3 );
  1043. d = ddist( pp->curve.c[k][2], pp->curve.c[k1][2] );
  1044. if( d == 0.0 )
  1045. {
  1046. /* this should never happen */
  1047. return 1;
  1048. }
  1049. d1 = dpara( pp->curve.c[k][2], pp->curve.c[k1][2], pt ) / d;
  1050. d2 = dpara( pp->curve.c[k][2], pp->curve.c[k1][2], pp->curve.vertex[k1] ) / d;
  1051. d2 *= 0.75 * pp->curve.alpha[k1];
  1052. if( d2 < 0 )
  1053. {
  1054. d1 = -d1;
  1055. d2 = -d2;
  1056. }
  1057. if( d1 < d2 - opttolerance )
  1058. {
  1059. return 1;
  1060. }
  1061. if( d1 < d2 )
  1062. {
  1063. res->pen += sq( d1 - d2 );
  1064. }
  1065. }
  1066. return 0;
  1067. }
  1068. /* optimize the path p, replacing sequences of Bezier segments by a
  1069. * single segment when possible. Return 0 on success, 1 with errno set
  1070. * on failure. */
  1071. static int opticurve( privpath_t* pp, double opttolerance )
  1072. {
  1073. int m = pp->curve.n;
  1074. int* pt = NULL; /* pt[m+1] */
  1075. double* pen = NULL; /* pen[m+1] */
  1076. int* len = NULL; /* len[m+1] */
  1077. opti_t* opt = NULL; /* opt[m+1] */
  1078. int om;
  1079. int i, j, r;
  1080. opti_t o;
  1081. dpoint_t p0;
  1082. int i1;
  1083. double area;
  1084. double alpha;
  1085. double* s = NULL;
  1086. double* t = NULL;
  1087. int* convc = NULL; /* conv[m]: pre-computed convexities */
  1088. double* areac = NULL; /* cumarea[m+1]: cache for fast area computation */
  1089. SAFE_CALLOC( pt, m + 1, int );
  1090. SAFE_CALLOC( pen, m + 1, double );
  1091. SAFE_CALLOC( len, m + 1, int );
  1092. SAFE_CALLOC( opt, m + 1, opti_t );
  1093. SAFE_CALLOC( convc, m, int );
  1094. SAFE_CALLOC( areac, m + 1, double );
  1095. /* pre-calculate convexity: +1 = right turn, -1 = left turn, 0 = corner */
  1096. for( i = 0; i < m; i++ )
  1097. {
  1098. if( pp->curve.tag[i] == POTRACE_CURVETO )
  1099. {
  1100. convc[i] = sign( dpara( pp->curve.vertex[mod( i - 1, m )], pp->curve.vertex[i],
  1101. pp->curve.vertex[mod( i + 1, m )] ) );
  1102. }
  1103. else
  1104. {
  1105. convc[i] = 0;
  1106. }
  1107. }
  1108. /* pre-calculate areas */
  1109. area = 0.0;
  1110. areac[0] = 0.0;
  1111. p0 = pp->curve.vertex[0];
  1112. for( i = 0; i < m; i++ )
  1113. {
  1114. i1 = mod( i + 1, m );
  1115. if( pp->curve.tag[i1] == POTRACE_CURVETO )
  1116. {
  1117. alpha = pp->curve.alpha[i1];
  1118. area += 0.3 * alpha * ( 4 - alpha )
  1119. * dpara( pp->curve.c[i][2], pp->curve.vertex[i1], pp->curve.c[i1][2] ) / 2;
  1120. area += dpara( p0, pp->curve.c[i][2], pp->curve.c[i1][2] ) / 2;
  1121. }
  1122. areac[i + 1] = area;
  1123. }
  1124. pt[0] = -1;
  1125. pen[0] = 0;
  1126. len[0] = 0;
  1127. /* Fixme: we always start from a fixed point -- should find the best
  1128. * curve cyclically */
  1129. for( j = 1; j <= m; j++ )
  1130. {
  1131. /* calculate best path from 0 to j */
  1132. pt[j] = j - 1;
  1133. pen[j] = pen[j - 1];
  1134. len[j] = len[j - 1] + 1;
  1135. for( i = j - 2; i >= 0; i-- )
  1136. {
  1137. r = opti_penalty( pp, i, mod( j, m ), &o, opttolerance, convc, areac );
  1138. if( r )
  1139. {
  1140. break;
  1141. }
  1142. if( len[j] > len[i] + 1 || ( len[j] == len[i] + 1 && pen[j] > pen[i] + o.pen ) )
  1143. {
  1144. pt[j] = i;
  1145. pen[j] = pen[i] + o.pen;
  1146. len[j] = len[i] + 1;
  1147. opt[j] = o;
  1148. }
  1149. }
  1150. }
  1151. om = len[m];
  1152. r = privcurve_init( &pp->ocurve, om );
  1153. if( r )
  1154. {
  1155. goto calloc_error;
  1156. }
  1157. SAFE_CALLOC( s, om, double );
  1158. SAFE_CALLOC( t, om, double );
  1159. j = m;
  1160. for( i = om - 1; i >= 0; i-- )
  1161. {
  1162. if( pt[j] == j - 1 )
  1163. {
  1164. pp->ocurve.tag[i] = pp->curve.tag[mod( j, m )];
  1165. pp->ocurve.c[i][0] = pp->curve.c[mod( j, m )][0];
  1166. pp->ocurve.c[i][1] = pp->curve.c[mod( j, m )][1];
  1167. pp->ocurve.c[i][2] = pp->curve.c[mod( j, m )][2];
  1168. pp->ocurve.vertex[i] = pp->curve.vertex[mod( j, m )];
  1169. pp->ocurve.alpha[i] = pp->curve.alpha[mod( j, m )];
  1170. pp->ocurve.alpha0[i] = pp->curve.alpha0[mod( j, m )];
  1171. pp->ocurve.beta[i] = pp->curve.beta[mod( j, m )];
  1172. s[i] = t[i] = 1.0;
  1173. }
  1174. else
  1175. {
  1176. pp->ocurve.tag[i] = POTRACE_CURVETO;
  1177. pp->ocurve.c[i][0] = opt[j].c[0];
  1178. pp->ocurve.c[i][1] = opt[j].c[1];
  1179. pp->ocurve.c[i][2] = pp->curve.c[mod( j, m )][2];
  1180. pp->ocurve.vertex[i] = interval(
  1181. opt[j].s, pp->curve.c[mod( j, m )][2], pp->curve.vertex[mod( j, m )] );
  1182. pp->ocurve.alpha[i] = opt[j].alpha;
  1183. pp->ocurve.alpha0[i] = opt[j].alpha;
  1184. s[i] = opt[j].s;
  1185. t[i] = opt[j].t;
  1186. }
  1187. j = pt[j];
  1188. }
  1189. /* calculate beta parameters */
  1190. for( i = 0; i < om; i++ )
  1191. {
  1192. i1 = mod( i + 1, om );
  1193. pp->ocurve.beta[i] = s[i] / ( s[i] + t[i1] );
  1194. }
  1195. pp->ocurve.alphacurve = 1;
  1196. free( pt );
  1197. free( pen );
  1198. free( len );
  1199. free( opt );
  1200. free( s );
  1201. free( t );
  1202. free( convc );
  1203. free( areac );
  1204. return 0;
  1205. calloc_error:
  1206. free( pt );
  1207. free( pen );
  1208. free( len );
  1209. free( opt );
  1210. free( s );
  1211. free( t );
  1212. free( convc );
  1213. free( areac );
  1214. return 1;
  1215. }
  1216. /* ---------------------------------------------------------------------- */
  1217. #define TRY( x ) \
  1218. if( x ) \
  1219. goto try_error
  1220. /* return 0 on success, 1 on error with errno set. */
  1221. int process_path( path_t* plist, const potrace_param_t* param, progress_t* progress )
  1222. {
  1223. path_t* p;
  1224. double nn = 0, cn = 0;
  1225. if( progress->callback )
  1226. {
  1227. /* precompute task size for progress estimates */
  1228. nn = 0;
  1229. list_forall( p, plist ) {
  1230. nn += p->priv->len;
  1231. }
  1232. cn = 0;
  1233. }
  1234. /* call downstream function with each path */
  1235. list_forall( p, plist ) {
  1236. TRY( calc_sums( p->priv ) );
  1237. TRY( calc_lon( p->priv ) );
  1238. TRY( bestpolygon( p->priv ) );
  1239. TRY( adjust_vertices( p->priv ) );
  1240. if( p->sign == '-' )
  1241. {
  1242. /* reverse orientation of negative paths */
  1243. reverse( &p->priv->curve );
  1244. }
  1245. smooth( &p->priv->curve, param->alphamax );
  1246. if( param->opticurve )
  1247. {
  1248. TRY( opticurve( p->priv, param->opttolerance ) );
  1249. p->priv->fcurve = &p->priv->ocurve;
  1250. }
  1251. else
  1252. {
  1253. p->priv->fcurve = &p->priv->curve;
  1254. }
  1255. privcurve_to_curve( p->priv->fcurve, &p->curve );
  1256. if( progress->callback )
  1257. {
  1258. cn += p->priv->len;
  1259. progress_update( cn / nn, progress );
  1260. }
  1261. }
  1262. progress_update( 1.0, progress );
  1263. return 0;
  1264. try_error:
  1265. return 1;
  1266. }