File indexing completed on 2024-12-22 04:04:14

0001 /* Copyright (C) 2001-2019 Peter Selinger.
0002    This file is part of Potrace. It is free software and it is covered
0003    by the GNU General Public License. See the file COPYING for details. */
0004 
0005 /* A simple and self-contained demo of the potracelib API */
0006 
0007 #ifdef HAVE_CONFIG_H
0008 #include <config.h>
0009 #endif
0010 
0011 #include <stdio.h>
0012 #include <string.h>
0013 #include <errno.h>
0014 #include <stdlib.h>
0015 
0016 #include "potracelib.h"
0017 
0018 #define WIDTH 250
0019 #define HEIGHT 250
0020 
0021 /* ---------------------------------------------------------------------- */
0022 /* auxiliary bitmap functions */
0023 
0024 /* macros for writing individual bitmap pixels */
0025 #define BM_WORDSIZE ((int)sizeof(potrace_word))
0026 #define BM_WORDBITS (8*BM_WORDSIZE)
0027 #define BM_HIBIT (((potrace_word)1)<<(BM_WORDBITS-1))
0028 #define bm_scanline(bm, y) ((bm)->map + (y)*(bm)->dy)
0029 #define bm_index(bm, x, y) (&bm_scanline(bm, y)[(x)/BM_WORDBITS])
0030 #define bm_mask(x) (BM_HIBIT >> ((x) & (BM_WORDBITS-1)))
0031 #define bm_range(x, a) ((int)(x) >= 0 && (int)(x) < (a))
0032 #define bm_safe(bm, x, y) (bm_range(x, (bm)->w) && bm_range(y, (bm)->h))
0033 #define BM_USET(bm, x, y) (*bm_index(bm, x, y) |= bm_mask(x))
0034 #define BM_UCLR(bm, x, y) (*bm_index(bm, x, y) &= ~bm_mask(x))
0035 #define BM_UPUT(bm, x, y, b) ((b) ? BM_USET(bm, x, y) : BM_UCLR(bm, x, y))
0036 #define BM_PUT(bm, x, y, b) (bm_safe(bm, x, y) ? BM_UPUT(bm, x, y, b) : 0)
0037 
0038 /* return new un-initialized bitmap. NULL with errno on error */
0039 static potrace_bitmap_t *bm_new(int w, int h) {
0040   potrace_bitmap_t *bm;
0041   int dy = (w + BM_WORDBITS - 1) / BM_WORDBITS;
0042 
0043   bm = (potrace_bitmap_t *) malloc(sizeof(potrace_bitmap_t));
0044   if (!bm) {
0045     return NULL;
0046   }
0047   bm->w = w;
0048   bm->h = h;
0049   bm->dy = dy;
0050   bm->map = (potrace_word *) calloc(h, dy * BM_WORDSIZE);
0051   if (!bm->map) {
0052     free(bm);
0053     return NULL;
0054   }
0055   return bm;
0056 }
0057 
0058 /* free a bitmap */
0059 static void bm_free(potrace_bitmap_t *bm) {
0060   if (bm != NULL) {
0061     free(bm->map);
0062   }
0063   free(bm);
0064 }
0065 
0066 /* ---------------------------------------------------------------------- */
0067 /* demo */
0068 
0069 int main() {
0070   int x, y, i;
0071   potrace_bitmap_t *bm;
0072   potrace_param_t *param;
0073   potrace_path_t *p;
0074   potrace_state_t *st;
0075   int n, *tag;
0076   potrace_dpoint_t (*c)[3];
0077 
0078   /* create a bitmap */
0079   bm = bm_new(WIDTH, HEIGHT);
0080   if (!bm) {
0081     fprintf(stderr, "Error allocating bitmap: %s\n", strerror(errno)); 
0082     return 1;
0083   }
0084 
0085   /* fill the bitmap with some pattern */
0086   for (y=0; y<HEIGHT; y++) {
0087     for (x=0; x<WIDTH; x++) {
0088       BM_PUT(bm, x, y, ((x*x + y*y*y) % 10000 < 5000) ? 1 : 0);
0089     }
0090   }
0091 
0092   /* set tracing parameters, starting from defaults */
0093   param = potrace_param_default();
0094   if (!param) {
0095     fprintf(stderr, "Error allocating parameters: %s\n", strerror(errno)); 
0096     return 1;
0097   }
0098   param->turdsize = 0;
0099 
0100   /* trace the bitmap */
0101   st = potrace_trace(param, bm);
0102   if (!st || st->status != POTRACE_STATUS_OK) {
0103     fprintf(stderr, "Error tracing bitmap: %s\n", strerror(errno));
0104     return 1;
0105   }
0106   bm_free(bm);
0107   
0108   /* output vector data, e.g. as a rudimentary EPS file */
0109   printf("%%!PS-Adobe-3.0 EPSF-3.0\n");
0110   printf("%%%%BoundingBox: 0 0 %d %d\n", WIDTH, HEIGHT);
0111   printf("gsave\n");
0112 
0113   /* draw each curve */
0114   p = st->plist;
0115   while (p != NULL) {
0116     n = p->curve.n;
0117     tag = p->curve.tag;
0118     c = p->curve.c;
0119     printf("%f %f moveto\n", c[n-1][2].x, c[n-1][2].y);
0120     for (i=0; i<n; i++) {
0121       switch (tag[i]) {
0122       case POTRACE_CORNER:
0123     printf("%f %f lineto\n", c[i][1].x, c[i][1].y);
0124     printf("%f %f lineto\n", c[i][2].x, c[i][2].y);
0125     break;
0126       case POTRACE_CURVETO:
0127     printf("%f %f %f %f %f %f curveto\n", 
0128            c[i][0].x, c[i][0].y,
0129            c[i][1].x, c[i][1].y,
0130            c[i][2].x, c[i][2].y);
0131     break;
0132       }
0133     }
0134     /* at the end of a group of a positive path and its negative
0135        children, fill. */
0136     if (p->next == NULL || p->next->sign == '+') {
0137       printf("0 setgray fill\n");
0138     }
0139     p = p->next;
0140   }
0141   printf("grestore\n");
0142   printf("%%EOF\n");
0143   
0144   potrace_state_free(st);
0145   potrace_param_free(param);
0146 
0147   return 0;
0148 }