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);
    }
}
Exemple #2
0
static void
out_splines(FILE *                 const fileP,
            spline_list_array_type const shape,
            unsigned int           const height) {

    unsigned listSeq;
    pixel lastColor;
    
    PPM_ASSIGN(lastColor, 0, 0, 0);
    
    for (listSeq = 0;
         listSeq < SPLINE_LIST_ARRAY_LENGTH(shape);
         ++listSeq) {
        
        spline_list_type const splineList =
            SPLINE_LIST_ARRAY_ELT(shape, listSeq);
        spline_type const first = SPLINE_LIST_ELT(splineList, 0);

        if (listSeq == 0 || !PPM_EQUAL(splineList.color, lastColor)) {
            if (listSeq > 0) {
                /* Close previous <path> element */
                if (!(shape.centerline || splineList.open))
                    fputs("z", fileP);
                fputs("\"/>\n", fileP);
            }
            /* Open new <path> element */
            fprintf(fileP, "<path style=\"%s:#%02x%02x%02x; %s:none;\" d=\"",
                    (shape.centerline || splineList.open) ? "stroke" : "fill",
                    PPM_GETR(splineList.color),
                    PPM_GETG(splineList.color),
                    PPM_GETB(splineList.color),
                    (shape.centerline || splineList.open) ? "fill" : "stroke");
        }
        fprintf(fileP, "M%g %g",
                START_POINT(first).x, height - START_POINT(first).y);

        outSplineList(fileP, splineList, height);

        lastColor = splineList.color;
    }

    if (SPLINE_LIST_ARRAY_LENGTH(shape) > 0) {
        spline_list_type const lastSplineList =
            SPLINE_LIST_ARRAY_ELT(shape, SPLINE_LIST_ARRAY_LENGTH(shape)-1);

        if (!(shape.centerline || lastSplineList.open))
            fputs("z", fileP);

        /* Close last <path> element */
        fputs("\"/>\n", fileP);
    }
}
Exemple #3
0
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");
}
Exemple #4
0
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 ("");
}
Exemple #5
0
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);
    }
}
Exemple #6
0
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)); */
    }
}
Exemple #7
0
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);
    }
}
Exemple #8
0
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);
}
Exemple #9
0
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;
}
Exemple #10
0
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;
}
Exemple #11
0
/******************************************************************************
* 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");

}
Exemple #12
0
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);
}
Exemple #14
0
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;
}
Exemple #15
0
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");
  }
}