-
Notifications
You must be signed in to change notification settings - Fork 11
/
potracelib_demo.c
executable file
·119 lines (102 loc) · 3.24 KB
/
potracelib_demo.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// gcc -Wall -Os -lm potracelib_demo.c -o potracelib_demo
// ./potracelib_demo > potracelib_demo.eps
/* Copyright (C) 2001-2019 Peter Selinger.
This file is part of Potrace. It is free software and it is covered
by the GNU General Public License. See the file COPYING for details. */
/* A simple and self-contained demo of the potracelib API */
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include "potracelib.h"
#define WIDTH 250
#define HEIGHT 250
/* ---------------------------------------------------------------------- */
/* auxiliary bitmap functions */
/* macros for writing individual bitmap pixels */
#define BM_WORDSIZE ((int)sizeof(potrace_word))
#define BM_WORDBITS (8*BM_WORDSIZE)
#define BM_HIBIT (((potrace_word)1)<<(BM_WORDBITS-1))
#define bm_index(bm, x, y) (&bm_scanline(bm, y)[(x)/BM_WORDBITS])
#define bm_mask(x) (BM_HIBIT >> ((x) & (BM_WORDBITS-1)))
#define bm_range(x, a) ((int)(x) >= 0 && (int)(x) < (a))
#define bm_safe(bm, x, y) (bm_range(x, (bm)->w) && bm_range(y, (bm)->h))
#define BM_USET(bm, x, y) (*bm_index(bm, x, y) |= bm_mask(x))
#define BM_UCLR(bm, x, y) (*bm_index(bm, x, y) &= ~bm_mask(x))
#define BM_UPUT(bm, x, y, b) ((b) ? BM_USET(bm, x, y) : BM_UCLR(bm, x, y))
#define BM_PUT(bm, x, y, b) (bm_safe(bm, x, y) ? BM_UPUT(bm, x, y, b) : 0)
/* ---------------------------------------------------------------------- */
/* demo */
int main()
{
int x, y, i;
potrace_bitmap_t *bm;
potrace_param_t *param;
potrace_path_t *p;
potrace_state_t *st;
int n, *tag;
potrace_dpoint_t (*c)[3];
/* create a bitmap */
bm = bm_new(WIDTH, HEIGHT);
if (!bm) {
fprintf(stderr, "Error allocating bitmap: %s\n", strerror(errno));
return 1;
}
/* fill the bitmap with some pattern */
for (y=0; y<HEIGHT; y++) {
for (x=0; x<WIDTH; x++) {
BM_PUT(bm, x, y, ((x*x + y*y*y) % 10000 < 5000) ? 1 : 0);
}
}
/* set tracing parameters, starting from defaults */
param = potrace_param_default();
if (!param) {
fprintf(stderr, "Error allocating parameters: %s\n", strerror(errno));
return 1;
}
param->turdsize = 0;
/* trace the bitmap */
st = potrace_trace(param, bm);
if (!st || st->status != POTRACE_STATUS_OK) {
fprintf(stderr, "Error tracing bitmap: %s\n", strerror(errno));
return 1;
}
bm_free(bm);
/* output vector data, e.g. as a rudimentary EPS file */
printf("%%!PS-Adobe-3.0 EPSF-3.0\n");
printf("%%%%BoundingBox: 0 0 %d %d\n", WIDTH, HEIGHT);
printf("gsave\n");
/* draw each curve */
p = st->plist;
while (p != NULL) {
n = p->curve.n;
tag = p->curve.tag;
c = p->curve.c;
printf("%f %f moveto\n", c[n-1][2].x, c[n-1][2].y);
for (i=0; i<n; i++) {
switch (tag[i]) {
case POTRACE_CORNER:
printf("%f %f lineto\n", c[i][1].x, c[i][1].y);
printf("%f %f lineto\n", c[i][2].x, c[i][2].y);
break;
case POTRACE_CURVETO:
printf("%f %f %f %f %f %f curveto\n",
c[i][0].x, c[i][0].y,
c[i][1].x, c[i][1].y,
c[i][2].x, c[i][2].y);
break;
}
}
/* at the end of a group of a positive path and its negative
children, fill. */
if (p->next == NULL || p->next->sign == '+') {
printf("0 setgray fill\n");
}
p = p->next;
}
printf("grestore\n");
printf("%%EOF\n");
potrace_state_free(st);
potrace_param_free(param);
return 0;
}