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 }