static void out_splines (FILE * file, spline_list_array_type shape) { unsigned this_list; spline_list_type list; for (this_list = 0; this_list < SPLINE_LIST_ARRAY_LENGTH (shape); this_list++) { unsigned this_spline; spline_type first; /* Whether to fill or stroke */ gboolean stroke; list = SPLINE_LIST_ARRAY_ELT (shape, this_list); first = SPLINE_LIST_ELT (list, 0); stroke = shape.centerline || list.open; /* If stroke, set outline color and no fill, otherwise set fill * color and no outline */ fprintf(file, "%s((%g,%g,%g))\n", stroke ? "lp" : "fp", list.color.r / 255.0, list.color.g / 255.0, list.color.b / 255.0); fputs(stroke ? "fe()\n" : "le()\n", file); /* Start a bezier object */ fputs("b()\n", file); /* Move to the start point */ fprintf(file, "bs(%g,%g,0)\n", START_POINT(first).x, START_POINT(first).y); /* write the splines */ for (this_spline = 0; this_spline < SPLINE_LIST_LENGTH (list); this_spline++) { spline_type s = SPLINE_LIST_ELT (list, this_spline); if (SPLINE_DEGREE(s) == LINEARTYPE) fprintf(file, "bs(%g,%g,0)\n", END_POINT(s).x, END_POINT(s).y); else fprintf(file, "bc(%g,%g,%g,%g,%g,%g,0)\n", CONTROL1(s).x, CONTROL1(s).y, CONTROL2(s).x, CONTROL2(s).y, END_POINT(s).x, END_POINT(s).y); } /* End the bezier object. If it's stroked do nothing otherwise close the path. */ if (!stroke) fputs("bC()\n", file); } }
static void out_splines (FILE * epd_file, spline_list_array_type shape) { unsigned this_list; spline_list_type list; at_color last_color = {0,0,0}; for (this_list = 0; this_list < SPLINE_LIST_ARRAY_LENGTH (shape); this_list++) { unsigned this_spline; spline_type first; list = SPLINE_LIST_ARRAY_ELT (shape, this_list); first = SPLINE_LIST_ELT (list, 0); if (this_list == 0 || !at_color_equal(&list.color, &last_color)) { if (this_list > 0) { OUT_LINE ((shape.centerline || list.open) ? "S" : "f"); OUT_LINE("h"); } OUT4 ("%.3f %.3f %.3f %s\n", (double) list.color.r / 255.0, (double) list.color.g / 255.0, (double) list.color.b / 255.0, (shape.centerline || list.open) ? "RG" : "rg"); last_color = list.color; } OUT_COMMAND2 (START_POINT (first).x, START_POINT (first).y, "m"); for (this_spline = 0; this_spline < SPLINE_LIST_LENGTH (list); this_spline++) { spline_type s = SPLINE_LIST_ELT (list, this_spline); if (SPLINE_DEGREE (s) == LINEARTYPE) OUT_COMMAND2 (END_POINT (s).x, END_POINT (s).y, "l"); else OUT_COMMAND6 (CONTROL1 (s).x, CONTROL1 (s).y, CONTROL2 (s).x, CONTROL2 (s).y, END_POINT (s).x, END_POINT (s).y, "c"); } } if (SPLINE_LIST_ARRAY_LENGTH(shape) > 0) OUT_LINE ((shape.centerline || list.open) ? "S" : "f"); }
void text_output_char (bzr_char_type c) { unsigned this_list; spline_list_array_type shape = BZR_SHAPE (c); printf ("Character: 0x%x=%u", CHARCODE (c), CHARCODE (c)); if (isprint (CHARCODE (c))) printf (" (%c)", CHARCODE (c)); puts (":"); printf (" set width: %.3f.\n", CHAR_SET_WIDTH (c)); printf (" min/max col: %.3f/%.3f; min/max row: %.3f/%.3f.\n", BZR_CHAR_MIN_COL (c), BZR_CHAR_MAX_COL (c), BZR_CHAR_MIN_ROW (c), BZR_CHAR_MAX_ROW (c)); for (this_list = 0; this_list < SPLINE_LIST_ARRAY_LENGTH (shape); this_list++) { unsigned this_spline; spline_list_type list = SPLINE_LIST_ARRAY_ELT (shape, this_list); printf (" Outline #%u:\n", this_list); for (this_spline = 0; this_spline < SPLINE_LIST_LENGTH (list); this_spline++) { spline_type s = SPLINE_LIST_ELT (list, this_spline); if (SPLINE_DEGREE (s) == LINEAR) printf (" (%.3f,%.3f)--(%.3f,%.3f)", START_POINT (s).x, START_POINT (s).y, END_POINT (s).x, END_POINT (s).y); else printf (" (%.3f,%.3f)..ctrls(%.3f,%.3f)&(%.3f,%.3f)..(%.3f,%.3f)", START_POINT (s).x, START_POINT (s).y, CONTROL1 (s).x, CONTROL1 (s).y, CONTROL2 (s).x, CONTROL2 (s).y, END_POINT (s).x, END_POINT(s).y); puts (""); } } puts (""); }
static void out_splines (SWFMovie m, spline_list_array_type shape, int height) { unsigned this_list; color_type last_color = {0,0,0}; for (this_list = 0; this_list < SPLINE_LIST_ARRAY_LENGTH (shape); this_list++) { SWFShape k; unsigned this_spline; spline_list_type list = SPLINE_LIST_ARRAY_ELT (shape, this_list); spline_type first = SPLINE_LIST_ELT (list, 0); if (this_list == 0 || !COLOR_EQUAL(list.color, last_color)) { k = newSWFShape(); SWFShape_setRightFill(k, SWFShape_addSolidFill(k, list.color.r, list.color.g, list.color.b, 0xff)); last_color = list.color; } SWFShape_movePenTo(k, SWFSCALE*START_POINT(first).x, SWFSCALE*height - SWFSCALE*START_POINT(first).y); for (this_spline = 0; this_spline < SPLINE_LIST_LENGTH (list); this_spline++) { spline_type s = SPLINE_LIST_ELT (list, this_spline); if (SPLINE_DEGREE(s) == LINEARTYPE) { SWFShape_drawLineTo(k, SWFSCALE*END_POINT(s).x, SWFSCALE*height - SWFSCALE*END_POINT(s).y); } else { SWFShape_drawCubicTo (k, SWFSCALE*CONTROL1(s).x, SWFSCALE*height - SWFSCALE*CONTROL1(s).y, SWFSCALE*CONTROL2(s).x, SWFSCALE*height - SWFSCALE*CONTROL2(s).y, SWFSCALE*END_POINT(s).x, SWFSCALE*height - SWFSCALE*END_POINT(s).y); } } SWFMovie_add(m,k); } }
void print_spline (FILE *f, spline_type s) { if (SPLINE_DEGREE (s) == LINEAR) fprintf (f, "(%.3f,%.3f)--(%.3f,%.3f).\n", START_POINT (s).x, START_POINT (s).y, END_POINT (s).x, END_POINT (s).y); else if (SPLINE_DEGREE (s) == CUBIC) fprintf (f, "(%.3f,%.3f)..ctrls(%.3f,%.3f)&(%.3f,%.3f)..(%.3f,%.3f).\n", START_POINT (s).x, START_POINT (s).y, CONTROL1 (s).x, CONTROL1 (s).y, CONTROL2 (s).x, CONTROL2 (s).y, END_POINT (s).x, END_POINT (s).y); else { /* FATAL1 ("print_spline: strange degree (%d)", SPLINE_DEGREE (s)); */ } }
void x_output_char (char_info_type c, spline_list_array_type splines) { unsigned this_list; if (!wants_display) return; /* Draw the fitted lines a little thicker, so they'll be easier to see. */ XSetLineAttributes (display, gc, 1, LineSolid, CapButt, JoinMiter); for (this_list = 0; this_list < SPLINE_LIST_ARRAY_LENGTH (splines); this_list++) { unsigned this_spline; spline_list_type list = SPLINE_LIST_ARRAY_ELT (splines, this_list); for (this_spline = 0; this_spline < SPLINE_LIST_LENGTH (list); this_spline++) { spline_type s = SPLINE_LIST_ELT (list, this_spline); if (SPLINE_DEGREE (s) == LINEAR) { coordinate_type start = real_cartesian_to_offset_x (START_POINT (s)); coordinate_type end = real_cartesian_to_offset_x (END_POINT (s)); XDrawLine (display, pixmap, gc, X_LINE (start, end)); } else if (SPLINE_DEGREE (s) == CUBIC) digitize_spline (s); else FATAL1 ("x_output_char: Spline with degree %d", SPLINE_DEGREE (s)); } } /* If desired, make sure everything is visible, then wait for the user to hit return, so s/he can look at the results. */ if (display_stop) { char dummy; send_event (server_window, foserver_update_pixmap_atom, pixmap); XSync (display, False); if (verbose) putchar ('\n'); printf ("RET to continue: " ); scanf ("%c", &dummy); } }
static void out_splines(FILE * file, spline_list_array_type shape, int height) { unsigned this_list; spline_list_type list; at_color last_color = { 0, 0, 0 }; for (this_list = 0; this_list < SPLINE_LIST_ARRAY_LENGTH(shape); this_list++) { unsigned this_spline; spline_type first; list = SPLINE_LIST_ARRAY_ELT(shape, this_list); first = SPLINE_LIST_ELT(list, 0); if (this_list == 0 || !at_color_equal(&list.color, &last_color)) { if (this_list > 0) { if (!(shape.centerline || list.open)) fputs("z", file); fputs("\"/>\n", file); } fprintf(file, "<path style=\"%s:#%02x%02x%02x; %s:none;\" d=\"", (shape.centerline || list.open) ? "stroke" : "fill", list.color.r, list.color.g, list.color.b, (shape.centerline || list.open) ? "fill" : "stroke"); } fprintf(file, "M%g %g", START_POINT(first).x, height - START_POINT(first).y); for (this_spline = 0; this_spline < SPLINE_LIST_LENGTH(list); this_spline++) { spline_type s = SPLINE_LIST_ELT(list, this_spline); if (SPLINE_DEGREE(s) == LINEARTYPE) { fprintf(file, "L%g %g", END_POINT(s).x, height - END_POINT(s).y); } else { fprintf(file, "C%g %g %g %g %g %g", CONTROL1(s).x, height - CONTROL1(s).y, CONTROL2(s).x, height - CONTROL2(s).y, END_POINT(s).x, height - END_POINT(s).y); } last_color = list.color; } } if (!(shape.centerline || list.open)) fputs("z", file); if (SPLINE_LIST_ARRAY_LENGTH(shape) > 0) fputs("\"/>\n", file); }
static void outSplineList(FILE * const fileP, spline_list_type const splineList, unsigned int const height) { unsigned splineSeq; for (splineSeq = 0; splineSeq < SPLINE_LIST_LENGTH(splineList); ++splineSeq) { spline_type const spline = SPLINE_LIST_ELT(splineList, splineSeq); if (SPLINE_DEGREE(spline) == LINEARTYPE) { fprintf(fileP, "L%g %g", END_POINT(spline).x, height - END_POINT(spline).y); } else fprintf(fileP, "C%g %g %g %g %g %g", CONTROL1(spline).x, height - CONTROL1(spline).y, CONTROL2(spline).x, height - CONTROL2(spline).y, END_POINT(spline).x, height - END_POINT(spline).y); } }
spline_type new_spline (void) { real_coordinate_type coord = { -100.0, -100.0 }; spline_type spline; START_POINT (spline) = CONTROL1 (spline) = CONTROL2 (spline) = END_POINT (spline) = coord; SPLINE_DEGREE (spline) = -1; SPLINE_LINEARITY (spline) = 0; return spline; }
void metafont_output_char (bzr_char_type c) { unsigned this_list; spline_list_array_type shape = BZR_SHAPE (c); int offset = CHAR_LSB (c); fprintf (mf_file, "\nbeginchar (%d, %.2fu#, %.2fu#, %.2fu#);\n", CHARCODE (c), CHAR_SET_WIDTH (c), CHAR_HEIGHT (c), CHAR_DEPTH (c)); /* Go through the list of splines once, assigning the control points to Metafont variables. This allows us to produce more information on proofsheets. */ for (this_list = 0; this_list < SPLINE_LIST_ARRAY_LENGTH (shape); this_list++) { unsigned this_spline; spline_list_type list = SPLINE_LIST_ARRAY_ELT (shape, this_list); OUT_ZASSIGNMENT (INDENT "z%u\\%us", this_list, 0, START_POINT (SPLINE_LIST_ELT (list, 0))); for (this_spline = 0; this_spline < SPLINE_LIST_LENGTH (list); this_spline++) { spline_type s = SPLINE_LIST_ELT (list, this_spline); if (SPLINE_DEGREE (s) == CUBIC) { OUT_ZASSIGNMENT (INDENT "z%u\\%uc1", this_list, this_spline, CONTROL1 (s)); OUT_ZASSIGNMENT (INDENT "z%u\\%uc2", this_list, this_spline, CONTROL2 (s)); } /* The last point in the list is also the first point, and we don't want to output two variables for the same point. */ if (this_spline < SPLINE_LIST_LENGTH (list) - 1) OUT_ZASSIGNMENT (INDENT "z%u\\%u", this_list, this_spline, END_POINT (s)); } } /* Go through the list of splines again, outputting the path-construction commands. */ for (this_list = 0; this_list < SPLINE_LIST_ARRAY_LENGTH (shape); this_list++) { unsigned this_spline; spline_list_type list = SPLINE_LIST_ARRAY_ELT (shape, this_list); OUT2 (INDENT "fill_or_unfill z%u\\%us\n", this_list, 0); for (this_spline = 0; this_spline < SPLINE_LIST_LENGTH (list); this_spline++) { spline_type s = SPLINE_LIST_ELT (list, this_spline); if (SPLINE_DEGREE (s) == LINEAR) OUT_STRING (INDENT INDENT "--"); else { OUT_STRING (INDENT INDENT "..controls "); OUT2 ("z%u\\%uc1 and ", this_list, this_spline); OUT2 ("z%u\\%uc2..", this_list, this_spline); } if (this_spline < SPLINE_LIST_LENGTH (list) - 1) OUT2 ("z%u\\%u\n", this_list, this_spline); } OUT_STRING ("cycle;\n"); } /* The plain Metafont `labels' command makes it possible to produce proofsheets with all the points labeled. We always want labels for the starting and ending points, and possibly labels for the control points on each spline, so we have our own command `proof_labels', defined in `bzrsetup.mf'. */ OUT_LINE (INDENT "proof_labels ("); for (this_list = 0; this_list < SPLINE_LIST_ARRAY_LENGTH (shape); this_list++) { unsigned this_spline; spline_list_type list = SPLINE_LIST_ARRAY_ELT (shape, this_list); for (this_spline = 0; this_spline < SPLINE_LIST_LENGTH (list); this_spline++) OUT2 (INDENT INDENT "%u\\%u,\n", this_list, this_spline); } OUT_STRING (");\n"); OUT_STATEMENT ("endchar"); mf_char_output_p[CHARCODE (c)] = true; }
/****************************************************************************** * This function outputs the DXF code which produces the polylines */ static void out_splines (FILE * dxf_file, spline_list_array_type shape) { unsigned this_list; double startx, starty; xypnt_head_rec *vec, *res; xypnt pnt, pnt_old = {0,0}; char fin, new_layer=0, layerstr[10]; int i, first_seg = 1, idx; strcpy(layerstr, "C1"); for (this_list = 0; this_list < SPLINE_LIST_ARRAY_LENGTH (shape); this_list++) { unsigned this_spline; at_color last_color = {0,0,0}; spline_list_type list = SPLINE_LIST_ARRAY_ELT (shape, this_list); spline_type first = SPLINE_LIST_ELT (list, 0); at_color curr_color = curr_color = (list.clockwise && shape.background_color != NULL)? *(shape.background_color) : list.color; if (this_list == 0 || !at_color_equal(&curr_color, &last_color)) { if (!(curr_color.r==0 && curr_color.g==0 && curr_color.b==0) || !color_check) { idx = GetIndexByRGBValue(curr_color.r, curr_color.g, curr_color.b); sprintf(layerstr, "C%d", idx); new_layer = 1; last_color = curr_color; } } startx = START_POINT (first).x; starty = START_POINT (first).y; if (!first_seg) { if (ROUND(startx*RESOLUTION) != pnt_old.xp || ROUND(starty*RESOLUTION) != pnt_old.yp || new_layer) { /* must begin new polyline */ new_layer = 0; fprintf(dxf_file, " 0\nSEQEND\n 8\n%s\n", layerstr); fprintf(dxf_file, " 0\nPOLYLINE\n 8\n%s\n 66\n1\n 10\n%f\n 20\n%f\n", layerstr, startx, starty); fprintf(dxf_file, " 0\nVERTEX\n 8\n%s\n 10\n%f\n 20\n%f\n", layerstr, startx, starty); pnt_old.xp = ROUND(startx*RESOLUTION); pnt_old.yp = ROUND(starty*RESOLUTION); } } else { fprintf(dxf_file, " 0\nPOLYLINE\n 8\n%s\n 66\n1\n 10\n%f\n 20\n%f\n", layerstr, startx, starty); fprintf(dxf_file, " 0\nVERTEX\n 8\n%s\n 10\n%f\n 20\n%f\n", layerstr, startx, starty); pnt_old.xp = ROUND(startx*RESOLUTION); pnt_old.yp = ROUND(starty*RESOLUTION); } for (this_spline = 0; this_spline < SPLINE_LIST_LENGTH (list); this_spline++) { spline_type s = SPLINE_LIST_ELT (list, this_spline); if (SPLINE_DEGREE (s) == LINEARTYPE) { if (ROUND(startx*RESOLUTION) != pnt_old.xp || ROUND(starty*RESOLUTION) != pnt_old.yp || new_layer) { /* must begin new polyline */ new_layer = 0; fprintf(dxf_file, " 0\nSEQEND\n 8\n%s\n", layerstr); fprintf(dxf_file, " 0\nPOLYLINE\n 8\n%s\n 66\n1\n 10\n%f\n 20\n%f\n", layerstr, startx, starty); fprintf(dxf_file, " 0\nVERTEX\n 8\n%s\n 10\n%f\n 20\n%f\n", layerstr, startx, starty); } fprintf(dxf_file, " 0\nVERTEX\n 8\n%s\n 10\n%f\n 20\n%f\n", layerstr, END_POINT(s).x, END_POINT (s).y); startx = END_POINT(s).x; starty = END_POINT(s).y; pnt_old.xp = ROUND(startx*RESOLUTION); pnt_old.yp = ROUND(starty*RESOLUTION); } else { vec = (struct xypnt_head_t *)calloc(1, sizeof (struct xypnt_head_t)); pnt.xp = ROUND(startx*RESOLUTION); pnt.yp = ROUND(starty*RESOLUTION); xypnt_add_pnt(vec, pnt); pnt.xp = ROUND(CONTROL1(s).x*RESOLUTION); pnt.yp = ROUND(CONTROL1 (s).y*RESOLUTION); xypnt_add_pnt(vec, pnt); pnt.xp = ROUND(CONTROL2(s).x*RESOLUTION); pnt.yp = ROUND(CONTROL2 (s).y*RESOLUTION); xypnt_add_pnt(vec, pnt); pnt.xp = ROUND(END_POINT(s).x*RESOLUTION); pnt.yp = ROUND(END_POINT (s).y*RESOLUTION); xypnt_add_pnt(vec, pnt); res = NULL; /* Note that spline order can be max. 4 since we have only 4 spline control points */ bspline_to_lines(vec, &res, 4, 4, 10000); xypnt_first_pnt(res, &pnt, &fin); if (pnt.xp != pnt_old.xp || pnt.yp != pnt_old.yp || new_layer) { /* must begin new polyline */ new_layer = 0; fprintf(dxf_file, " 0\nSEQEND\n 8\n%s\n", layerstr); fprintf(dxf_file, " 0\nPOLYLINE\n 8\n%s\n 66\n1\n 10\n%f\n 20\n%f\n", layerstr, (double)pnt.xp/RESOLUTION, (double)pnt.yp/RESOLUTION); fprintf(dxf_file, " 0\nVERTEX\n 8\n%s\n 10\n%f\n 20\n%f\n", layerstr, (double)pnt.xp/RESOLUTION, (double)pnt.yp/RESOLUTION); } i = 0; while (!fin) { if (i) { fprintf(dxf_file, " 0\nVERTEX\n 8\n%s\n 10\n%f\n 20\n%f\n", layerstr, (double)pnt.xp/RESOLUTION, (double)pnt.yp/RESOLUTION); } xypnt_next_pnt(res, &pnt, &fin); i++; } pnt_old = pnt; xypnt_dispose_list(&vec); xypnt_dispose_list(&res); startx = END_POINT(s).x; starty = END_POINT(s).y; free(res); free(vec); } } first_seg = 0; last_color = curr_color; } fprintf(dxf_file, " 0\nSEQEND\n 8\n0\n"); }
static void digitize_spline (spline_type s) { coordinate_type start = real_cartesian_to_offset_x (START_POINT (s)), control1 = real_cartesian_to_offset_x (CONTROL1 (s)), control2 = real_cartesian_to_offset_x (CONTROL2 (s)), end = real_cartesian_to_offset_x (END_POINT (s)); /* These a_i are the coefficients of the polynomial p(t) = a_3 t^3 + a_2 t^2 + a_1 t + a_0, computed by expanding the Bernshte\u in polynomial z(t) = (1 - t)^3z_1 + 3(1 - t)^2tz_2 + 3(1 - t)t^2z_3 + t^3z_4, where z_1 is the starting point of the spline, z_2 and z_3 the control points, and z_4 the ending point. We have two such polynomials p(t), one for the x-coordinate, one for the y-coordinate. So everything here is done with points and vectors, instead of just numbers. a_0 = x_0 a_1 = 3(x_1 - x_0) a_2 = 3(x_0 + x_2 - 2x_1) a_3 = x_3 - x_0 + 3(x_1 - x_2) */ coordinate_type /* a0 = start, */ a1 = IPmult_scalar (IPsubtractP (control1, start), 3), a2 = IPmult_scalar (IPsubtractP (IPadd (start, control2), IPmult_scalar (control1, 2)), 3), a3 = IPadd (IPsubtractP (end, start), IPmult_scalar (IPsubtractP (control1, control2), 3)); /* The step size. We want to use the length of the bounding rectangle to compute this, instead of the distance between the starting point and the ending point, since the latter will be zero if the spline is cyclic. */ real factor = int_distance (control1, start) + int_distance (control2, control1) + int_distance (end, control2) + int_distance (start, end), /* Avoid division by zero, in pathological cases. (We will just produce one point. */ delta = 1.0 / MAX (factor, 1), delta_squared = delta * delta, delta_cubed = delta_squared * delta; /* The current position. */ coordinate_type p = start, previous_p = { start.x - 1, 0 }; /* The real current position. */ real_coordinate_type real_p = int_to_real_coord (p); /* The first three forward differences evaluated at t = 0. */ vector_type d = make_vector (Padd (IPmult_real (a3, delta_cubed), Padd (IPmult_real (a2, delta_squared), IPmult_real (a1, delta)))), d2 = make_vector (Padd (IPmult_real (a3, 6 * delta_cubed), IPmult_real (a2, 2 * delta_squared))), d3 = make_vector (IPmult_real (a3, 6 * delta_cubed)); /* Where we will collect the points to output. */ unsigned point_count = 0; XPoint point_list[(unsigned) (1.0 / delta) + 1]; real t; for (t = 0.0; t <= 1.0; t += delta) { if (!IPequal (p, previous_p)) { point_list[point_count].x = p.x; point_list[point_count].y = p.y; point_count++; previous_p = p; } /* We must keep track of the current position in unrounded coordinates, so the calculations do not lose precision. */ real_p = Padd_vector (real_p, d); p.x = ROUND (real_p.x); p.y = ROUND (real_p.y); d = Vadd (d, d2); d2 = Vadd (d2, d3); /* d3 is constant with respect to t. */ } #if 0 /* GDB under system V doesn't grok XPoint, so here's a way to print out the points we find. */ { unsigned i; for (i = 0; i < point_count; i++) printf ("(%d,%d)", point_list[i].x, point_list[i].y); puts (""); } #endif XDrawPoints (display, pixmap, gc, point_list, point_count, CoordModeOrigin); }
static void do_points (spline_list_array_type in_splines, gint32 image_ID) { gint32 vectors; gint32 stroke; gint i, j; gboolean have_points = FALSE; spline_list_type spline_list; /* check if there really is something to do... */ for (i = 0; i < SPLINE_LIST_ARRAY_LENGTH (in_splines); i++) { spline_list = SPLINE_LIST_ARRAY_ELT (in_splines, i); /* Ignore single points that are on their own */ if (SPLINE_LIST_LENGTH (spline_list) < 2) continue; have_points = TRUE; break; } if (!have_points) return; vectors = gimp_vectors_new (image_ID, _("Selection")); for (j = 0; j < SPLINE_LIST_ARRAY_LENGTH (in_splines); j++) { spline_type seg; spline_list = SPLINE_LIST_ARRAY_ELT (in_splines, j); /* Ignore single points that are on their own */ if (SPLINE_LIST_LENGTH (spline_list) < 2) continue; seg = SPLINE_LIST_ELT (spline_list, 0); stroke = gimp_vectors_bezier_stroke_new_moveto (vectors, START_POINT (seg).x, START_POINT (seg).y); for (i = 0; i < SPLINE_LIST_LENGTH (spline_list); i++) { seg = SPLINE_LIST_ELT (spline_list, i); if (SPLINE_DEGREE (seg) == LINEAR) gimp_vectors_bezier_stroke_lineto (vectors, stroke, END_POINT (seg).x, END_POINT (seg).y); else if (SPLINE_DEGREE (seg) == CUBIC) gimp_vectors_bezier_stroke_cubicto (vectors, stroke, CONTROL1 (seg).x, CONTROL1 (seg).y, CONTROL2 (seg).x, CONTROL2 (seg).y, END_POINT (seg).x, END_POINT (seg).y); else g_warning ("print_spline: strange degree (%d)", SPLINE_DEGREE (seg)); } gimp_vectors_stroke_close (vectors, stroke); /* transform to GIMPs coordinate system, taking the selections * bounding box into account */ gimp_vectors_stroke_scale (vectors, stroke, 1.0, -1.0); gimp_vectors_stroke_translate (vectors, stroke, sel_x1, sel_y1 + sel_height + 1); } gimp_image_insert_vectors (image_ID, vectors, -1, -1); }
static void out_fig_splines(FILE * file, spline_list_array_type shape, int llx, int lly, int urx, int ury, at_exception_type * exp) { unsigned this_list; /* int fig_colour, fig_depth, i; */ int fig_colour, fig_fill, fig_width, fig_subt, fig_spline_close, i; int *spline_colours; /* add an array of colours for splines (one for each group) create palette hash */ /* Need to create hash table for colours */ XMALLOC(spline_colours, (sizeof(int) * SPLINE_LIST_ARRAY_LENGTH(shape))); /* Preload the big 8 */ fig_col_init(); /* Load the colours from the splines */ for (this_list = 0; this_list < SPLINE_LIST_ARRAY_LENGTH(shape); this_list++) { spline_list_type list = SPLINE_LIST_ARRAY_ELT(shape, this_list); at_color curr_color = (list.clockwise && shape.background_color != NULL) ? *(shape.background_color) : list.color; spline_colours[this_list] = get_fig_colour(curr_color, exp); } /* Output colours */ if (LAST_FIG_COLOUR > 32) { for (i = 32; i < LAST_FIG_COLOUR; i++) { fprintf(file, "0 %d #%.2x%.2x%.2x\n", i, fig_colour_map[i].c.r, fig_colour_map[i].c.g, fig_colour_map[i].c.b); } } /* Each "spline list" in the array appears to be a group of splines */ fig_depth = SPLINE_LIST_ARRAY_LENGTH(shape) + 20; if (fig_depth > 999) { fig_depth = 999; } for (this_list = 0; this_list < SPLINE_LIST_ARRAY_LENGTH(shape); this_list++) { unsigned this_spline; spline_list_type list = SPLINE_LIST_ARRAY_ELT(shape, this_list); /* store the spline points in two arrays, control weights in another */ int *pointx, *pointy; gfloat *contrl; int pointcount = 0, is_spline = 0, j; int maxlength = SPLINE_LIST_LENGTH(list) * 5 + 1; XMALLOC(pointx, maxlength * sizeof(int)); XMALLOC(pointy, maxlength * sizeof(int)); XMALLOC(contrl, maxlength * sizeof(gfloat)); if (list.clockwise) { fig_colour = FIG_WHITE; } else { fig_colour = spline_colours[this_list]; } fig_spline_close = 5; for (this_spline = 0; this_spline < SPLINE_LIST_LENGTH(list); this_spline++) { spline_type s = SPLINE_LIST_ELT(list, this_spline); if (pointcount == 0) { pointx[pointcount] = FIG_X(START_POINT(s).x); pointy[pointcount] = FIG_Y(START_POINT(s).y); contrl[pointcount] = (gfloat) 0.0; fig_addtobbox(START_POINT(s).x, START_POINT(s).y); pointcount++; } /* Apparently START_POINT for one spline section is same as END_POINT for previous section - should gfloatly test for this */ if (SPLINE_DEGREE(s) == LINEARTYPE) { pointx[pointcount] = FIG_X(END_POINT(s).x); pointy[pointcount] = FIG_Y(END_POINT(s).y); contrl[pointcount] = (gfloat) 0.0; fig_addtobbox(START_POINT(s).x, START_POINT(s).y); pointcount++; } else { /* Assume Bezier like spline */ /* Convert approximated bezier to interpolated X Spline */ gfloat temp; for (temp = (gfloat) 0.2; temp < (gfloat) 0.9; temp += (gfloat) 0.2) { pointx[pointcount] = FIG_X(bezpnt(temp, START_POINT(s).x, CONTROL1(s).x, CONTROL2(s).x, END_POINT(s).x)); pointy[pointcount] = FIG_Y(bezpnt(temp, START_POINT(s).y, CONTROL1(s).y, CONTROL2(s).y, END_POINT(s).y)); contrl[pointcount] = (gfloat) - 1.0; pointcount++; } pointx[pointcount] = FIG_X(END_POINT(s).x); pointy[pointcount] = FIG_Y(END_POINT(s).y); contrl[pointcount] = (gfloat) 0.0; fig_addtobbox(START_POINT(s).x, START_POINT(s).y); fig_addtobbox(CONTROL1(s).x, CONTROL1(s).y); fig_addtobbox(CONTROL2(s).x, CONTROL2(s).y); fig_addtobbox(END_POINT(s).x, END_POINT(s).y); pointcount++; is_spline = 1; } } if (shape.centerline) { fig_fill = -1; fig_width = 1; fig_spline_close = 4; } else { /* Use zero width lines - unit width is too thick */ fig_fill = 20; fig_width = 0; fig_spline_close = 5; } if (is_spline != 0) { fig_new_depth(); fprintf(file, "3 %d 0 %d %d %d %d 0 %d 0.00 0 0 0 %d\n", fig_spline_close, fig_width, fig_colour, fig_colour, fig_depth, fig_fill, pointcount); /* Print out points */ j = 0; for (i = 0; i < pointcount; i++) { j++; if (j == 1) { fprintf(file, "\t"); } fprintf(file, "%d %d ", pointx[i], pointy[i]); if (j == 8) { fprintf(file, "\n"); j = 0; } } if (j != 0) { fprintf(file, "\n"); } j = 0; /* Print out control weights */ for (i = 0; i < pointcount; i++) { j++; if (j == 1) { fprintf(file, "\t"); } fprintf(file, "%f ", contrl[i]); if (j == 8) { fprintf(file, "\n"); j = 0; } } if (j != 0) { fprintf(file, "\n"); } } else { /* Polygons can be handled better as polygons */ fig_subt = 3; if (pointcount == 2) { if ((pointx[0] == pointx[1]) && (pointy[0] == pointy[1])) { /* Point */ fig_new_depth(); fprintf(file, "2 1 0 1 %d %d %d 0 -1 0.000 0 0 -1 0 0 1\n", fig_colour, fig_colour, fig_depth); fprintf(file, "\t%d %d\n", pointx[0], pointy[0]); } else { /* Line segment? */ fig_new_depth(); fprintf(file, "2 1 0 1 %d %d %d 0 -1 0.000 0 0 -1 0 0 2\n", fig_colour, fig_colour, fig_depth); fprintf(file, "\t%d %d %d %d\n", pointx[0], pointy[0], pointx[1], pointy[1]); } } else { if ((pointcount == 3) && (pointx[0] == pointx[2]) && (pointy[0] == pointy[2])) { /* Line segment? */ fig_new_depth(); fprintf(file, "2 1 0 1 %d %d %d 0 -1 0.000 0 0 -1 0 0 2\n", fig_colour, fig_colour, fig_depth); fprintf(file, "\t%d %d %d %d\n", pointx[0], pointy[0], pointx[1], pointy[1]); } else { if ((pointx[0] != pointx[pointcount - 1]) || (pointy[0] != pointy[pointcount - 1])) { if (shape.centerline) { fig_subt = 1; } else { /* Need to have last point same as first for polygon */ pointx[pointcount] = pointx[0]; pointy[pointcount] = pointy[0]; pointcount++; } } fig_new_depth(); fprintf(file, "2 %d 0 %d %d %d %d 0 %d 0.00 0 0 0 0 0 %d\n", fig_subt, fig_width, fig_colour, fig_colour, fig_depth, fig_fill, pointcount); /* Print out points */ j = 0; for (i = 0; i < pointcount; i++) { j++; if (j == 1) { fprintf(file, "\t"); } fprintf(file, "%d %d ", pointx[i], pointy[i]); if (j == 8) { fprintf(file, "\n"); j = 0; } } if (j != 0) { fprintf(file, "\n"); } } } } /* fig_depth--; */ if (fig_depth < 0) { fig_depth = 0; } free(pointx); free(pointy); free(contrl); } free(spline_colours); return; }
static void out_splines(FILE * er_file, spline_list_array_type shape, unsigned width, unsigned height, at_output_opts_type * opts) { unsigned this_list, corresp_pt; double x0, y0, x1, y1, x2, y2, corresp_length; for (this_list = 0; this_list < SPLINE_LIST_ARRAY_LENGTH(shape); this_list++) { unsigned this_spline; spline_type prev; spline_list_type list = SPLINE_LIST_ARRAY_ELT(shape, this_list); unsigned length = SPLINE_LIST_LENGTH(list); unsigned out_length = (list.open || length == 1 ? length + 1 : length); fprintf(er_file, "Shape = {\n"); fprintf(er_file, "\t#Shape Number %d\n", this_list + 1); fprintf(er_file, "\tGroup = Default\n"); fprintf(er_file, "\tType = Source\n"); fprintf(er_file, "\tRoll = A\n"); fprintf(er_file, "\tOpaque = True\n"); fprintf(er_file, "\tLocked = False\n"); fprintf(er_file, "\tWarp = True\n"); fprintf(er_file, "\tCookieCut = True\n"); fprintf(er_file, "\tColorCorrect = True\n"); fprintf(er_file, "\tPrecision = 10\n"); fprintf(er_file, "\tClosed = %s\n", (list.open ? "False" : "True")); fprintf(er_file, "\tTween = Linear\n"); fprintf(er_file, "\tBPoints = %d\n", out_length); fprintf(er_file, "\tCPoints = %d\n", NUM_CORRESP_POINTS); fprintf(er_file, "\tFormKey = {\n"); fprintf(er_file, "\t\tFrame = 1\n"); fprintf(er_file, "\t\tPointList = {\n"); prev = PREV_SPLINE_LIST_ELT(list, 0); if (list.open || length == 1) SPLINE_DEGREE(prev) = (polynomial_degree) - 1; for (this_spline = 0; this_spline < length; this_spline++) { spline_type s = SPLINE_LIST_ELT(list, this_spline); if (SPLINE_DEGREE(prev) == -1) { x0 = START_POINT(s).x; y0 = START_POINT(s).y; } else if (SPLINE_DEGREE(prev) == CUBICTYPE) { x0 = CONTROL2(prev).x; y0 = CONTROL2(prev).y; } else { /* if (SPLINE_DEGREE(prev) == LINEARTYPE) */ x0 = START_POINT(s).x; y0 = START_POINT(s).y; } x1 = START_POINT(s).x; y1 = START_POINT(s).y; if (SPLINE_DEGREE(s) == CUBICTYPE) { x2 = CONTROL1(s).x; y2 = CONTROL1(s).y; } else { x2 = START_POINT(s).x; y2 = START_POINT(s).y; } fprintf(er_file, "\t\t\t(%f, %f), (%f, %f), (%f, %f),\n", x0 / width, y0 / height, x1 / width, y1 / height, x2 / width, y2 / height); prev = s; } if (list.open || length == 1) { x0 = CONTROL2(prev).x; y0 = CONTROL2(prev).y; x2 = x1 = END_POINT(prev).x; y2 = y1 = END_POINT(prev).y; fprintf(er_file, "\t\t\t(%f, %f), (%f, %f), (%f, %f),\n", x0 / width, y0 / height, x1 / width, y1 / height, x2 / width, y2 / height); } /* Close PointList and enclosing FormKey. */ fprintf(er_file, "\t\t}\n\n\t}\n\n"); if (shape.centerline && shape.preserve_width) { gfloat w = (gfloat) 1.0 / (shape.width_weight_factor); fprintf(er_file, "\tWeightKey = {\n"); fprintf(er_file, "\t\tFrame = 1\n"); fprintf(er_file, "\t\tPointList = {\n"); prev = PREV_SPLINE_LIST_ELT(list, 0); if (list.open || length == 1) SPLINE_DEGREE(prev) = (polynomial_degree) - 1; for (this_spline = 0; this_spline < length; this_spline++) { spline_type s = SPLINE_LIST_ELT(list, this_spline); if (SPLINE_DEGREE(prev) == -1) x0 = START_POINT(s).z; else if (SPLINE_DEGREE(prev) == CUBICTYPE) x0 = CONTROL2(prev).z; else /* if (SPLINE_DEGREE(prev) == LINEARTYPE) */ x0 = START_POINT(s).z; x1 = START_POINT(s).z; if (SPLINE_DEGREE(s) == CUBICTYPE) x2 = CONTROL1(s).z; else x2 = START_POINT(s).z; fprintf(er_file, "\t\t\t%g, %g, %g,\n", x0 * w, x1 * w, x2 * w); prev = s; } if (list.open || length == 1) { x0 = CONTROL2(prev).z; x2 = x1 = END_POINT(prev).z; fprintf(er_file, "\t\t\t%g, %g, %g,\n", x0 * w, x1 * w, x2 * w); } /* Close PointList and enclosing WeightKey. */ fprintf(er_file, "\t\t}\n\n\t}\n\n"); } fprintf(er_file, "\tCorrKey = {\n"); fprintf(er_file, "\t\tFrame = 1\n"); fprintf(er_file, "\t\tPointList = {\n"); fprintf(er_file, "\t\t\t0"); corresp_length = out_length - (list.open ? 1.0 : 2.0); for (corresp_pt = 1; corresp_pt < NUM_CORRESP_POINTS; corresp_pt++) { fprintf(er_file, ", %g", corresp_length * corresp_pt / (NUM_CORRESP_POINTS - (list.open ? 1.0 : 0.0))); } /* Close PointList and enclosing CorrKey. */ fprintf(er_file, "\n\t\t}\n\n\t}\n\n"); /* Close Shape. */ fprintf(er_file, "}\n\n"); } }