potracer 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ext/potracer/extconf.h +4 -0
- data/ext/potracer/extconf.rb +11 -0
- data/ext/potracer/potracer.c +309 -0
- data/ext/potracer/potracer.h +28 -0
- data/lib/potracer.rb +13 -0
- metadata +50 -0
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'mkmf'
|
2
|
+
|
3
|
+
RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
|
4
|
+
|
5
|
+
extension_name = 'potracer/potracer'
|
6
|
+
|
7
|
+
raise "potracelib.h not found" unless have_header('potracelib.h')
|
8
|
+
raise "lib potrace not found" unless have_library('potrace', 'potrace_version')
|
9
|
+
|
10
|
+
create_header
|
11
|
+
create_makefile(extension_name)
|
@@ -0,0 +1,309 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
|
3
|
+
#include "extconf.h"
|
4
|
+
#include "potracelib.h"
|
5
|
+
|
6
|
+
#include "potracer.h"
|
7
|
+
|
8
|
+
static void
|
9
|
+
rb_progress (double progress, void *callback)
|
10
|
+
{
|
11
|
+
rb_funcall((VALUE)callback, rb_intern("call"), 1, rb_int_new(100 * progress));
|
12
|
+
}
|
13
|
+
|
14
|
+
static VALUE
|
15
|
+
params_alloc (VALUE klass)
|
16
|
+
{
|
17
|
+
potrace_param_t *params = potrace_param_default();
|
18
|
+
return Data_Wrap_Struct(klass, 0, potrace_param_free, params);
|
19
|
+
}
|
20
|
+
|
21
|
+
static VALUE
|
22
|
+
params_get_turdsize (VALUE klass)
|
23
|
+
{
|
24
|
+
potrace_param_t *params;
|
25
|
+
Data_Get_Struct(klass, potrace_param_t, params);
|
26
|
+
return rb_int_new(params->turdsize);
|
27
|
+
}
|
28
|
+
|
29
|
+
static VALUE
|
30
|
+
params_set_turdsize (VALUE klass, VALUE size)
|
31
|
+
{
|
32
|
+
potrace_param_t *params;
|
33
|
+
Data_Get_Struct(klass, potrace_param_t, params);
|
34
|
+
params->turdsize = NUM2INT(size);
|
35
|
+
return size;
|
36
|
+
}
|
37
|
+
|
38
|
+
static VALUE
|
39
|
+
params_get_turnpolicy (VALUE klass)
|
40
|
+
{
|
41
|
+
potrace_param_t *params;
|
42
|
+
Data_Get_Struct(klass, potrace_param_t, params);
|
43
|
+
return rb_int_new(params->turnpolicy);
|
44
|
+
}
|
45
|
+
|
46
|
+
static VALUE
|
47
|
+
params_set_turnpolicy (VALUE klass, VALUE policy)
|
48
|
+
{
|
49
|
+
potrace_param_t *params;
|
50
|
+
Data_Get_Struct(klass, potrace_param_t, params);
|
51
|
+
params->turnpolicy = NUM2INT(policy);
|
52
|
+
return policy;
|
53
|
+
}
|
54
|
+
|
55
|
+
static VALUE
|
56
|
+
params_get_alphamax (VALUE klass)
|
57
|
+
{
|
58
|
+
potrace_param_t *params;
|
59
|
+
Data_Get_Struct(klass, potrace_param_t, params);
|
60
|
+
return rb_float_new(params->alphamax);
|
61
|
+
}
|
62
|
+
|
63
|
+
static VALUE
|
64
|
+
params_set_alphamax (VALUE klass, VALUE max)
|
65
|
+
{
|
66
|
+
potrace_param_t *params;
|
67
|
+
Data_Get_Struct(klass, potrace_param_t, params);
|
68
|
+
params->alphamax = NUM2DBL(max);
|
69
|
+
return max;
|
70
|
+
}
|
71
|
+
|
72
|
+
static VALUE
|
73
|
+
params_get_opticurve (VALUE klass)
|
74
|
+
{
|
75
|
+
potrace_param_t *params;
|
76
|
+
Data_Get_Struct(klass, potrace_param_t, params);
|
77
|
+
return (params->opticurve == 1) ? Qtrue : Qfalse;
|
78
|
+
}
|
79
|
+
|
80
|
+
static VALUE
|
81
|
+
params_set_opticurve_true (VALUE klass)
|
82
|
+
{
|
83
|
+
potrace_param_t *params;
|
84
|
+
Data_Get_Struct(klass, potrace_param_t, params);
|
85
|
+
params->opticurve = 1;
|
86
|
+
return Qtrue;
|
87
|
+
}
|
88
|
+
|
89
|
+
static VALUE
|
90
|
+
params_set_opticurve_false (VALUE klass)
|
91
|
+
{
|
92
|
+
potrace_param_t *params;
|
93
|
+
Data_Get_Struct(klass, potrace_param_t, params);
|
94
|
+
params->opticurve = 0;
|
95
|
+
return Qfalse;
|
96
|
+
}
|
97
|
+
|
98
|
+
static VALUE
|
99
|
+
params_get_opttolerance (VALUE klass)
|
100
|
+
{
|
101
|
+
potrace_param_t *params;
|
102
|
+
Data_Get_Struct(klass, potrace_param_t, params);
|
103
|
+
return rb_float_new(params->opttolerance);
|
104
|
+
}
|
105
|
+
|
106
|
+
static VALUE
|
107
|
+
params_set_opttolerance (VALUE klass, VALUE tolerance)
|
108
|
+
{
|
109
|
+
potrace_param_t *params;
|
110
|
+
Data_Get_Struct(klass, potrace_param_t, params);
|
111
|
+
params->opttolerance = NUM2DBL(tolerance);
|
112
|
+
return tolerance;
|
113
|
+
}
|
114
|
+
|
115
|
+
static void
|
116
|
+
trace_mark (potrace_state_t *state)
|
117
|
+
{
|
118
|
+
}
|
119
|
+
|
120
|
+
static VALUE
|
121
|
+
trace_alloc (VALUE klass)
|
122
|
+
{
|
123
|
+
potrace_state_t *trace = NULL;
|
124
|
+
return Data_Wrap_Struct(klass, trace_mark, potrace_state_free, trace);
|
125
|
+
}
|
126
|
+
|
127
|
+
static VALUE
|
128
|
+
trace_trace (VALUE obj, VALUE bitmap, VALUE params)
|
129
|
+
{
|
130
|
+
const potrace_bitmap_t *bm;
|
131
|
+
potrace_param_t *param;
|
132
|
+
VALUE p;
|
133
|
+
|
134
|
+
Data_Get_Struct(bitmap, potrace_bitmap_t, bm);
|
135
|
+
Data_Get_Struct(params, potrace_param_t, param);
|
136
|
+
|
137
|
+
if (rb_block_given_p()) {
|
138
|
+
p = rb_block_proc();
|
139
|
+
param->progress.callback = &rb_progress;
|
140
|
+
param->progress.data = (void *)p;
|
141
|
+
}
|
142
|
+
|
143
|
+
DATA_PTR(obj) = potrace_trace(param, bm);
|
144
|
+
|
145
|
+
rb_gc_mark(bitmap);
|
146
|
+
rb_gc_mark(params);
|
147
|
+
|
148
|
+
return obj;
|
149
|
+
}
|
150
|
+
|
151
|
+
static VALUE
|
152
|
+
trace_as_array (VALUE klass)
|
153
|
+
{
|
154
|
+
VALUE result = rb_ary_new();
|
155
|
+
potrace_path_t *p;
|
156
|
+
int i, n, *tag;
|
157
|
+
potrace_dpoint_t (*c)[3];
|
158
|
+
potrace_state_t *trace = NULL;
|
159
|
+
Data_Get_Struct(klass, potrace_state_t, trace);
|
160
|
+
|
161
|
+
if (trace->status == POTRACE_STATUS_OK) {
|
162
|
+
p = trace->plist;
|
163
|
+
while (p != NULL) {
|
164
|
+
n = p->curve.n;
|
165
|
+
tag = p->curve.tag;
|
166
|
+
c = p->curve.c;
|
167
|
+
MOVE_TO(result, c[n-1][2]);
|
168
|
+
for (i = 0; i < n; i++) {
|
169
|
+
switch (tag[i]) {
|
170
|
+
case POTRACE_CORNER:
|
171
|
+
LINE_TO(result, c[i][1]);
|
172
|
+
LINE_TO(result, c[i][2]);
|
173
|
+
break;
|
174
|
+
case POTRACE_CURVETO:
|
175
|
+
CURVE_TO(result, c[i]);
|
176
|
+
break;
|
177
|
+
}
|
178
|
+
}
|
179
|
+
p = p->next;
|
180
|
+
}
|
181
|
+
}
|
182
|
+
|
183
|
+
return result;
|
184
|
+
}
|
185
|
+
|
186
|
+
static void
|
187
|
+
bitmap_mark (potrace_bitmap_t *bm)
|
188
|
+
{
|
189
|
+
}
|
190
|
+
|
191
|
+
static void
|
192
|
+
bitmap_free (potrace_bitmap_t *bm)
|
193
|
+
{
|
194
|
+
if (bm != NULL) {
|
195
|
+
free(bm->map);
|
196
|
+
}
|
197
|
+
free(bm);
|
198
|
+
}
|
199
|
+
|
200
|
+
static void
|
201
|
+
bitmap_init(int argc, VALUE *argv, VALUE klass)
|
202
|
+
{
|
203
|
+
potrace_bitmap_t *bm;
|
204
|
+
}
|
205
|
+
|
206
|
+
static VALUE
|
207
|
+
bitmap_new (int argc, VALUE *argv, VALUE klass)
|
208
|
+
{
|
209
|
+
int i, j;
|
210
|
+
potrace_bitmap_t *bm;
|
211
|
+
VALUE bdata, row;
|
212
|
+
|
213
|
+
bdata = Data_Make_Struct(klass, potrace_bitmap_t, bitmap_mark, bitmap_free, bm);
|
214
|
+
bm->w = (argc > 0) ? NUM2INT(argv[0]) : BM_WIDTH;
|
215
|
+
bm->h = (argc > 1) ? NUM2INT(argv[1]) : BM_HEIGHT;
|
216
|
+
bm->dy = (bm->w + BM_WORDBITS - 1) / BM_WORDBITS;
|
217
|
+
bm->map = ALLOC_N(potrace_word, bm->dy * bm->h * BM_WORDSIZE);
|
218
|
+
|
219
|
+
if (argc > 2) {
|
220
|
+
for (i = 0; i < bm->h; i++) {
|
221
|
+
row = rb_ary_entry(argv[2], (long)i);
|
222
|
+
for (j = 0; j < bm->w; j++) {
|
223
|
+
BM_PUT(bm, j, i, NUM2INT(rb_ary_entry(row, (long)j)));
|
224
|
+
}
|
225
|
+
}
|
226
|
+
}
|
227
|
+
|
228
|
+
return bdata;
|
229
|
+
}
|
230
|
+
|
231
|
+
static VALUE
|
232
|
+
bitmap_get_width (VALUE klass)
|
233
|
+
{
|
234
|
+
potrace_bitmap_t *bm;
|
235
|
+
Data_Get_Struct(klass, potrace_bitmap_t, bm);
|
236
|
+
return rb_int_new(bm->w);
|
237
|
+
}
|
238
|
+
|
239
|
+
static VALUE
|
240
|
+
bitmap_get_height (VALUE klass)
|
241
|
+
{
|
242
|
+
potrace_bitmap_t *bm;
|
243
|
+
Data_Get_Struct(klass, potrace_bitmap_t, bm);
|
244
|
+
return rb_int_new(bm->h);
|
245
|
+
}
|
246
|
+
|
247
|
+
static VALUE
|
248
|
+
bitmap_as_array (VALUE klass)
|
249
|
+
{
|
250
|
+
int i, j;
|
251
|
+
potrace_bitmap_t *bm;
|
252
|
+
VALUE result, row;
|
253
|
+
Data_Get_Struct(klass, potrace_bitmap_t, bm);
|
254
|
+
result = rb_ary_new2((long)bm->h);
|
255
|
+
for (i = 0; i < bm->h; i++) {
|
256
|
+
row = rb_ary_new2((long)bm->w);
|
257
|
+
for (j = 0; j < bm->w; j++) {
|
258
|
+
rb_ary_store(row, (long)j, rb_int_new(BM_GET(bm, j, i)));
|
259
|
+
}
|
260
|
+
rb_ary_store(result, (long)i, row);
|
261
|
+
}
|
262
|
+
|
263
|
+
return result;
|
264
|
+
}
|
265
|
+
|
266
|
+
void
|
267
|
+
Init_potracer () {
|
268
|
+
// Define the Potracer module
|
269
|
+
rb_mPotracer = rb_define_module("Potracer");
|
270
|
+
rb_define_const(rb_mPotracer, "VERSION", rb_str_new2(potrace_version()));
|
271
|
+
|
272
|
+
// Define the Trace class inside the Potracer module
|
273
|
+
rb_cPotracerTrace = rb_define_class_under(rb_mPotracer, "Trace", rb_cObject);
|
274
|
+
rb_define_alloc_func(rb_cPotracerTrace, trace_alloc);
|
275
|
+
rb_define_protected_method(rb_cPotracerTrace, "do_trace", trace_trace, 2);
|
276
|
+
rb_define_method(rb_cPotracerTrace, "to_a", trace_as_array, 0);
|
277
|
+
|
278
|
+
// Define the Params class inside the Potracer module
|
279
|
+
rb_cPotracerParams = rb_define_class_under(rb_mPotracer, "Params", rb_cObject);
|
280
|
+
rb_define_alloc_func(rb_cPotracerParams, params_alloc);
|
281
|
+
rb_define_method(rb_cPotracerParams, "turd_size", params_get_turdsize, 0);
|
282
|
+
rb_define_method(rb_cPotracerParams, "turd_size=", params_set_turdsize, 1);
|
283
|
+
rb_define_method(rb_cPotracerParams, "turn_policy", params_get_turnpolicy, 0);
|
284
|
+
rb_define_method(rb_cPotracerParams, "turn_policy=", params_set_turnpolicy, 1);
|
285
|
+
rb_define_method(rb_cPotracerParams, "alpha_max", params_get_alphamax, 0);
|
286
|
+
rb_define_method(rb_cPotracerParams, "alpha_max=", params_set_alphamax, 1);
|
287
|
+
rb_define_method(rb_cPotracerParams, "optimized?", params_get_opticurve, 0);
|
288
|
+
rb_define_method(rb_cPotracerParams, "optimize!", params_set_opticurve_true, 0);
|
289
|
+
rb_define_method(rb_cPotracerParams, "unoptimize!", params_set_opticurve_false, 0);
|
290
|
+
rb_define_method(rb_cPotracerParams, "tolerance", params_get_opttolerance, 0);
|
291
|
+
rb_define_method(rb_cPotracerParams, "tolerance=", params_set_opttolerance, 1);
|
292
|
+
|
293
|
+
// Define the Turnpolicy module inside the Potracer module
|
294
|
+
rb_mTurnpolicy = rb_define_module_under(rb_mPotracer, "Turnpolicy");
|
295
|
+
rb_define_const(rb_mTurnpolicy, "BLACK", rb_int_new(POTRACE_TURNPOLICY_BLACK));
|
296
|
+
rb_define_const(rb_mTurnpolicy, "WHITE", rb_int_new(POTRACE_TURNPOLICY_WHITE));
|
297
|
+
rb_define_const(rb_mTurnpolicy, "LEFT", rb_int_new(POTRACE_TURNPOLICY_LEFT));
|
298
|
+
rb_define_const(rb_mTurnpolicy, "RIGHT", rb_int_new(POTRACE_TURNPOLICY_RIGHT));
|
299
|
+
rb_define_const(rb_mTurnpolicy, "MINORITY", rb_int_new(POTRACE_TURNPOLICY_MINORITY));
|
300
|
+
rb_define_const(rb_mTurnpolicy, "MAJORITY", rb_int_new(POTRACE_TURNPOLICY_MAJORITY));
|
301
|
+
rb_define_const(rb_mTurnpolicy, "RANDOM", rb_int_new(POTRACE_TURNPOLICY_RANDOM));
|
302
|
+
|
303
|
+
// Define the Bitmap class inside the Potracer module
|
304
|
+
rb_cPotracerBitmap = rb_define_class_under(rb_mPotracer, "Bitmap", rb_cObject);
|
305
|
+
rb_define_singleton_method(rb_cPotracerBitmap, "new", bitmap_new, -1);
|
306
|
+
rb_define_method(rb_cPotracerBitmap, "width", bitmap_get_width, 0);
|
307
|
+
rb_define_method(rb_cPotracerBitmap, "height", bitmap_get_height, 0);
|
308
|
+
rb_define_method(rb_cPotracerBitmap, "to_a", bitmap_as_array, 0);
|
309
|
+
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#define BM_WIDTH 250
|
2
|
+
#define BM_HEIGHT 250
|
3
|
+
#define BM_WORDSIZE ((int)sizeof(potrace_word))
|
4
|
+
#define BM_WORDBITS (8*BM_WORDSIZE)
|
5
|
+
#define BM_HIBIT (((potrace_word)1)<<(BM_WORDBITS-1))
|
6
|
+
#define bm_scanline(bm, y) ((bm)->map + (y)*(bm)->dy)
|
7
|
+
#define bm_index(bm, x, y) (&bm_scanline(bm, y)[(x)/BM_WORDBITS])
|
8
|
+
#define bm_mask(x) (BM_HIBIT >> ((x) & (BM_WORDBITS-1)))
|
9
|
+
#define bm_range(x, a) ((int)(x) >= 0 && (int)(x) < (a))
|
10
|
+
#define bm_safe(bm, x, y) (bm_range(x, (bm)->w) && bm_range(y, (bm)->h))
|
11
|
+
#define BM_USET(bm, x, y) (*bm_index(bm, x, y) |= bm_mask(x))
|
12
|
+
#define BM_UCLR(bm, x, y) (*bm_index(bm, x, y) &= ~bm_mask(x))
|
13
|
+
#define BM_UPUT(bm, x, y, b) ((b) ? BM_USET(bm, x, y) : BM_UCLR(bm, x, y))
|
14
|
+
#define BM_PUT(bm, x, y, b) (bm_safe(bm, x, y) ? BM_UPUT(bm, x, y, b) : 0)
|
15
|
+
#define BM_UGET(bm, x, y) ((*bm_index(bm, x, y) & bm_mask(x)) != 0)
|
16
|
+
#define BM_GET(bm, x, y) (bm_safe(bm, x, y) ? BM_UGET(bm, x, y) : 0)
|
17
|
+
#define STRSYM(s) ID2SYM(rb_intern(s))
|
18
|
+
#define RB_PAIR(p) rb_float_new(p.x), rb_float_new(p.y)
|
19
|
+
#define PUSH_TR(ar, n, s, ps...) rb_ary_push(ar, rb_ary_new3(n, STRSYM(s), ps))
|
20
|
+
#define MOVE_TO(ar, c) PUSH_TR(ar, 3, "moveto", RB_PAIR(c))
|
21
|
+
#define LINE_TO(ar, c) PUSH_TR(ar, 3, "lineto", RB_PAIR(c))
|
22
|
+
#define CURVE_TO(ar, c) PUSH_TR(ar, 7, "curveto", RB_PAIR(c[0]), RB_PAIR(c[1]), RB_PAIR(c[2]))
|
23
|
+
|
24
|
+
static VALUE rb_mPotracer;
|
25
|
+
static VALUE rb_mTurnpolicy;
|
26
|
+
static VALUE rb_cPotracerTrace;
|
27
|
+
static VALUE rb_cPotracerParams;
|
28
|
+
static VALUE rb_cPotracerBitmap;
|
data/lib/potracer.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require_relative 'potracer/potracer'
|
2
|
+
|
3
|
+
module Potracer
|
4
|
+
class Trace
|
5
|
+
def trace(bitmap=nil, params=nil, &block)
|
6
|
+
if block_given?
|
7
|
+
self.do_trace(bitmap || @bitmap, params || @params, &block)
|
8
|
+
else
|
9
|
+
self.do_trace(bitmap || @bitmap, params || @params)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
metadata
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: potracer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Kenny Parnell
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-10-03 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Ruby bindings for the potrace library.
|
15
|
+
email: k.parnell@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions:
|
18
|
+
- ext/potracer/extconf.rb
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- lib/potracer.rb
|
22
|
+
- ext/potracer/extconf.h
|
23
|
+
- ext/potracer/potracer.h
|
24
|
+
- ext/potracer/potracer.c
|
25
|
+
- ext/potracer/extconf.rb
|
26
|
+
homepage: https://github.com/kparnell/potracer
|
27
|
+
licenses: []
|
28
|
+
post_install_message:
|
29
|
+
rdoc_options: []
|
30
|
+
require_paths:
|
31
|
+
- lib
|
32
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
requirements: []
|
45
|
+
rubyforge_project:
|
46
|
+
rubygems_version: 1.8.23
|
47
|
+
signing_key:
|
48
|
+
specification_version: 3
|
49
|
+
summary: Ruby bindings for potrace.
|
50
|
+
test_files: []
|