diff options
Diffstat (limited to 'converter')
-rw-r--r-- | converter/other/pamtosvg/autotrace.c | 27 | ||||
-rw-r--r-- | converter/other/pamtosvg/autotrace.h | 48 | ||||
-rw-r--r-- | converter/other/pamtosvg/curve.h | 17 | ||||
-rw-r--r-- | converter/other/pamtosvg/fit.c | 200 | ||||
-rw-r--r-- | converter/other/pamtosvg/fit.h | 4 | ||||
-rw-r--r-- | converter/other/pamtosvg/point.c | 53 | ||||
-rw-r--r-- | converter/other/pamtosvg/point.h | 22 | ||||
-rw-r--r-- | converter/other/pamtosvg/spline.c | 11 | ||||
-rw-r--r-- | converter/other/pamtosvg/spline.h | 4 | ||||
-rw-r--r-- | converter/other/pamtosvg/vector.c | 300 | ||||
-rw-r--r-- | converter/other/pamtosvg/vector.h | 118 |
11 files changed, 407 insertions, 397 deletions
diff --git a/converter/other/pamtosvg/autotrace.c b/converter/other/pamtosvg/autotrace.c index e9902669..fa5b7e15 100644 --- a/converter/other/pamtosvg/autotrace.c +++ b/converter/other/pamtosvg/autotrace.c @@ -56,7 +56,7 @@ at_fitting_opts_copy (at_fitting_opts_type * original) return new_opts; } -void +void at_fitting_opts_free(at_fitting_opts_type * opts) { free(opts); @@ -88,10 +88,10 @@ at_output_opts_free(at_output_opts_type * opts) /* at_splines_new_full modifies its 'bitmap' argument when it does the thin_image thing. */ -at_spline_list_array_type * +at_spline_list_array_type * at_splines_new_full(at_bitmap_type * const bitmap, at_fitting_opts_type * const opts, - at_msg_func msg_func, + at_msg_func msg_func, void * const msg_data, at_progress_func notify_progress, void * const progress_data, @@ -128,20 +128,20 @@ at_splines_new_full(at_bitmap_type * const bitmap, if (opts->centerline) { pixel background_color; - if (opts->backgroundSpec) + if (opts->backgroundSpec) background_color = opts->background_color; else PPM_ASSIGN(background_color, 255, 255, 255); - + pixelOutlineList = - find_centerline_pixels(*bitmap, background_color, + find_centerline_pixels(*bitmap, background_color, notify_progress, progress_data, test_cancel, testcancel_data, &exp); } else pixelOutlineList = find_outline_pixels(*bitmap, opts->backgroundSpec, - opts->background_color, + opts->background_color, notify_progress, progress_data, test_cancel, testcancel_data, &exp); @@ -150,8 +150,8 @@ at_splines_new_full(at_bitmap_type * const bitmap, retval = NULL; else { at_spline_list_array_type * splinesP; - - MALLOCVAR_NOFAIL(splinesP); + + MALLOCVAR_NOFAIL(splinesP); fit_outlines_to_splines(pixelOutlineList, opts, haveDistMap ? &distanceMap : NULL, image_header.width, @@ -180,7 +180,7 @@ at_splines_new_full(at_bitmap_type * const bitmap, -void +void at_splines_write(at_output_write_func outputWriter, FILE * const writeto, at_output_opts_type * const optsArg, @@ -195,7 +195,7 @@ at_splines_write(at_output_write_func outputWriter, lly = 0; urx = splinesP->width; ury = splinesP->height; - + if (optsArg == NULL) { newOpts = true; optsP = at_output_opts_new(); @@ -212,9 +212,12 @@ at_splines_write(at_output_write_func outputWriter, -void +void at_splines_free(at_spline_list_array_type * const splines) { free_spline_list_array(splines); free(splines); } + + + diff --git a/converter/other/pamtosvg/autotrace.h b/converter/other/pamtosvg/autotrace.h index 2ac81a08..e30105a2 100644 --- a/converter/other/pamtosvg/autotrace.h +++ b/converter/other/pamtosvg/autotrace.h @@ -46,12 +46,12 @@ typedef struct _at_spline_list_array_type at_spline_list_array_type; /* Third degree is the highest we deal with. */ typedef enum _at_polynomial_degree { - AT_LINEARTYPE = 1, - AT_QUADRATICTYPE = 2, - AT_CUBICTYPE = 3, + AT_LINEARTYPE = 1, + AT_QUADRATICTYPE = 2, + AT_CUBICTYPE = 3, AT_PARALLELELLIPSETYPE = 4, - AT_ELLIPSETYPE = 5, - AT_CIRCLETYPE = 6 + AT_ELLIPSETYPE = 5, + AT_CIRCLETYPE = 6 /* not the real number of points to define a circle but to distinguish between a cubic spline */ } at_polynomial_degree; @@ -63,7 +63,7 @@ typedef enum _at_polynomial_degree straight line defined by the endpoints. */ struct _at_spline_type { - float_coord v[4]; /* The control points. */ + Point v[4]; /* The control points. */ at_polynomial_degree degree; float linearity; }; @@ -88,8 +88,8 @@ struct _at_spline_list_array_type /* splines bbox */ unsigned short height, width; - - /* the values for following members are inherited from + + /* the values for following members are inherited from at_fitting_opts_type */ bool backgroundSpec; pixel background_color; @@ -101,7 +101,7 @@ struct _at_spline_list_array_type /* Fitting option. - With using at_fitting_opts_doc macro, the description of + With using at_fitting_opts_doc macro, the description of each option could be get. e.g. at_fitting_opts_doc(background_color) */ struct _at_fitting_opts_type { bool backgroundSpec; @@ -122,7 +122,7 @@ struct _at_fitting_opts_type { struct _at_output_opts_type { - int dpi; /* DPI is used only in MIF output.*/ + int dpi; /* DPI is used only in MIF output.*/ }; struct _at_bitmap_type @@ -144,16 +144,16 @@ void (* at_msg_func) (const char * const msg, at_msg_type const msg_type, void * const client_data); -typedef +typedef int (*at_output_write_func) (FILE * const file, const char * const name, int const llx, - int const lly, + int const lly, int const urx, int const ury, at_output_opts_type * const opts, at_spline_list_array_type const shape, - at_msg_func msg_func, + at_msg_func msg_func, void * const msg_data); /* @@ -181,7 +181,7 @@ bool (*at_testcancel_func) (void * const client_data); * TODO: internal data access, copy * --------------------------------------------------------------------- */ at_fitting_opts_type * at_fitting_opts_new(void); -at_fitting_opts_type * at_fitting_opts_copy (at_fitting_opts_type * original); +at_fitting_opts_type * at_fitting_opts_copy (at_fitting_opts_type * original); void at_fitting_opts_free(at_fitting_opts_type * opts); /* TODO: Gettextize */ @@ -206,8 +206,8 @@ void at_output_opts_free(at_output_opts_type * opts); args: NOTIFY_PROGRESS is called repeatedly inside at_splines_new_full - to notify the progress of the execution. This might be useful for - interactive applications. NOTIFY_PROGRESS is called following + to notify the progress of the execution. This might be useful for + interactive applications. NOTIFY_PROGRESS is called following format: NOTIFY_PROGRESS (percentage, progress_data); @@ -215,27 +215,27 @@ void at_output_opts_free(at_output_opts_type * opts); test_cancel is called repeatedly inside at_splines_new_full to test whether the execution is canceled or not. If test_cancel returns TRUE, execution of at_splines_new_full - is stopped as soon as possible and returns NULL. If test_cancel + is stopped as soon as possible and returns NULL. If test_cancel returns FALSE, nothing happens. test_cancel is called following format: TEST_CANCEL (testcancel_data); - - NULL is valid value for notify_progress and/or test_cancel if - you don't need to know the progress of the execution and/or - cancel the execution */ -at_spline_list_array_type * + NULL is valid value for notify_progress and/or test_cancel if + you don't need to know the progress of the execution and/or + cancel the execution */ + +at_spline_list_array_type * at_splines_new_full(at_bitmap_type * const bitmap, at_fitting_opts_type * const opts, - at_msg_func msg_func, + at_msg_func msg_func, void * const msg_data, at_progress_func notify_progress, void * const progress_data, at_testcancel_func test_cancel, void * const testcancel_data); -void +void at_splines_write(at_output_write_func output_writer, FILE * const writeto, at_output_opts_type * const opts, diff --git a/converter/other/pamtosvg/curve.h b/converter/other/pamtosvg/curve.h index ba5f1833..c7845e7a 100644 --- a/converter/other/pamtosvg/curve.h +++ b/converter/other/pamtosvg/curve.h @@ -14,7 +14,7 @@ i.e., integers, after filtering they are reals. */ typedef struct { - float_coord coord; + Point coord; float t; } point_type; @@ -89,7 +89,7 @@ free_curve(curve * const curveP); /* Like `append_pixel', for a point in real coordinates. */ void append_point(curve_type const curve, - float_coord const coord); + Point const coord); /* Append the point P to the end of C's list. */ void @@ -98,11 +98,11 @@ append_pixel(curve_type const c, /* Write some or all, respectively, of the curve C in human-readable form to the log file, if logging is enabled. */ -extern void log_curve (curve_type c, bool print_t); -extern void log_entire_curve (curve_type c); +void log_curve (curve_type c, bool print_t); +void log_entire_curve (curve_type c); /* Display the curve C online, if displaying is enabled. */ -extern void display_curve (curve_type); +void display_curve (curve_type); @@ -134,12 +134,12 @@ typedef struct { #define CURVE_LIST_CLOCKWISE(c_l) ((c_l).clockwise) -extern curve_list_type new_curve_list (void); +curve_list_type new_curve_list (void); void free_curve_list(curve_list_type * const curve_list); -extern void append_curve (curve_list_type *, curve_type); +void append_curve (curve_list_type *, curve_type); /* And a character is a list of outlines. I named this `curve_list_array_type' because `curve_list_list_type' seemed pretty @@ -161,7 +161,7 @@ new_curve_list_array(void); void free_curve_list_array(const curve_list_array_type * const curve_list_array, - at_progress_func notify_progress, + at_progress_func notify_progress, void * const client_data); void @@ -169,4 +169,3 @@ append_curve_list(curve_list_array_type * const curve_list_array, curve_list_type const curve_list); #endif - diff --git a/converter/other/pamtosvg/fit.c b/converter/other/pamtosvg/fit.c index c5a46310..9465ff75 100644 --- a/converter/other/pamtosvg/fit.c +++ b/converter/other/pamtosvg/fit.c @@ -34,6 +34,7 @@ #include "message.h" #include "logreport.h" #include "spline.h" +#include "point.h" #include "vector.h" #include "curve.h" #include "pxl-outline.h" @@ -45,6 +46,7 @@ typedef enum {LINEEND_INIT, LINEEND_TERM} LineEnd; static LineEnd otherEnd(LineEnd const thisEnd) { + switch (thisEnd) { case LINEEND_INIT: return LINEEND_TERM; case LINEEND_TERM: return LINEEND_INIT; @@ -58,8 +60,8 @@ otherEnd(LineEnd const thisEnd) { /* We need to manipulate lists of array indices. */ typedef struct IndexList { - unsigned *data; - unsigned length; + unsigned int * data; + unsigned int length; } IndexList; /* The usual accessor macros. */ @@ -71,7 +73,7 @@ typedef struct IndexList { static pm_pixelcoord -intCoordFmReal(float_coord const realCoord) { +intCoordFmReal(Point const realCoord) { /*---------------------------------------------------------------------------- Turn an real point into a integer one. -----------------------------------------------------------------------------*/ @@ -124,8 +126,8 @@ indexList_append(IndexList * const listP, static float -distance(float_coord const p1, - float_coord const p2) { +distance(Point const p1, + Point const p2) { /*---------------------------------------------------------------------------- Return the Euclidean distance between 'p1' and 'p2'. -----------------------------------------------------------------------------*/ @@ -154,8 +156,8 @@ appendCorner(IndexList * const cornerListP, static void findVectors(unsigned int const testIndex, pixel_outline_type const outline, - vector_type * const inP, - vector_type * const outP, + Vector * const inP, + Vector * const outP, unsigned int const cornerSurround) { /*---------------------------------------------------------------------------- Return the difference vectors coming in and going out of the outline @@ -179,13 +181,15 @@ findVectors(unsigned int const testIndex, for (i = O_PREV(outline, testIndex), doneCt = 0; doneCt < cornerSurround; i = O_PREV(outline, i), ++doneCt) - *inP = Vadd(*inP, IPsubtract(O_COORDINATE(outline, i), candidate)); + *inP = vector_sum(*inP, vector_IPointDiff(O_COORDINATE(outline, i), + candidate)); /* And the points after p. */ for (i = O_NEXT(outline, testIndex), doneCt = 0; doneCt < cornerSurround; i = O_NEXT(outline, i), ++doneCt) - *outP = Vadd(*outP, IPsubtract(O_COORDINATE(outline, i), candidate)); + *outP = vector_sum(*outP, vector_IPointDiff(O_COORDINATE(outline, i), + candidate)); } @@ -237,14 +241,14 @@ lookAheadForBetterCorner(pixel_outline_type const outline, i < O_LENGTH(outline) && !at_exception_got_fatal(exceptionP)) { - vector_type inVector, outVector; + Vector inVector, outVector; float cornerAngle; /* Check the angle. */ q = i % O_LENGTH(outline); findVectors(q, outline, &inVector, &outVector, cornerSurround); - cornerAngle = Vangle(inVector, outVector, exceptionP); + cornerAngle = vector_angle(inVector, outVector, exceptionP); if (!at_exception_got_fatal(exceptionP)) { /* Perhaps the angle is sufficiently small that we want to consider this a corner, even if it's not the best @@ -429,8 +433,8 @@ remove_knee_points(curve * const curveP, intCoordFmReal(CURVE_POINT(curveP, i)); pm_pixelcoord const next = intCoordFmReal(CURVE_POINT(curveP, CURVE_NEXT(curveP, i))); - vector_type const prev_delta = IPsubtract(previous, current); - vector_type const next_delta = IPsubtract(next, current); + Vector const prev_delta = vector_IPointDiff(previous, current); + Vector const next_delta = vector_IPointDiff(next, current); if (ONLY_ONE_ZERO(prev_delta) && ONLY_ONE_ZERO(next_delta) && ((clockwise && CLOCKWISE_KNEE(prev_delta, next_delta)) @@ -467,7 +471,7 @@ filter(curve * const curveP, unsigned int const offset = CURVE_CYCLIC(curveP) ? 0 : 1; unsigned int iteration, thisPoint; - float_coord prevNewPoint; + Point prevNewPoint; /* We must have at least three points -- the previous one, the current one, and the next one. But if we don't have at least five, we will @@ -499,8 +503,8 @@ filter(curve * const curveP, for (thisPoint = offset; thisPoint < CURVE_LENGTH(curveP) - offset; ++thisPoint) { - vector_type in, out, sum; - float_coord newPoint; + Vector in, out, sum; + Point newPoint; /* Calculate the vectors in and out, computed by looking at n points on either side of this_point. Experimental @@ -509,7 +513,7 @@ filter(curve * const curveP, signed int prev, prevprev; /* have to be signed */ unsigned int next, nextnext; - float_coord candidate = CURVE_POINT(curveP, thisPoint); + Point candidate = CURVE_POINT(curveP, thisPoint); prev = CURVE_PREV(curveP, thisPoint); prevprev = CURVE_PREV(curveP, prev); @@ -521,25 +525,32 @@ filter(curve * const curveP, */ in.dx = in.dy = in.dz = 0.0; - in = Vadd(in, Psubtract(CURVE_POINT(curveP, prev), candidate)); + in = vector_sum(in, + vector_fromTwoPoints(CURVE_POINT(curveP, prev), + candidate)); if (prevprev >= 0) - in = Vadd(in, - Psubtract(CURVE_POINT(curveP, prevprev), candidate)); + in = vector_sum( + in, + vector_fromTwoPoints(CURVE_POINT(curveP, prevprev), + candidate)); /* And the points after p. Don't use more points after p than we ended up with before it. */ out.dx = out.dy = out.dz = 0.0; - out = Vadd(out, Psubtract(CURVE_POINT(curveP, next), candidate)); + out = vector_sum( + out, + vector_fromTwoPoints(CURVE_POINT(curveP, next), candidate)); if (nextnext < CURVE_LENGTH(curveP)) - out = Vadd(out, - Psubtract(CURVE_POINT(curveP, nextnext), - candidate)); + out = vector_sum( + out, + vector_fromTwoPoints(CURVE_POINT(curveP, nextnext), + candidate)); /* Start with the old point. */ newPoint = candidate; - sum = Vadd(in, out); + sum = vector_sum(in, out); /* We added 2*n+2 points, so we have to divide the sum by 2*n+2 */ newPoint.x += sum.dx / 6; newPoint.y += sum.dy / 6; @@ -623,13 +634,13 @@ findCorners(pixel_outline_type const outline, /* Consider each pixel on the outline in turn. */ for (p = firstPixelSeq; p <= lastPixelSeq;) { - vector_type inVector, outVector; + Vector inVector, outVector; float cornerAngle; /* Check if the angle is small enough. */ findVectors(p, outline, &inVector, &outVector, fittingOptsP->corner_surround); - cornerAngle = Vangle(inVector, outVector, exceptionP); + cornerAngle = vector_angle(inVector, outVector, exceptionP); if (at_exception_got_fatal(exceptionP)) goto cleanup; @@ -994,7 +1005,7 @@ computePointWeights(curve_list_type const curveList, unsigned pointSeq; curve_type const curve = CURVE_LIST_ELT(curveList, curveSeq); for (pointSeq = 0; pointSeq < CURVE_LENGTH(curve); ++pointSeq) { - float_coord * const coordP = &CURVE_POINT(curve, pointSeq); + Point * const coordP = &CURVE_POINT(curve, pointSeq); unsigned int x = coordP->x; unsigned int y = height - (unsigned int)coordP->y - 1; @@ -1167,7 +1178,7 @@ splineLinearEnough(spline_type * const splineP, ++thisPoint) { float const t = CURVE_T(curve, thisPoint); - float_coord const splinePoint = evaluate_spline(*splineP, t); + Point const splinePoint = evaluate_spline(*splineP, t); float const a = splinePoint.x - START_POINT(*splineP).x; float const b = splinePoint.y - START_POINT(*splineP).y; @@ -1208,8 +1219,8 @@ splineLinearEnough(spline_type * const splineP, static spline_list_type * fitCurve(curve * const curveP, - vector_type const begSlope, - vector_type const endSlope, + Vector const begSlope, + Vector const endSlope, const fitting_opts_type * const fittingOptsP, at_exception_type * const exceptionP); @@ -1252,8 +1263,8 @@ fitWithLine(curve * const curveP) { static spline_type fitOneSpline(curve * const curveP, - vector_type const begSlope, - vector_type const endSlope, + Vector const begSlope, + Vector const endSlope, at_exception_type * const exceptionP) { /*---------------------------------------------------------------------------- Return a spline that fits the points of curve *curveP, @@ -1287,16 +1298,16 @@ fitOneSpline(curve * const curveP, B_i^n(t) = { n \choose i } t^i (1-t)^{n-i}, i = 0..n */ - struct vectorPair { - vector_type beg; - vector_type end; + struct VectorPair { + Vector beg; + Vector end; }; - struct vectorPair tang; + struct VectorPair tang; spline_type spline; - vector_type begVector, endVector; + Vector begVector, endVector; unsigned int i; - struct vectorPair * A; /* malloc'ed array */ + struct VectorPair * A; /* malloc'ed array */ /* I don't know the meaning of this array, but it is one entry for each point in the curve (A[i] is for the ith point in the curve). */ @@ -1312,12 +1323,12 @@ fitOneSpline(curve * const curveP, BEG_POINT(spline) = CURVE_POINT(curveP, 0); END_POINT(spline) = LAST_CURVE_POINT(curveP); - begVector = make_vector(BEG_POINT(spline)); - endVector = make_vector(END_POINT(spline)); + begVector = vector_fromPoint(BEG_POINT(spline)); + endVector = vector_fromPoint(END_POINT(spline)); for (i = 0; i < CURVE_LENGTH(curveP); ++i) { - A[i].beg = Vmult_scalar(tang.beg, B1(CURVE_T(curveP, i))); - A[i].end = Vmult_scalar(tang.end, B2(CURVE_T(curveP, i))); + A[i].beg = vector_scaled(tang.beg, B1(CURVE_T(curveP, i))); + A[i].end = vector_scaled(tang.end, B2(CURVE_T(curveP, i))); } C.beg.beg = 0.0; C.beg.end = 0.0; C.end.end = 0.0; /* initial value */ @@ -1325,26 +1336,29 @@ fitOneSpline(curve * const curveP, X.beg = 0.0; X.end = 0.0; /* initial value */ for (i = 0; i < CURVE_LENGTH(curveP); ++i) { - struct vectorPair * const AP = &A[i]; - vector_type temp, temp0, temp1, temp2, temp3; + struct VectorPair * const AP = &A[i]; + Vector temp, temp0, temp1, temp2, temp3; - C.beg.beg += Vdot(AP->beg, AP->beg); - C.beg.end += Vdot(AP->beg, AP->end); - /* C.end.beg = Vdot(AP->end, AP->beg) is done outside of loop */ - C.end.end += Vdot(AP->end, AP->end); + C.beg.beg += vector_dotProduct(AP->beg, AP->beg); + C.beg.end += vector_dotProduct(AP->beg, AP->end); + /* C.end.beg = vector_dotProduct(AP->end, AP->beg) + is done outside of loop */ + C.end.end += vector_dotProduct(AP->end, AP->end); /* Now the right-hand side of the equation in the paper. */ - temp0 = Vmult_scalar(begVector, B0(CURVE_T(curveP, i))); - temp1 = Vmult_scalar(begVector, B1(CURVE_T(curveP, i))); - temp2 = Vmult_scalar(endVector, B2(CURVE_T(curveP, i))); - temp3 = Vmult_scalar(endVector, B3(CURVE_T(curveP, i))); - - temp = make_vector( - Vsubtract_point(CURVE_POINT(curveP, i), - Vadd(temp0, Vadd(temp1, Vadd(temp2, temp3))))); - - X.beg += Vdot(temp, AP->beg); - X.end += Vdot(temp, AP->end); + temp0 = vector_scaled(begVector, B0(CURVE_T(curveP, i))); + temp1 = vector_scaled(begVector, B1(CURVE_T(curveP, i))); + temp2 = vector_scaled(endVector, B2(CURVE_T(curveP, i))); + temp3 = vector_scaled(endVector, B3(CURVE_T(curveP, i))); + + temp = vector_fromPoint( + vector_diffPoint( + CURVE_POINT(curveP, i), + vector_sum(temp0, vector_sum(temp1, + vector_sum(temp2, temp3))))); + + X.beg += vector_dotProduct(temp, AP->beg); + X.end += vector_dotProduct(temp, AP->end); } free(A); @@ -1363,10 +1377,10 @@ fitOneSpline(curve * const curveP, alpha.beg = XCendDet / CDet; alpha.end = CbegXDet / CDet; - CONTROL1(spline) = Vadd_point(BEG_POINT(spline), - Vmult_scalar(tang.beg, alpha.beg)); - CONTROL2(spline) = Vadd_point(END_POINT(spline), - Vmult_scalar(tang.end, alpha.end)); + CONTROL1(spline) = vector_sumPoint( + BEG_POINT(spline), vector_scaled(tang.beg, alpha.beg)); + CONTROL2(spline) = vector_sumPoint( + END_POINT(spline), vector_scaled(tang.end, alpha.end)); SPLINE_DEGREE(spline) = CUBICTYPE; } } @@ -1391,7 +1405,7 @@ logSplineFit(spline_type const spline) { -static vector_type +static Vector findHalfTangent(LineEnd const toWhichEnd, curve * const curveP, unsigned int const tangentSurround) { @@ -1420,14 +1434,14 @@ findHalfTangent(LineEnd const toWhichEnd, the mean of a vector pointing left and one pointing right is the zero vector. In that case, we use fewer "tangentSurround" points. -----------------------------------------------------------------------------*/ - float_coord const tangentPoint = + Point const tangentPoint = CURVE_POINT(curveP, toWhichEnd == LINEEND_INIT ? 0 : CURVE_LENGTH(curveP) - 1); - vector_type const zeroZero = { 0.0, 0.0 }; + Vector const zeroZero = { 0.0, 0.0 }; unsigned int surroundCt; bool gotNonzero; - vector_type mean; + Vector mean; for (surroundCt = MIN(CURVE_LENGTH(curveP) / 2, tangentSurround), gotNonzero = false; @@ -1435,27 +1449,28 @@ findHalfTangent(LineEnd const toWhichEnd, --surroundCt) { unsigned int i; - vector_type sum; + Vector sum; unsigned int n; for (i = 0, n = 0, sum = zeroZero; i < surroundCt; ++i) { unsigned int const thisIndex = toWhichEnd == LINEEND_INIT ? i + 1 : CURVE_LENGTH(curveP) - 1 - i; - float_coord const thisPoint = CURVE_POINT(curveP, thisIndex); + Point const thisPoint = CURVE_POINT(curveP, thisIndex); - if (!pointsEqual(thisPoint, tangentPoint)) { + if (!point_equal(thisPoint, tangentPoint)) { /* Perhaps we should weight the tangent from `thisPoint' by some factor dependent on the distance from the tangent point. */ - sum = Vadd(sum, Pdirection(thisPoint, tangentPoint)); + sum = vector_sum(sum, vector_pointDirection(thisPoint, + tangentPoint)); ++n; } } - mean = n > 0 ? Vmult_scalar(sum, 1.0 / n) : Vhorizontal(); + mean = n > 0 ? vector_scaled(sum, 1.0 / n) : vector_horizontal(); - if (Vequal(mean, Vzero())) { + if (vector_equal(mean, vector_zero())) { /* We have points on multiple sides of the endpoint whose vectors happen to add up to zero, which is not usable. */ @@ -1474,7 +1489,7 @@ findTangent(curve * const curveP, LineEnd const toWhichEnd, curve * const adjacentCurveP, unsigned int const tangentSurround, - vector_type * const tangentP) { + Vector * const tangentP) { /*---------------------------------------------------------------------------- Find an approximation to the slope of *curveP (i.e. slope of tangent line) at an endpoint (per 'toWhichEnd'). @@ -1499,7 +1514,7 @@ findTangent(curve * const curveP, be placed on the half-lines defined by the slopes and endpoints, and we never recompute the tangent after this. -----------------------------------------------------------------------------*/ - vector_type const slopeThisCurve = + Vector const slopeThisCurve = findHalfTangent(toWhichEnd, curveP, tangentSurround); LOG2(" tangent to %s of curve %lx: ", @@ -1509,14 +1524,15 @@ findTangent(curve * const curveP, slopeThisCurve.dx, slopeThisCurve.dy, slopeThisCurve.dz); if (adjacentCurveP) { - vector_type const slopeAdjCurve = + Vector const slopeAdjCurve = findHalfTangent(otherEnd(toWhichEnd), adjacentCurveP, tangentSurround); LOG3("(adjacent curve half tangent (%.3f,%.3f,%.3f)) ", slopeAdjCurve.dx, slopeAdjCurve.dy, slopeAdjCurve.dz); - *tangentP = Vmult_scalar(Vadd(slopeThisCurve, slopeAdjCurve), 0.5); + *tangentP = vector_scaled(vector_sum(slopeThisCurve, slopeAdjCurve), + 0.5); } else *tangentP = slopeThisCurve; @@ -1554,9 +1570,9 @@ findError(curve * const curveP, worstPoint = 0; for (thisPoint = 0; thisPoint < CURVE_LENGTH(curveP); ++thisPoint) { - float_coord const curvePoint = CURVE_POINT(curveP, thisPoint); + Point const curvePoint = CURVE_POINT(curveP, thisPoint); float const t = CURVE_T(curveP, thisPoint); - float_coord const splinePoint = evaluate_spline(spline, t); + Point const splinePoint = evaluate_spline(spline, t); float const thisError = distance(curvePoint, splinePoint); if (thisError >= worstError) { worstPoint = thisPoint; @@ -1610,8 +1626,8 @@ setInitialParameterValues(curve * const curveP) { CURVE_T(curveP, 0) = 0.0; for (p = 1; p < CURVE_LENGTH(curveP); ++p) { - float_coord const point = CURVE_POINT(curveP, p); - float_coord const previous_p = CURVE_POINT(curveP, p - 1); + Point const point = CURVE_POINT(curveP, p); + Point const previous_p = CURVE_POINT(curveP, p - 1); float const d = distance(point, previous_p); CURVE_T(curveP, p) = CURVE_T(curveP, p - 1) + d; } @@ -1634,7 +1650,7 @@ subdivideCurve(curve * const curveP, const fitting_opts_type * const fittingOptsP, curve ** const leftCurvePP, curve ** const rghtCurvePP, - vector_type * const joinSlopeP) { + Vector * const joinSlopeP) { /*---------------------------------------------------------------------------- Split curve *curveP into two, at 'subdivisionIndex'. (Actually, leave *curveP alone, but return as *leftCurvePP and *rghtCurvePP @@ -1747,8 +1763,8 @@ divisionPoint(curve * const curveP, static spline_list_type * divideAndFit(curve * const curveP, - vector_type const begSlope, - vector_type const endSlope, + Vector const begSlope, + Vector const endSlope, unsigned int const subdivisionIndex, const fitting_opts_type * const fittingOptsP, at_exception_type * const exceptionP) { @@ -1768,7 +1784,7 @@ divideAndFit(curve * const curveP, /* The beginning (lower indexes) subcurve */ curve * rghtCurveP; /* The other subcurve */ - vector_type joinSlope; + Vector joinSlope; /* The slope of the end of the left subcurve and start of the right subcurve. */ @@ -1816,8 +1832,8 @@ divideAndFit(curve * const curveP, static spline_list_type * fitWithLeastSquares(curve * const curveP, - vector_type const begSlope, - vector_type const endSlope, + Vector const begSlope, + Vector const endSlope, const fitting_opts_type * const fittingOptsP, at_exception_type * const exceptionP) { /*---------------------------------------------------------------------------- @@ -1840,7 +1856,7 @@ fitWithLeastSquares(curve * const curveP, if (CURVE_CYCLIC(curveP) && CURVE_LENGTH(curveP) < 4) { unsigned i; for (i = 0; i < CURVE_LENGTH(curveP); ++i) { - float_coord const point = CURVE_POINT(curveP, i); + Point const point = CURVE_POINT(curveP, i); fprintf(stderr, "point %u = (%f, %f)\n", i, point.x, point.y); } } @@ -1891,8 +1907,8 @@ fitWithLeastSquares(curve * const curveP, static spline_list_type * fitCurve(curve * const curveP, - vector_type const begSlope, - vector_type const endSlope, + Vector const begSlope, + Vector const endSlope, const fitting_opts_type * const fittingOptsP, at_exception_type * const exceptionP) { /*---------------------------------------------------------------------------- @@ -1941,7 +1957,7 @@ fitCurves(curve_list_type const curveList, curve * const curveP = CURVE_LIST_ELT(curveList, curveSeq); - vector_type begSlope, endSlope; + Vector begSlope, endSlope; spline_list_type * curveSplinesP; LOG2("\nFitting curve #%u (%lx):\n", curveSeq, (unsigned long)curveP); diff --git a/converter/other/pamtosvg/fit.h b/converter/other/pamtosvg/fit.h index 529da5c7..8c234f33 100644 --- a/converter/other/pamtosvg/fit.h +++ b/converter/other/pamtosvg/fit.h @@ -10,7 +10,7 @@ #include "exception.h" /* See fit.c for descriptions of these variables, all of which can be - set using options. + set using options. */ typedef at_fitting_opts_type fitting_opts_type; @@ -21,7 +21,7 @@ fit_outlines_to_splines(pixel_outline_list_type const pixelOutlineList, unsigned short const width, unsigned short const height, at_exception_type * const exception, - at_progress_func notifyProgress, + at_progress_func notifyProgress, void * const progressData, at_testcancel_func testCancel, void * const testcancelData, diff --git a/converter/other/pamtosvg/point.c b/converter/other/pamtosvg/point.c index 6a9ffafa..94502d83 100644 --- a/converter/other/pamtosvg/point.c +++ b/converter/other/pamtosvg/point.c @@ -4,12 +4,21 @@ #include "point.h" -float_coord -makePoint(float const x, - float const y, - float const z) { - float_coord retval; + +/* Operations on points with real coordinates. It is not orthogonal, + but more convenient, to have the subtraction operator return a + vector, and the addition operator return a point. +*/ + + + +Point +point_make(float const x, + float const y, + float const z) { + + Point retval; retval.x = x; retval.y = y; @@ -21,8 +30,8 @@ makePoint(float const x, bool -pointsEqual(float_coord const comparand, - float_coord const comparator) { +point_equal(Point const comparand, + Point const comparator) { return epsilon_equal(comparand.x, comparator.x) @@ -35,3 +44,33 @@ pointsEqual(float_coord const comparand, +Point +point_sum(Point const coord1, + Point const coord2) { + + Point retval; + + retval.x = coord1.x + coord2.x; + retval.y = coord1.y + coord2.y; + retval.z = coord1.z + coord2.z; + + return retval; +} + + + +Point +point_scaled(Point const coord, + float const r) { + + Point retval; + + retval.x = coord.x * r; + retval.y = coord.y * r; + retval.z = coord.z * r; + + return retval; +} + + + diff --git a/converter/other/pamtosvg/point.h b/converter/other/pamtosvg/point.h index 1304d0fe..63594027 100644 --- a/converter/other/pamtosvg/point.h +++ b/converter/other/pamtosvg/point.h @@ -5,15 +5,23 @@ typedef struct { float x, y, z; -} float_coord; +} Point; -float_coord -makePoint(float const x, - float const y, - float const z); +Point +point_make(float const x, + float const y, + float const z); bool -pointsEqual(float_coord const comparand, - float_coord const comparator); +point_equal(Point const comparand, + Point const comparator); + +Point +point_sum(Point const coord1, + Point const coord2); + +Point +point_scaled(Point const coord, + float const r); #endif diff --git a/converter/other/pamtosvg/spline.c b/converter/other/pamtosvg/spline.c index 61167ec4..9535ec6a 100644 --- a/converter/other/pamtosvg/spline.c +++ b/converter/other/pamtosvg/spline.c @@ -34,7 +34,7 @@ print_spline (FILE *f, spline_type s) of de Casteljau's algorithm. See Schneider's thesis, p.37. The variable names are taken from there. */ -float_coord +Point evaluate_spline (spline_type s, float t) { spline_type V[4]; /* We need degree+1 splines, but assert degree <= 3. */ @@ -52,9 +52,9 @@ evaluate_spline (spline_type s, float t) for (j = 1; j <= degree; j++) for (i = 0; i <= degree - j; i++) { - float_coord t1 = Pmult_scalar (V[j - 1].v[i], one_minus_t); - float_coord t2 = Pmult_scalar (V[j - 1].v[i + 1], t); - float_coord temp = Padd (t1, t2); + Point t1 = point_scaled(V[j - 1].v[i], one_minus_t); + Point t2 = point_scaled(V[j - 1].v[i + 1], t); + Point temp = point_sum(t1, t2); V[j].v[i].x = temp.x; V[j].v[i].y = temp.y; V[j].v[i].z = temp.z; @@ -76,7 +76,7 @@ new_spline_list (void) return answer; } -spline_list_type +spline_list_type empty_spline_list (void) { spline_list_type answer; @@ -192,4 +192,3 @@ append_spline_list (spline_list_array_type *l, spline_list_type s) SPLINE_LIST_ARRAY_LENGTH(*l)); LAST_SPLINE_LIST_ARRAY_ELT (*l) = s; } - diff --git a/converter/other/pamtosvg/spline.h b/converter/other/pamtosvg/spline.h index 96ceab4e..b0a731f8 100644 --- a/converter/other/pamtosvg/spline.h +++ b/converter/other/pamtosvg/spline.h @@ -28,10 +28,10 @@ typedef at_spline_type spline_type; #ifndef _IMPORTING /* Print a spline on the given file. */ -extern void print_spline (FILE *, spline_type); +void print_spline (FILE *, spline_type); /* Evaluate SPLINE at the given T value. */ -extern float_coord evaluate_spline (spline_type spline, float t); +Point evaluate_spline (spline_type spline, float t); #endif /* Each outline in a character is typically represented by many diff --git a/converter/other/pamtosvg/vector.c b/converter/other/pamtosvg/vector.c index b1cffb4a..e91c6a24 100644 --- a/converter/other/pamtosvg/vector.c +++ b/converter/other/pamtosvg/vector.c @@ -12,15 +12,39 @@ #include "message.h" #include "epsilon-equal.h" -static float acos_d (float, at_exception_type * excep); +static float +acosD(float const v, + at_exception_type * const excepP) { + float vAdj; + float a; + float retval; + + if (epsilon_equal(v, 1.0)) + vAdj = 1.0; + else if (epsilon_equal(v, -1.0)) + vAdj = -1.0; + else + vAdj = v; + + errno = 0; + a = acos(vAdj); + if (errno == ERANGE || errno == EDOM) { + at_exception_fatal(excepP, strerror(errno)); + retval = 0.0; + } else + retval = a * 180.0 / M_PI; + + return retval; +} -/* Given the point COORD, return the corresponding vector. */ -vector_type -make_vector(float_coord const c) { - vector_type v; +Vector +vector_fromPoint(Point const c) { +/* Vector corresponding to point 'c', taken as a vector from the origin. */ + + Vector v; v.dx = c.x; v.dy = c.y; @@ -31,12 +55,28 @@ make_vector(float_coord const c) { +Vector +vector_fromTwoPoints(Point const c1, + Point const c2) { + + Vector retval; + + retval.dx = c1.x - c2.x; + retval.dy = c1.y - c2.y; + retval.dz = c1.z - c2.z; + + return retval; +} + + + /* And the converse: given a vector, return the corresponding point. */ -float_coord -vector_to_point(vector_type const v) { +Point +vector_toPoint_point(Vector const v) { +/* vector as a point, i.e., a displacement from the origin. */ - float_coord coord; + Point coord; coord.x = v.dx; coord.y = v.dy; @@ -48,18 +88,18 @@ vector_to_point(vector_type const v) { float -magnitude(vector_type const v) { +vector_magnitude(Vector const v) { return sqrt(SQR(v.dx) + SQR(v.dy) + SQR(v.dz)); } -vector_type -normalize(vector_type const v) { +Vector +vector_normalized(Vector const v) { - vector_type new_v; - float const m = magnitude(v); + Vector new_v; + float const m = vector_magnitude(v); if (m > 0.0) { new_v.dx = v.dx / m; @@ -76,225 +116,152 @@ normalize(vector_type const v) { -vector_type -Vadd(vector_type const v1, - vector_type const v2) { +Vector +vector_sum(Vector const addend, + Vector const adder) { - vector_type new_v; + Vector retval; - new_v.dx = v1.dx + v2.dx; - new_v.dy = v1.dy + v2.dy; - new_v.dz = v1.dz + v2.dz; + retval.dx = addend.dx + adder.dx; + retval.dy = addend.dy + adder.dy; + retval.dz = addend.dz + adder.dz; - return new_v; + return retval; } float -Vdot(vector_type const v1, - vector_type const v2) { +vector_dotProduct(Vector const v1, + Vector const v2) { return v1.dx * v2.dx + v1.dy * v2.dy + v1.dz * v2.dz; } -vector_type -Vmult_scalar(vector_type const v, - float const r) { +Vector +vector_scaled(Vector const v, + float const r) { - vector_type new_v; + Vector retval; - new_v.dx = v.dx * r; - new_v.dy = v.dy * r; - new_v.dz = v.dz * r; + retval.dx = v.dx * r; + retval.dy = v.dy * r; + retval.dz = v.dz * r; - return new_v; + return retval; } -/* Given the IN_VECTOR and OUT_VECTOR, return the angle between them in - degrees, in the range zero to 180. -*/ - float -Vangle(vector_type const in_vector, - vector_type const out_vector, - at_exception_type * const exP) { - - vector_type const v1 = normalize(in_vector); - vector_type const v2 = normalize(out_vector); - - return acos_d(Vdot(v2, v1), exP); -} - - - -float_coord -Vadd_point(float_coord const c, - vector_type const v) { - - float_coord new_c; - - new_c.x = c.x + v.dx; - new_c.y = c.y + v.dy; - new_c.z = c.z + v.dz; - - return new_c; -} - - +vector_angle(Vector const inVector, + Vector const outVector, + at_exception_type * const exP) { -float_coord -Vsubtract_point(float_coord const c, - vector_type const v) { - - float_coord new_c; - - new_c.x = c.x - v.dx; - new_c.y = c.y - v.dy; - new_c.z = c.z - v.dz; - - return new_c; -} - - - -pm_pixelcoord -Vadd_int_point(pm_pixelcoord const c, - vector_type const v) { - - pm_pixelcoord a; +/* The angle between 'inVector' and 'outVector' in degrees, in the range zero + to 180. +*/ - a.col = ROUND ((float) c.col + v.dx); - a.row = ROUND ((float) c.row + v.dy); + Vector const v1 = vector_normalized(inVector); + Vector const v2 = vector_normalized(outVector); - return a; + return acosD(vector_dotProduct(v2, v1), exP); } -vector_type -Vabs(vector_type const v) { +Point +vector_sumPoint(Point const c, + Vector const v) { - vector_type new_v; + Point retval; - new_v.dx = (float) fabs (v.dx); - new_v.dy = (float) fabs (v.dy); - new_v.dz = (float) fabs (v.dz); + retval.x = c.x + v.dx; + retval.y = c.y + v.dy; + retval.z = c.z + v.dz; - return new_v; + return retval; } -/* Operations on points. */ - -float_coord -Padd(float_coord const coord1, - float_coord const coord2) { +Point +vector_diffPoint(Point const c, + Vector const v) { - float_coord sum; + Point retval; - sum.x = coord1.x + coord2.x; - sum.y = coord1.y + coord2.y; - sum.z = coord1.z + coord2.z; + retval.x = c.x - v.dx; + retval.y = c.y - v.dy; + retval.z = c.z - v.dz; - return sum; + return retval; } -float_coord -Pmult_scalar(float_coord const coord, - float const r) { +Vector +vector_IPointDiff(pm_pixelcoord const coord1, + pm_pixelcoord const coord2) { - float_coord answer; + Vector retval; - answer.x = coord.x * r; - answer.y = coord.y * r; - answer.z = coord.z * r; + retval.dx = (int) (coord1.col - coord2.col); + retval.dy = (int) (coord1.row - coord2.row); + retval.dz = 0.0; - return answer; + return retval; } -vector_type -Psubtract(float_coord const c1, - float_coord const c2) { - - vector_type v; - - v.dx = c1.x - c2.x; - v.dy = c1.y - c2.y; - v.dz = c1.z - c2.z; - - return v; -} +pm_pixelcoord +vector_sumIntPoint(pm_pixelcoord const c, + Vector const v) { +/* This returns the rounded sum. */ + pm_pixelcoord retval; -vector_type -Pdirection(float_coord const final, - float_coord const initial) { + retval.col = ROUND ((float) c.col + v.dx); + retval.row = ROUND ((float) c.row + v.dy); - return normalize(Psubtract(final, initial)); + return retval; } -/* Operations on integer points. */ +Vector +vector_abs(Vector const v) { -vector_type -IPsubtract(pm_pixelcoord const coord1, - pm_pixelcoord const coord2) { +/* First-quadrant mirror of 'v' (both components unsigned) */ - vector_type v; + Vector retval; - v.dx = (int) (coord1.col - coord2.col); - v.dy = (int) (coord1.row - coord2.row); - v.dz = 0.0; + retval.dx = (float) fabs (v.dx); + retval.dy = (float) fabs (v.dy); + retval.dz = (float) fabs (v.dz); - return v; + return retval; } -static float -acos_d(float const v, - at_exception_type * const excepP) { - - float vAdj; - float a; - float retval; - - if (epsilon_equal(v, 1.0)) - vAdj = 1.0; - else if (epsilon_equal(v, -1.0)) - vAdj = -1.0; - else - vAdj = v; +Vector +vector_pointDirection(Point const final, + Point const initial) { - errno = 0; - a = acos(vAdj); - if (errno == ERANGE || errno == EDOM) { - at_exception_fatal(excepP, strerror(errno)); - retval = 0.0; - } else - retval = a * 180.0 / M_PI; - - return retval; + return vector_normalized(vector_fromTwoPoints(final, initial)); } -vector_type -Vhorizontal(void) { +Vector +vector_horizontal(void) { - vector_type retval; + Vector retval; retval.dx = 1.0; retval.dy = 0.0; @@ -304,10 +271,10 @@ Vhorizontal(void) { } -vector_type -Vzero(void) { +Vector +vector_zero(void) { - vector_type retval; + Vector retval; retval.dx = 0.0; retval.dy = 0.0; @@ -318,8 +285,8 @@ Vzero(void) { bool -Vequal(vector_type const comparand, - vector_type const comparator) { +vector_equal(Vector const comparand, + Vector const comparator) { return epsilon_equal(comparand.dx, comparator.dx) @@ -329,3 +296,6 @@ Vequal(vector_type const comparand, epsilon_equal(comparand.dz, comparator.dz) ; } + + + diff --git a/converter/other/pamtosvg/vector.h b/converter/other/pamtosvg/vector.h index 7dbf4dcb..65364c82 100644 --- a/converter/other/pamtosvg/vector.h +++ b/converter/other/pamtosvg/vector.h @@ -11,103 +11,79 @@ typedef struct { float dx, dy, dz; -} vector_type; +} Vector; -/* Consider a point as a vector from the origin. */ -vector_type -make_vector(float_coord const); +Vector +vector_fromPoint(Point const c); -/* And a vector as a point, i.e., a displacement from the origin. */ -float_coord -vector_to_point(vector_type const); +Vector +vector_fromTwoPoints(Point const c1, + Point const c2); + +Point +vector_toPoint_point(Vector const v); /* Definitions for these common operations can be found in any decent - linear algebra book, and most calculus books. */ + linear algebra book, and most calculus books. +*/ float -magnitude(vector_type const); +vector_magnitude(Vector const v); -vector_type -normalize(vector_type const); +Vector +vector_normalized(Vector const v); -vector_type -Vadd(vector_type const, - vector_type const); +Vector +vector_sum(Vector const addend, + Vector const adder); float -Vdot(vector_type const, - vector_type const); +vector_dotProduct(Vector const v1, + Vector const v2); -vector_type -Vmult_scalar(vector_type const, - float const); +Vector +vector_scaled(Vector const v, + float const r); float -Vangle(vector_type const in, - vector_type const out, - at_exception_type * const exP); - -/* These operations could have been named `P..._vector' just as well as - V..._point, so we may as well allow both names. */ - -#define Padd_vector Vadd_point - -float_coord -Vadd_point(float_coord const, - vector_type const); +vector_angle(Vector const inVector, + Vector const outVector, + at_exception_type * const exP); -#define Psubtract_vector Vsubtract_point +Point +vector_sumPoint(Point const c, + Vector const v); -float_coord -Vsubtract_point(float_coord const, - vector_type const); - -vector_type -Pdirection(float_coord const final, - float_coord const initial); - -/* This returns the rounded sum. */ -#define IPadd_vector Vadd_int_point +Point +vector_diffPoint(Point const c, + Vector const v); pm_pixelcoord -Vadd_int_point(pm_pixelcoord const c, - vector_type const v); - -/* Take the absolute value of both components. */ -vector_type -Vabs(vector_type const); - -/* Operations on points with real coordinates. It is not orthogonal, - but more convenient, to have the subtraction operator return a - vector, and the addition operator return a point. */ -vector_type -Psubtract(float_coord const, - float_coord const); +vector_sumIntPoint(pm_pixelcoord const c, + Vector const v); -vector_type -IPsubtract(pm_pixelcoord const coord1, - pm_pixelcoord const coord2); +Vector +vector_abs(Vector const v); -/* These are heavily used in spline fitting. */ +Vector +vector_pointDirection(Point const final, + Point const initial); -float_coord -Padd(float_coord const, - float_coord const); -float_coord -Pmult_scalar(float_coord const, - float const); +Vector +vector_IPointDiff(pm_pixelcoord const coord1, + pm_pixelcoord const coord2); -vector_type -Vhorizontal(void); +Vector +vector_horizontal(void); -vector_type -Vzero(void); +Vector +vector_zero(void); bool -Vequal(vector_type const, - vector_type const); +vector_equal(Vector const comparand, + Vector const comparator); #endif |