rbclipper 6.4.2.5.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,530 @@
1
+ /*
2
+ * Clipper Ruby Bindings
3
+ * Copyright 2010 Mike Owens <http://mike.filespanker.com/>
4
+ * Changed by Dag Rende for Clipper after 2.9
5
+ *
6
+ * Released under the same terms as Clipper.
7
+ *
8
+ */
9
+
10
+ #include "clipper.hpp"
11
+ #include <ruby.h>
12
+
13
+ #ifndef DBL2NUM
14
+ # define DBL2NUM rb_float_new
15
+ #endif
16
+
17
+ using namespace std;
18
+ using namespace ClipperLib;
19
+
20
+ static ID id_even_odd;
21
+ static ID id_non_zero;
22
+ static ID id_positive;
23
+ static ID id_negative;
24
+ static ID id_polygons;
25
+ static ID id_ex_polygons;
26
+ static ID id_jtSquare;
27
+ static ID id_jtMiter;
28
+ static ID id_jtRound;
29
+ static ID id_etClosedPolygon;
30
+ static ID id_etClosedLine;
31
+ static ID id_etOpenButt;
32
+ static ID id_etOpenSquare;
33
+ static ID id_etOpenRound;
34
+
35
+ static inline Clipper*
36
+ XCLIPPER(VALUE x)
37
+ {
38
+ Clipper* clipper;
39
+ Data_Get_Struct(x, Clipper, clipper);
40
+ return clipper;
41
+ }
42
+
43
+ static inline ClipperOffset*
44
+ XCLIPPEROFFSET(VALUE x)
45
+ {
46
+ ClipperOffset* clipperOffset;
47
+ Data_Get_Struct(x, ClipperOffset, clipperOffset);
48
+ return clipperOffset;
49
+ }
50
+
51
+ static inline PolyFillType
52
+ sym_to_filltype(VALUE sym)
53
+ {
54
+ ID inp = rb_to_id(sym);
55
+
56
+ if (inp == id_even_odd) {
57
+ return pftEvenOdd;
58
+ } else if (inp == id_non_zero) {
59
+ return pftNonZero;
60
+ } else if (inp == id_positive) {
61
+ return pftPositive;
62
+ } else if (inp == id_negative) {
63
+ return pftNegative;
64
+ }
65
+
66
+ rb_raise(rb_eArgError, "%s", "Expected :even_odd, :non_zero, :positive or :negative");
67
+ }
68
+
69
+ static inline EndType
70
+ sym_to_endtype(VALUE sym)
71
+ {
72
+ ID inp = rb_to_id(sym);
73
+
74
+ if (inp == id_etClosedPolygon) {
75
+ return etClosedPolygon;
76
+ } else if (inp == id_etClosedLine) {
77
+ return etClosedLine;
78
+ } else if (inp == id_etOpenButt) {
79
+ return etOpenButt;
80
+ } else if (inp == id_etOpenSquare) {
81
+ return etOpenSquare;
82
+ } else if (inp == id_etOpenRound) {
83
+ return etOpenRound;
84
+ }
85
+
86
+ rb_raise(rb_eArgError, "%s", "Expected :etClosedPolygon, :etClosedLine or :etOpenButt or :etOpenSquare or :etOpenRound");
87
+ }
88
+
89
+ static inline JoinType
90
+ sym_to_jointype(VALUE sym)
91
+ {
92
+ ID inp = rb_to_id(sym);
93
+
94
+ if (inp == id_jtSquare) {
95
+ return jtSquare;
96
+ } else if (inp == id_jtMiter) {
97
+ return jtMiter;
98
+ } else if (inp == id_jtRound) {
99
+ return jtRound;
100
+ }
101
+
102
+ rb_raise(rb_eArgError, "%s", "Expected :jtSquare, :jtMiter or :jtRound");
103
+ }
104
+
105
+ extern "C" {
106
+
107
+ static inline IntPoint
108
+ xy_to_intpoint(VALUE px, VALUE py, double multiplier) {
109
+ return IntPoint((long64)(NUM2DBL(px) * multiplier), (long64)(NUM2DBL(py) * multiplier));
110
+ }
111
+
112
+ static void
113
+ ary_to_polygon(VALUE ary, ClipperLib::Path* poly, double multiplier)
114
+ {
115
+ const char* earg =
116
+ "Paths have format: [[p0_x, p0_y], [p1_x, p1_y], ...]";
117
+
118
+ Check_Type(ary, T_ARRAY);
119
+
120
+ for(long i = 0; i != RARRAY_LEN(ary); i++) {
121
+ VALUE sub = rb_ary_entry(ary, i);
122
+ Check_Type(sub, T_ARRAY);
123
+
124
+ if(RARRAY_LEN(sub) != 2) {
125
+ rb_raise(rb_eArgError, "%s", earg);
126
+ }
127
+
128
+ VALUE px = rb_ary_entry(sub, 0);
129
+ VALUE py = rb_ary_entry(sub, 1);
130
+ poly->push_back(IntPoint((long64)(NUM2DBL(px) * multiplier), (long64)(NUM2DBL(py) * multiplier)));
131
+ }
132
+ }
133
+
134
+ static void
135
+ arys_to_polygons(VALUE polygonsValue, ClipperLib::Paths* polygons, const double multiplier)
136
+ {
137
+ for(long i = 0; i != RARRAY_LEN(polygonsValue); i++) {
138
+ VALUE sub = rb_ary_entry(polygonsValue, i);
139
+ Check_Type(sub, T_ARRAY);
140
+
141
+ ClipperLib::Path tmp;
142
+ ary_to_polygon(sub, &tmp, multiplier);
143
+ polygons->push_back(tmp);
144
+ }
145
+ }
146
+
147
+ static void
148
+ rbclipper_free(void* ptr)
149
+ {
150
+ delete (Clipper*) ptr;
151
+ }
152
+
153
+ static void
154
+ rbclipperoffset_free(void* ptr)
155
+ {
156
+ delete (ClipperOffset*) ptr;
157
+ }
158
+
159
+ static VALUE
160
+ rbclipper_new(VALUE klass)
161
+ {
162
+ Clipper* ptr = new Clipper;
163
+ VALUE r = Data_Wrap_Struct(klass, 0, rbclipper_free, ptr);
164
+ rb_obj_call_init(r, 0, 0);
165
+ rb_iv_set(r, "@multiplier", INT2NUM(1048576));
166
+ return r;
167
+ }
168
+
169
+ static VALUE
170
+ rbclipperoffset_new(VALUE klass)
171
+ {
172
+ ClipperOffset* ptr = new ClipperOffset;
173
+ VALUE r = Data_Wrap_Struct(klass, 0, rbclipperoffset_free, ptr);
174
+ rb_obj_call_init(r, 0, 0);
175
+ rb_iv_set(r, "@multiplier", INT2NUM(1048576));
176
+ return r;
177
+ }
178
+
179
+ static VALUE
180
+ rbclipper_add_polygon_internal(VALUE self, VALUE polygon,
181
+ PolyType polytype, bool closed = true)
182
+ {
183
+ ClipperLib::Path tmp;
184
+ double multiplier = NUM2DBL(rb_iv_get(self, "@multiplier"));
185
+ ary_to_polygon(polygon, &tmp, multiplier);
186
+ XCLIPPER(self)->AddPath(tmp, polytype, closed);
187
+ return Qnil;
188
+ }
189
+
190
+ static VALUE
191
+ rbclipper_add_polygons_internal(VALUE self, VALUE polygonsValue, PolyType polytype, bool closed = true) {
192
+ Paths tmp;
193
+ const double multiplier = NUM2DBL(rb_iv_get(self, "@multiplier"));
194
+ arys_to_polygons(polygonsValue, &tmp, multiplier);
195
+ XCLIPPER(self)->AddPaths(tmp, polytype, closed);
196
+ return Qnil;
197
+ }
198
+
199
+ static VALUE
200
+ rbclipper_minkowski_sum(VALUE self, VALUE patternValue, VALUE pathsValue, bool isClosed = true) {
201
+ Paths paths;
202
+ const double multiplier = NUM2DBL(rb_iv_get(self, "@multiplier"));
203
+ arys_to_polygons(pathsValue, &paths, multiplier);
204
+
205
+ Path pattern;
206
+ ary_to_polygon(patternValue, &pattern, multiplier);
207
+
208
+ Paths solution;
209
+ ClipperLib::MinkowskiSum(pattern, paths, solution, isClosed);
210
+
211
+ const double inv_multiplier = 1.0 / multiplier;
212
+
213
+ VALUE r = rb_ary_new();
214
+ for(Paths::iterator i = solution.begin(); i != solution.end(); ++i) {
215
+ VALUE sub = rb_ary_new();
216
+ for(Path::iterator p = i->begin(); p != i->end(); ++p) {
217
+ rb_ary_push(sub, rb_ary_new3(2, DBL2NUM(p->X * inv_multiplier), DBL2NUM(p->Y * inv_multiplier)));
218
+ }
219
+ rb_ary_push(r, sub);
220
+ }
221
+ return r;
222
+ }
223
+
224
+ static VALUE
225
+ rbclipper_minkowski_diff(VALUE self, VALUE poly1v, VALUE poly2v) {
226
+ const double multiplier = NUM2DBL(rb_iv_get(self, "@multiplier"));
227
+ Path poly1;
228
+ ary_to_polygon(poly1v, &poly1, multiplier);
229
+ Path poly2;
230
+ ary_to_polygon(poly2v, &poly2, multiplier);
231
+
232
+ Paths solution;
233
+ ClipperLib::MinkowskiDiff(poly1, poly2, solution);
234
+
235
+ const double inv_multiplier = 1.0 / multiplier;
236
+
237
+ VALUE r = rb_ary_new();
238
+ for(Paths::iterator i = solution.begin(); i != solution.end(); ++i) {
239
+ VALUE sub = rb_ary_new();
240
+ for(Path::iterator p = i->begin(); p != i->end(); ++p) {
241
+ rb_ary_push(sub, rb_ary_new3(2, DBL2NUM(p->X * inv_multiplier), DBL2NUM(p->Y * inv_multiplier)));
242
+ }
243
+ rb_ary_push(r, sub);
244
+ }
245
+ return r;
246
+ }
247
+
248
+ static VALUE
249
+ rbclipper_add_subject_polyline(VALUE self, VALUE polyline)
250
+ {
251
+ return rbclipper_add_polygon_internal(self, polyline, ptSubject, false);
252
+ }
253
+
254
+ static VALUE
255
+ rbclipper_add_subject_polylines(VALUE self, VALUE polylines)
256
+ {
257
+ return rbclipper_add_polygons_internal(self, polylines, ptSubject, false);
258
+ }
259
+
260
+ static VALUE
261
+ rbclipper_add_subject_polygon(VALUE self, VALUE polygon)
262
+ {
263
+ return rbclipper_add_polygon_internal(self, polygon, ptSubject);
264
+ }
265
+
266
+ static VALUE
267
+ rbclipper_add_clip_polygon(VALUE self, VALUE polygon)
268
+ {
269
+ return rbclipper_add_polygon_internal(self, polygon, ptClip);
270
+ }
271
+
272
+ static VALUE
273
+ rbclipper_add_subject_polygons(VALUE self, VALUE polygons)
274
+ {
275
+ return rbclipper_add_polygons_internal(self, polygons, ptSubject);
276
+ }
277
+
278
+ static VALUE
279
+ rbclipper_add_clip_polygons(VALUE self, VALUE polygons)
280
+ {
281
+ return rbclipper_add_polygons_internal(self, polygons, ptClip);
282
+ }
283
+
284
+ static VALUE
285
+ rbclipper_clear(VALUE self)
286
+ {
287
+ XCLIPPER(self)->Clear();
288
+ return Qnil;
289
+ }
290
+
291
+ static VALUE
292
+ rbclipperoffset_clear(VALUE self)
293
+ {
294
+ XCLIPPEROFFSET(self)->Clear();
295
+ return Qnil;
296
+ }
297
+
298
+ static VALUE
299
+ rbclipper_multiplier(VALUE self)
300
+ {
301
+ return rb_iv_get(self, "@multiplier");
302
+ }
303
+
304
+ static VALUE
305
+ rbclipper_multiplier_eq(VALUE self, VALUE multiplier)
306
+ {
307
+ rb_iv_set(self, "@multiplier", multiplier);
308
+ return multiplier;
309
+ }
310
+
311
+ static VALUE
312
+ rbclipper_orientation(VALUE self, VALUE polygonValue)
313
+ {
314
+ double multiplier = NUM2DBL(rb_iv_get(self, "@multiplier"));
315
+ ClipperLib::Path polygon;
316
+ ary_to_polygon(polygonValue, &polygon, multiplier);
317
+
318
+ return ClipperLib::Orientation(polygon) ? Qtrue : Qfalse;
319
+ }
320
+
321
+ static VALUE
322
+ rbclipper_area(VALUE self, VALUE polygonValue)
323
+ {
324
+ double multiplier = NUM2DBL(rb_iv_get(self, "@multiplier"));
325
+ ClipperLib::Path polygon;
326
+ ary_to_polygon(polygonValue, &polygon, multiplier);
327
+
328
+ return DBL2NUM(ClipperLib::Area(polygon) / multiplier / multiplier);
329
+ }
330
+
331
+ static VALUE
332
+ rbclipper_point_in_polygon(VALUE self, VALUE px, VALUE py, VALUE polygonValue)
333
+ {
334
+ double multiplier = NUM2DBL(rb_iv_get(self, "@multiplier"));
335
+ ClipperLib::Path polygon;
336
+ ary_to_polygon(polygonValue, &polygon, multiplier);
337
+
338
+ return INT2NUM(ClipperLib::PointInPolygon(xy_to_intpoint(px, py, multiplier), polygon));
339
+ }
340
+
341
+ static VALUE
342
+ rbclipper_offset_polygons(int argc, VALUE* argv, VALUE self)
343
+ {
344
+ const double multiplier = NUM2DBL(rb_iv_get(self, "@multiplier"));
345
+ const double inv_multiplier = 1.0 / multiplier;
346
+ VALUE polygonsValue, deltaValue, joinTypeValue, endTypeValue;
347
+
348
+ rb_scan_args(argc, argv, "31", &polygonsValue, &deltaValue, &joinTypeValue, &endTypeValue);
349
+
350
+ Paths polygons;
351
+ arys_to_polygons(polygonsValue, &polygons, multiplier);
352
+
353
+ Paths resultPaths;
354
+ XCLIPPEROFFSET(self)->AddPaths(polygons, sym_to_jointype(joinTypeValue), sym_to_endtype(endTypeValue));
355
+ XCLIPPEROFFSET(self)->Execute(resultPaths, NUM2DBL(deltaValue) * multiplier);
356
+
357
+ VALUE r = rb_ary_new();
358
+ for(Paths::iterator i = resultPaths.begin(); i != resultPaths.end(); ++i) {
359
+ VALUE sub = rb_ary_new();
360
+ for(Path::iterator p = i->begin(); p != i->end(); ++p) {
361
+ rb_ary_push(sub, rb_ary_new3(2, DBL2NUM(p->X * inv_multiplier), DBL2NUM(p->Y * inv_multiplier)));
362
+ }
363
+ rb_ary_push(r, sub);
364
+ }
365
+ return r;
366
+ }
367
+
368
+ static VALUE
369
+ rbclipper_execute_internal(VALUE self, ClipType cliptype,
370
+ VALUE subjfill, VALUE clipfill, VALUE resulttype)
371
+ {
372
+ if (NIL_P(subjfill)) {
373
+ subjfill = ID2SYM(id_even_odd);
374
+ }
375
+
376
+ if (NIL_P(clipfill)) {
377
+ clipfill = ID2SYM(id_even_odd);
378
+ }
379
+
380
+ if (NIL_P(resulttype)) {
381
+ resulttype = ID2SYM(id_polygons);
382
+ }
383
+
384
+ double inv_multiplier = 1.0 / NUM2LONG(rb_iv_get(self, "@multiplier"));
385
+
386
+ VALUE r = rb_ary_new();
387
+ if (resulttype == ID2SYM(id_polygons)) {
388
+ PolyTree polytree;
389
+ Paths solution;
390
+ XCLIPPER(self)->Execute((ClipType) cliptype,
391
+ polytree,
392
+ sym_to_filltype(subjfill),
393
+ sym_to_filltype(clipfill));
394
+ ClosedPathsFromPolyTree(polytree, solution);
395
+ for(Paths::iterator i = solution.begin(); i != solution.end(); ++i) {
396
+ VALUE sub = rb_ary_new();
397
+ for(Path::iterator p = i->begin(); p != i->end(); ++p) {
398
+ rb_ary_push(sub, rb_ary_new3(2, DBL2NUM(p->X * inv_multiplier), DBL2NUM(p->Y * inv_multiplier)));
399
+ }
400
+ rb_ary_push(r, sub);
401
+ }
402
+ #ifdef use_lines
403
+ OpenPathsFromPolyTree(polytree, solution);
404
+ for(Paths::iterator i = solution.begin(); i != solution.end(); ++i) {
405
+ VALUE sub = rb_ary_new();
406
+ rb_ary_push(sub, Qnil);
407
+ for(Path::iterator p = i->begin(); p != i->end(); ++p) {
408
+ rb_ary_push(sub, rb_ary_new3(2, DBL2NUM(p->X * inv_multiplier), DBL2NUM(p->Y * inv_multiplier)));
409
+ }
410
+ rb_ary_push(r, sub);
411
+ }
412
+ #endif
413
+ }
414
+ return r;
415
+ }
416
+
417
+ static VALUE
418
+ rbclipper_intersection(int argc, VALUE* argv, VALUE self)
419
+ {
420
+ VALUE subjfill, clipfill, resulttype;
421
+ rb_scan_args(argc, argv, "03", &subjfill, &clipfill, &resulttype);
422
+ return rbclipper_execute_internal(self, ctIntersection, subjfill, clipfill, resulttype);
423
+ }
424
+
425
+ static VALUE
426
+ rbclipper_union(int argc, VALUE* argv, VALUE self)
427
+ {
428
+ VALUE subjfill, clipfill, resulttype;
429
+ rb_scan_args(argc, argv, "03", &subjfill, &clipfill, &resulttype);
430
+ return rbclipper_execute_internal(self, ctUnion, subjfill, clipfill, resulttype);
431
+ }
432
+
433
+
434
+ static VALUE
435
+ rbclipper_difference(int argc, VALUE* argv, VALUE self)
436
+ {
437
+ VALUE subjfill, clipfill, resulttype;
438
+ rb_scan_args(argc, argv, "03", &subjfill, &clipfill, &resulttype);
439
+ return rbclipper_execute_internal(self, ctDifference, subjfill, clipfill, resulttype);
440
+ }
441
+
442
+
443
+ static VALUE
444
+ rbclipper_xor(int argc, VALUE* argv, VALUE self)
445
+ {
446
+ VALUE subjfill, clipfill, resulttype;
447
+ rb_scan_args(argc, argv, "03", &subjfill, &clipfill, &resulttype);
448
+ return rbclipper_execute_internal(self, ctXor, subjfill, clipfill, resulttype);
449
+ }
450
+
451
+ typedef VALUE (*ruby_method)(...);
452
+
453
+ void Init_clipper() {
454
+
455
+ id_even_odd = rb_intern("even_odd");
456
+ id_non_zero = rb_intern("non_zero");
457
+ id_positive = rb_intern("positive");
458
+ id_negative = rb_intern("negative");
459
+ id_polygons = rb_intern("polygons");
460
+ id_ex_polygons = rb_intern("expolygons");
461
+ id_jtSquare = rb_intern("jtSquare");
462
+ id_jtMiter = rb_intern("jtMiter");
463
+ id_jtRound = rb_intern("jtRound");
464
+ id_etClosedPolygon = rb_intern("etClosedPolygon");
465
+ id_etClosedLine = rb_intern("etClosedLine");
466
+ id_etOpenButt = rb_intern("etOpenButt");
467
+ id_etOpenSquare = rb_intern("etOpenSquare");
468
+ id_etOpenRound = rb_intern("etOpenRound");
469
+
470
+ VALUE mod = rb_define_module("Clipper");
471
+
472
+ VALUE k = rb_define_class_under(mod, "Clipper", rb_cObject);
473
+ rb_define_singleton_method(k, "new",
474
+ (ruby_method) rbclipper_new, 0);
475
+
476
+ rb_define_method(k, "orientation",
477
+ (ruby_method) rbclipper_orientation, 1);
478
+ rb_define_method(k, "point_in_polygon",
479
+ (ruby_method) rbclipper_point_in_polygon, 3);
480
+ rb_define_method(k, "area",
481
+ (ruby_method) rbclipper_area, 1);
482
+ rb_define_method(k, "add_subject_polygon",
483
+ (ruby_method) rbclipper_add_subject_polygon, 1);
484
+ rb_define_method(k, "add_clip_polygon",
485
+ (ruby_method) rbclipper_add_clip_polygon, 1);
486
+ rb_define_method(k, "add_subject_polyline",
487
+ (ruby_method) rbclipper_add_subject_polyline, 1);
488
+ rb_define_method(k, "add_subject_polygons",
489
+ (ruby_method) rbclipper_add_subject_polygons, 1);
490
+ rb_define_method(k, "add_clip_polygons",
491
+ (ruby_method) rbclipper_add_clip_polygons, 1);
492
+ rb_define_method(k, "add_subject_polylines",
493
+ (ruby_method) rbclipper_add_subject_polylines, 1);
494
+ rb_define_method(k, "clear!",
495
+ (ruby_method) rbclipper_clear, 0);
496
+ rb_define_method(k, "intersection",
497
+ (ruby_method) rbclipper_intersection, -1);
498
+ rb_define_method(k, "union",
499
+ (ruby_method) rbclipper_union, -1);
500
+ rb_define_method(k, "difference",
501
+ (ruby_method) rbclipper_difference, -1);
502
+ rb_define_method(k, "xor",
503
+ (ruby_method) rbclipper_xor, -1);
504
+
505
+ rb_define_method(k, "multiplier",
506
+ (ruby_method) rbclipper_multiplier, 0);
507
+ rb_define_method(k, "multiplier=",
508
+ (ruby_method) rbclipper_multiplier_eq, 1);
509
+
510
+ rb_define_method(k, "minkowski_sum",
511
+ (ruby_method) rbclipper_minkowski_sum, 3);
512
+
513
+ rb_define_method(k, "minkowski_diff",
514
+ (ruby_method) rbclipper_minkowski_diff, 2);
515
+
516
+ VALUE ko = rb_define_class_under(mod, "ClipperOffset", rb_cObject);
517
+ rb_define_singleton_method(ko, "new",
518
+ (ruby_method) rbclipperoffset_new, 0);
519
+ rb_define_method(ko, "offset_polygons",
520
+ (ruby_method) rbclipper_offset_polygons, -1);
521
+ rb_define_method(ko, "clear!",
522
+ (ruby_method) rbclipperoffset_clear, 0);
523
+
524
+ rb_define_method(ko, "multiplier",
525
+ (ruby_method) rbclipper_multiplier, 0);
526
+ rb_define_method(ko, "multiplier=",
527
+ (ruby_method) rbclipper_multiplier_eq, 1);
528
+ }
529
+
530
+ } /* extern "C" */
@@ -0,0 +1,6 @@
1
+ module Clipper
2
+ # Keep first two components sync'd to Clipper's major/minor.
3
+ # Last is our build number based on that. Hopefully there
4
+ # won't be too much churn re: Clipper's version vs. the bindings.
5
+ VERSION = "6.4.2.5.5"
6
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rbclipper
3
+ version: !ruby/object:Gem::Version
4
+ version: 6.4.2.5.5
5
+ platform: ruby
6
+ authors:
7
+ - Angus Johnson
8
+ - Mike Owens
9
+ - Dag Rende
10
+ - Jaap van der Plas
11
+ - Simon George
12
+ - Kjell Morgenstern
13
+ - Will Ross
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+ date: 2021-12-08 00:00:00.000000000 Z
18
+ dependencies:
19
+ - !ruby/object:Gem::Dependency
20
+ name: bundler
21
+ requirement: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '1.5'
26
+ type: :development
27
+ prerelease: false
28
+ version_requirements: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '1.5'
33
+ - !ruby/object:Gem::Dependency
34
+ name: rake
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: minitest
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '5.8'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '5.8'
61
+ - !ruby/object:Gem::Dependency
62
+ name: minitest-junit
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: minitest-snail
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ description: Builds a native ruby extension for Clipper
90
+ email:
91
+ - will@spanner.org
92
+ executables: []
93
+ extensions:
94
+ - ext/clipper/extconf.rb
95
+ extra_rdoc_files:
96
+ - README.md
97
+ - Changelog
98
+ - ext/clipper/rbclipper.cpp
99
+ files:
100
+ - Changelog
101
+ - Gemfile
102
+ - LICENSE.bindings
103
+ - LICENSE.clipper
104
+ - README.md
105
+ - Rakefile
106
+ - ext/clipper/clipper.cpp
107
+ - ext/clipper/clipper.hpp
108
+ - ext/clipper/extconf.rb
109
+ - ext/clipper/rbclipper.cpp
110
+ - lib/clipper/version.rb
111
+ homepage: http://github.com/spanner/rbclipper
112
+ licenses:
113
+ - Boost Software License - Version 1.0
114
+ metadata: {}
115
+ post_install_message:
116
+ rdoc_options:
117
+ - "--main=README.md"
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ required_rubygems_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: 1.3.6
130
+ requirements: []
131
+ rubygems_version: 3.1.4
132
+ signing_key:
133
+ specification_version: 4
134
+ summary: Ruby wrapper for Clipper, Angus Johnson's excellent polygon clipping library
135
+ test_files: []