globegit-postgresql-plruby 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. data/Changes +121 -0
  2. data/README.markdown +155 -0
  3. data/Rakefile +48 -0
  4. data/docs/plruby.rb +1931 -0
  5. data/ex_trans.sql +33 -0
  6. data/extconf.rb +267 -0
  7. data/plruby.html +1454 -0
  8. data/plruby.rd +1571 -0
  9. data/postgresql-plruby.gemspec +56 -0
  10. data/src/conversions.h +5 -0
  11. data/src/conversions/basic/conversions.h +25 -0
  12. data/src/conversions/basic/extconf.rb +8 -0
  13. data/src/conversions/basic/plruby_basic.c +357 -0
  14. data/src/conversions/bitstring/bitstring.sql +75 -0
  15. data/src/conversions/bitstring/conversions.h +15 -0
  16. data/src/conversions/bitstring/extconf.rb +8 -0
  17. data/src/conversions/bitstring/plruby_bitstring.c +579 -0
  18. data/src/conversions/convcommon.h +129 -0
  19. data/src/conversions/datetime/conversions.h +13 -0
  20. data/src/conversions/datetime/extconf.rb +8 -0
  21. data/src/conversions/datetime/plruby_datetime.c +269 -0
  22. data/src/conversions/geometry/conversions.h +37 -0
  23. data/src/conversions/geometry/extconf.rb +8 -0
  24. data/src/conversions/geometry/geometry.sql +196 -0
  25. data/src/conversions/geometry/plruby_geometry.c +2494 -0
  26. data/src/conversions/network/conversions.h +21 -0
  27. data/src/conversions/network/extconf.rb +8 -0
  28. data/src/conversions/network/network.sql +63 -0
  29. data/src/conversions/network/plruby_network.c +537 -0
  30. data/src/package.h +20 -0
  31. data/src/plpl.c +1708 -0
  32. data/src/plplan.c +893 -0
  33. data/src/plruby.c +1676 -0
  34. data/src/plruby.h +324 -0
  35. data/src/pltrans.c +388 -0
  36. data/test/conv_bitstring/b.rb +45 -0
  37. data/test/conv_bitstring/runtest +26 -0
  38. data/test/conv_bitstring/test.expected.73 +148 -0
  39. data/test/conv_bitstring/test.expected.74 +148 -0
  40. data/test/conv_bitstring/test.expected.80 +148 -0
  41. data/test/conv_bitstring/test.expected.81 +148 -0
  42. data/test/conv_bitstring/test.expected.82 +148 -0
  43. data/test/conv_bitstring/test.expected.83 +148 -0
  44. data/test/conv_bitstring/test.expected.84 +148 -0
  45. data/test/conv_bitstring/test.out +148 -0
  46. data/test/conv_bitstring/test_mklang.sql +8 -0
  47. data/test/conv_bitstring/test_queries.sql +63 -0
  48. data/test/conv_bitstring/test_queries.sql.in +63 -0
  49. data/test/conv_geometry/b.rb +45 -0
  50. data/test/conv_geometry/runtest +26 -0
  51. data/test/conv_geometry/test.expected.73 +265 -0
  52. data/test/conv_geometry/test.expected.74 +265 -0
  53. data/test/conv_geometry/test.expected.80 +265 -0
  54. data/test/conv_geometry/test.expected.81 +265 -0
  55. data/test/conv_geometry/test.expected.82 +265 -0
  56. data/test/conv_geometry/test.expected.83 +265 -0
  57. data/test/conv_geometry/test.expected.84 +265 -0
  58. data/test/conv_geometry/test.out +265 -0
  59. data/test/conv_geometry/test_mklang.sql +8 -0
  60. data/test/conv_geometry/test_queries.sql +194 -0
  61. data/test/conv_geometry/test_queries.sql.in +194 -0
  62. data/test/conv_network/b.rb +45 -0
  63. data/test/conv_network/runtest +26 -0
  64. data/test/conv_network/test.expected.73 +213 -0
  65. data/test/conv_network/test.expected.74 +237 -0
  66. data/test/conv_network/test.expected.80 +237 -0
  67. data/test/conv_network/test.expected.81 +237 -0
  68. data/test/conv_network/test.expected.82 +237 -0
  69. data/test/conv_network/test.expected.83 +237 -0
  70. data/test/conv_network/test.expected.84 +237 -0
  71. data/test/conv_network/test.out +237 -0
  72. data/test/conv_network/test_mklang.sql +8 -0
  73. data/test/conv_network/test_queries.sql +60 -0
  74. data/test/conv_network/test_queries.sql.in +60 -0
  75. data/test/plp/b.rb +34 -0
  76. data/test/plp/runtest +29 -0
  77. data/test/plp/test.expected.73 +472 -0
  78. data/test/plp/test.expected.74 +472 -0
  79. data/test/plp/test.expected.75 +472 -0
  80. data/test/plp/test.expected.80 +472 -0
  81. data/test/plp/test.expected.81 +472 -0
  82. data/test/plp/test.expected.82 +472 -0
  83. data/test/plp/test.expected.83 +472 -0
  84. data/test/plp/test.expected.84 +472 -0
  85. data/test/plp/test.out +472 -0
  86. data/test/plp/test_mklang.sql +8 -0
  87. data/test/plp/test_queries.sql +273 -0
  88. data/test/plp/test_setup.sql +931 -0
  89. data/test/plp/test_setup.sql.in +931 -0
  90. data/test/plt/b.rb +34 -0
  91. data/test/plt/runtest +29 -0
  92. data/test/plt/test.expected.73 +178 -0
  93. data/test/plt/test.expected.74 +178 -0
  94. data/test/plt/test.expected.75 +178 -0
  95. data/test/plt/test.expected.80 +178 -0
  96. data/test/plt/test.expected.81 +178 -0
  97. data/test/plt/test.expected.82 +178 -0
  98. data/test/plt/test.expected.83 +164 -0
  99. data/test/plt/test.expected.84 +168 -0
  100. data/test/plt/test.out +168 -0
  101. data/test/plt/test_mklang.sql +8 -0
  102. data/test/plt/test_queries.sql +72 -0
  103. data/test/plt/test_setup.sql +252 -0
  104. data/test/plt/test_setup.sql.in +252 -0
  105. data/test/range/b.rb +45 -0
  106. data/test/range/runtest +26 -0
  107. data/test/range/test.expected.73 +396 -0
  108. data/test/range/test.expected.73.in +396 -0
  109. data/test/range/test.expected.74 +396 -0
  110. data/test/range/test.expected.74.in +396 -0
  111. data/test/range/test.expected.75 +396 -0
  112. data/test/range/test.expected.75.in +396 -0
  113. data/test/range/test.expected.80 +396 -0
  114. data/test/range/test.expected.81 +397 -0
  115. data/test/range/test.expected.82 +397 -0
  116. data/test/range/test.expected.83 +397 -0
  117. data/test/range/test.expected.84 +399 -0
  118. data/test/range/test.out +399 -0
  119. data/test/range/test_mklang.sql +8 -0
  120. data/test/range/test_queries.sql +249 -0
  121. data/test/range/test_queries.sql.in +249 -0
  122. metadata +207 -0
@@ -0,0 +1,8 @@
1
+ require 'mkmf'
2
+
3
+ if CONFIG["LIBRUBYARG"] == "$(LIBRUBYARG_SHARED)" &&
4
+ !enable_config("plruby-shared")
5
+ $LIBRUBYARG = ""
6
+ end
7
+ have_library('ruby18', 'ruby_init')
8
+ create_makefile('plruby/plruby_geometry')
@@ -0,0 +1,196 @@
1
+ set client_min_messages = 'WARNING';
2
+
3
+ drop table pl_box cascade;
4
+
5
+ create table pl_box (
6
+ data box, barea float, boverlaps bool, boverleft bool, boverright bool,
7
+ bleft bool, bright bool
8
+ );
9
+
10
+ create or replace function box_val(box[]) returns setof pl_box as '
11
+ b1 = Box.new(2.5,2.5,1.0,1.0)
12
+ b2 = Box.new(2.0,2.0,2.5,2.5)
13
+ b3 = Box.new(3.0,3.0,5.0,5.0)
14
+ args[0].each do |b|
15
+ yield [b, b.area, b.overlap?(b1), b.overleft?(b2),
16
+ b.overright?(b2), b.left?(b3), b3.right?(b)]
17
+ end
18
+ ' language 'plruby';
19
+
20
+ select * from
21
+ box_val('{(2.0,2.0,0.0,0.0);(1.0,1.0,3.0,3.0);(2.5,2.5,2.5,3.5);(3.0,3.0,3.0,3.0)'::box[]);
22
+
23
+ drop table pl_box cascade;
24
+
25
+ create table pl_box (
26
+ b box, bcmp1 int, bcmp2 int, bin bool, bcontain bool, bcenter point
27
+ );
28
+
29
+ create or replace function box_val(box[]) returns setof pl_box as '
30
+ b1 = Box.new(3.0,3.0,5.0,5.0)
31
+ b2 = Box.new(3.5,3.0,4.5,3.0)
32
+ b3 = Box.new(0,0,3,3)
33
+ args[0].each do |b|
34
+ yield [b, b <=> b1, b <=> b2, b.in?(b3), b.contain?(b3), b.center]
35
+ end
36
+ ' language 'plruby';
37
+
38
+ select * from
39
+ box_val('{(2.0,2.0,0.0,0.0);(1.0,1.0,3.0,3.0);(2.5,2.5,2.5,3.5);(3.0,3.0,3.0,3.0)}'::box[]);
40
+
41
+ drop table pl_box cascade;
42
+
43
+ create table pl_box (
44
+ b0 box, b1 box, b2 box, b3 box
45
+ );
46
+
47
+ create or replace function box_val(box[]) returns setof pl_box as '
48
+ p0 = [Point.new(-10.0,0.0), Point.new(-3.0,4.0),
49
+ Point.new(5.1, 34.5), Point.new(-5.0,-12.0)]
50
+ args[0].each do |b|
51
+ p0.each do |p|
52
+ yield [b + p, b - p, b * p, b / p]
53
+ end
54
+ p0.each do |p|
55
+ yield [p + b, p - b, p * b, p / b]
56
+ end
57
+ end
58
+ ' language 'plruby';
59
+
60
+ select * from
61
+ box_val('{(2.0,2.0,0.0,0.0);(1.0,1.0,3.0,3.0);(2.5,2.5,2.5,3.5);(3.0,3.0,3.0,3.0)}'::box[]);
62
+
63
+ drop table pl_box cascade;
64
+
65
+ create table pl_box (
66
+ p point, dp float, d0 float, c circle, w float, h float
67
+ );
68
+
69
+ create or replace function box_val(box[]) returns setof pl_box as '
70
+ p = Point.new(6,4)
71
+ args[0].each do |b|
72
+ p0 = b.center
73
+ yield [p0, Geometry::distance(p, b),Geometry::distance(p, p0),
74
+ b.to_circle, b.height, b.width]
75
+ end
76
+ ' language 'plruby';
77
+
78
+ select * from
79
+ box_val('{(2.0,2.0,0.0,0.0);(1.0,1.0,3.0,3.0);(2.5,2.5,2.5,3.5);(3.0,3.0,3.0,3.0)}'::box[]);
80
+
81
+ drop table pl_box cascade;
82
+
83
+ create table pl_box (
84
+ nb int, ll float, pc bool
85
+ );
86
+
87
+ create or replace function path_val(path[]) returns setof pl_box as '
88
+ args[0].each do |b|
89
+ yield [b.npoints, b.length, b.closed?]
90
+ end
91
+ ' language 'plruby';
92
+
93
+ select * from
94
+ path_val('{[1,2,3,4],(0,0),(3,0),(4,5),(1,6),11,12,13,14,25,12}'::path[]);
95
+
96
+ drop table pl_box cascade;
97
+
98
+ create table pl_box (
99
+ p path, p0 path, p1 path
100
+ );
101
+
102
+ create or replace function path_val(path[]) returns setof pl_box as '
103
+ p0 = Point.new(6,7)
104
+ args[0].each do |b|
105
+ yield [b, b + p0, b - p0]
106
+ end
107
+ ' language 'plruby';
108
+
109
+ select * from
110
+ path_val('{"[1,2,3,4]","(0,0),(3,0),(4,5),(1,6)","11,12,13,14,25,12"}'::path[]);
111
+
112
+ drop table pl_box cascade;
113
+
114
+ create table pl_box (
115
+ p path, p0 path, p1 path
116
+ );
117
+
118
+ create or replace function path_val(path[]) returns setof pl_box as '
119
+ p0 = Point.new(6,7)
120
+ args[0].each do |b|
121
+ yield [b, b * p0, b / p0]
122
+ end
123
+ ' language 'plruby';
124
+
125
+ select * from
126
+ path_val('{"[1,2,3,4]","(0,0),(3,0),(4,5),(1,6)","11,12,13,14,25,12"}'::path[]);
127
+
128
+ drop table pl_box cascade;
129
+
130
+ create table pl_box (
131
+ center point, area float, radius float, diameter float
132
+ );
133
+
134
+ create or replace function circle_val(circle[]) returns setof pl_box as '
135
+ args[0].each do |b|
136
+ yield b.center, b.area, b.radius, b.diameter
137
+ end
138
+ ' language 'plruby';
139
+
140
+ select * from
141
+ circle_val('{"<(5,1),3>","<(1,2),100>","<(100,200),10>","<(100,1),115>","1,3,5"}'::circle[]);
142
+
143
+
144
+ drop table pl_box cascade;
145
+
146
+ create table pl_box (
147
+ p circle, p0 circle, p1 circle
148
+ );
149
+
150
+ create or replace function circle_val(circle[]) returns setof pl_box as '
151
+ p0 = Point.new(6,7)
152
+ args[0].each do |b|
153
+ yield [b, b + p0, b - p0]
154
+ end
155
+ ' language 'plruby';
156
+
157
+ select * from
158
+ circle_val('{"<(5,1),3>","<(1,2),100>","<(100,200),10>","<(100,1),115>","1,3,5"}'::circle[]);
159
+
160
+ drop table pl_box cascade;
161
+
162
+ create table pl_box (
163
+ p circle, p0 circle, p1 circle
164
+ );
165
+
166
+ create or replace function circle_val(circle[]) returns setof pl_box as '
167
+ p0 = Point.new(6,7)
168
+ args[0].each do |b|
169
+ yield [b, p0 * b, p0 / b ]
170
+ end
171
+ ' language 'plruby';
172
+
173
+ select * from
174
+ circle_val('{"<(5,1),3>","<(1,2),100>","<(100,200),10>","<(100,1),115>","1,3,5"}'::circle[]);
175
+
176
+ drop table pl_box cascade;
177
+
178
+ create table pl_box (
179
+ overlap bool, overleft bool, overright bool,
180
+ bleft bool, bright bool, below bool, above bool
181
+ );
182
+
183
+ create or replace function circle_val(circle, circle) returns setof pl_box as '
184
+ b0 = args[0]
185
+ b1 = args[1]
186
+ yield b0.overlap?(b1), b0.overleft?(b1), b0.overright?(b1),
187
+ b0.left?(b1), b0.right?(b1), b0.below?(b1), b0.above?(b1)
188
+ ' language 'plruby';
189
+
190
+
191
+ select * from
192
+ circle_val('<(5,1),3>'::circle, '<(1,2),100>'::circle);
193
+
194
+ select * from
195
+ circle_val('<(100,200),10>'::circle, '<(100,1),115>'::circle);
196
+
@@ -0,0 +1,2494 @@
1
+ #include "convcommon.h"
2
+
3
+ #include <math.h>
4
+ #include <limits.h>
5
+ #include <float.h>
6
+ #include <ctype.h>
7
+
8
+ #include "libpq/pqformat.h"
9
+ #include "utils/geo_decls.h"
10
+
11
+ static VALUE pl_cPoint;
12
+
13
+ static VALUE
14
+ pl_convert(VALUE obj, ID id, void (*func)())
15
+ {
16
+ if (TYPE(obj) == T_DATA &&
17
+ RDATA(obj)->dmark == (RUBY_DATA_FUNC)func) {
18
+ return obj;
19
+ }
20
+ obj = rb_funcall(obj, id, 0, 0);
21
+ if (TYPE(obj) != T_DATA ||
22
+ RDATA(obj)->dmark != (RUBY_DATA_FUNC)func) {
23
+ rb_raise(rb_eArgError, "invalid conversion");
24
+ }
25
+ return obj;
26
+ }
27
+
28
+ static void pl_point_mark(Point *p) {}
29
+ static void pl_circle_mark(CIRCLE *l) {}
30
+ static void pl_poly_mark(POLYGON *l) {}
31
+
32
+ #define INIT_COPY(init_copy, type_struct, mark_func) \
33
+ static VALUE \
34
+ init_copy(VALUE copy, VALUE orig) \
35
+ { \
36
+ type_struct *t0, *t1; \
37
+ \
38
+ if (copy == orig) return copy; \
39
+ if (TYPE(orig) != T_DATA || \
40
+ RDATA(orig)->dmark != (RUBY_DATA_FUNC)mark_func) { \
41
+ rb_raise(rb_eTypeError, "wrong argument type to clone"); \
42
+ } \
43
+ Data_Get_Struct(orig, type_struct, t0); \
44
+ Data_Get_Struct(copy, type_struct, t1); \
45
+ MEMCPY(t1, t0, type_struct, 1); \
46
+ return copy; \
47
+ }
48
+
49
+ static VALUE
50
+ pl_point_s_alloc(VALUE obj)
51
+ {
52
+ Point *p;
53
+ return Data_Make_Struct(obj, Point, pl_point_mark, free, p);
54
+ }
55
+
56
+ INIT_COPY(pl_point_init_copy, Point, pl_point_mark);
57
+
58
+ static VALUE
59
+ pl_point_s_datum(VALUE obj, VALUE a)
60
+ {
61
+ Point *p0, *p1;
62
+ Oid typoid;
63
+ VALUE res;
64
+
65
+ p0 = (Point *)plruby_datum_get(a, &typoid);
66
+ if (typoid != POINTOID) {
67
+ rb_raise(rb_eArgError, "unknown OID type %d", typoid);
68
+ }
69
+ p1 = ALLOC_N(Point, 1);
70
+ memcpy(p1, p0, sizeof(Point));
71
+ res = Data_Wrap_Struct(obj, pl_point_mark, free, p1);
72
+ OBJ_TAINT(res);
73
+ return res;
74
+ }
75
+
76
+ static VALUE
77
+ pl_point_to_datum(VALUE obj, VALUE a)
78
+ {
79
+ Point *p0, *p1;
80
+ int typoid;
81
+
82
+ typoid = plruby_datum_oid(a, 0);
83
+ if (typoid != POINTOID) {
84
+ return Qnil;
85
+ }
86
+ Data_Get_Struct(obj, Point, p0);
87
+ p1 = (Point *)palloc(sizeof(Point));
88
+ memcpy(p1, p0, sizeof(Point));
89
+ return plruby_datum_set(a, (Datum)p1);
90
+ }
91
+
92
+ PL_MLOAD(pl_point_mload, point_recv, Point);
93
+ PL_MDUMP(pl_point_mdump, point_send);
94
+
95
+ static VALUE
96
+ pl_point_s_str(VALUE obj, VALUE a)
97
+ {
98
+ Point *p;
99
+ VALUE res;
100
+
101
+ a = plruby_to_s(a);
102
+ res = Data_Make_Struct(obj, Point, pl_point_mark, free, p);
103
+ CPY_FREE(p, PLRUBY_DFC1(point_in, RSTRING_PTR(a)), sizeof(Point));
104
+ if (OBJ_TAINTED(obj) || OBJ_TAINTED(a)) OBJ_TAINT(res);
105
+ return res;
106
+ }
107
+
108
+ static VALUE
109
+ pl_point_init(VALUE obj, VALUE a, VALUE b)
110
+ {
111
+ Point *point;
112
+
113
+ Data_Get_Struct(obj, Point, point);
114
+ a = rb_Float(a);
115
+ b = rb_Float(b);
116
+ point->x = RFLOAT_VALUE(a);
117
+ point->y = RFLOAT_VALUE(b);
118
+ return obj;
119
+ }
120
+
121
+ static VALUE
122
+ pl_point_x(VALUE obj)
123
+ {
124
+ Point *point;
125
+ VALUE res;
126
+
127
+ Data_Get_Struct(obj, Point, point);
128
+ res = rb_float_new(point->x);
129
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
130
+ return res;
131
+ }
132
+
133
+ static VALUE
134
+ pl_point_setx(VALUE obj, VALUE a)
135
+ {
136
+ Point *point;
137
+
138
+ Data_Get_Struct(obj, Point, point);
139
+ a = rb_Float(a);
140
+ point->x = RFLOAT_VALUE(a);
141
+ return a;
142
+ }
143
+
144
+ static VALUE
145
+ pl_point_y(VALUE obj)
146
+ {
147
+ Point *point;
148
+ VALUE res;
149
+
150
+ Data_Get_Struct(obj, Point, point);
151
+ res = rb_float_new(point->y);
152
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
153
+ return res;
154
+ }
155
+
156
+ static VALUE
157
+ pl_point_sety(VALUE obj, VALUE a)
158
+ {
159
+ Point *point;
160
+
161
+ Data_Get_Struct(obj, Point, point);
162
+ a = rb_Float(a);
163
+ point->y = RFLOAT_VALUE(a);
164
+ return a;
165
+ }
166
+
167
+ static VALUE
168
+ pl_point_aref(VALUE obj, VALUE a)
169
+ {
170
+ Point *point;
171
+ int i;
172
+ VALUE res;
173
+
174
+ Data_Get_Struct(obj, Point, point);
175
+ i = NUM2INT(rb_Integer(a));
176
+ if (i < 0) i = -i;
177
+ switch (i) {
178
+ case 0:
179
+ res = rb_float_new(point->x);
180
+ break;
181
+
182
+ case 1:
183
+ res = rb_float_new(point->y);
184
+ break;
185
+
186
+ default:
187
+ res = Qnil;
188
+ }
189
+ if (OBJ_TAINTED(obj) || OBJ_TAINTED(a)) OBJ_TAINT(res);
190
+ return res;
191
+ }
192
+
193
+ static VALUE
194
+ pl_point_aset(VALUE obj, VALUE a, VALUE b)
195
+ {
196
+ Point *point;
197
+ int i;
198
+
199
+ Data_Get_Struct(obj, Point, point);
200
+ i = NUM2INT(rb_Integer(a));
201
+ b = rb_Float(b);
202
+ if (i < 0) i = -i;
203
+ switch (i) {
204
+ case 0:
205
+ point->x = RFLOAT_VALUE(b);
206
+ break;
207
+ case 1:
208
+ point->y = RFLOAT_VALUE(b);
209
+ break;
210
+ default:
211
+ rb_raise(rb_eArgError, "[]= invalid indice");
212
+ }
213
+ return b;
214
+ }
215
+
216
+ #define TO_STRING(NAME_,FUNCTION_) \
217
+ static VALUE \
218
+ NAME_(VALUE obj) \
219
+ { \
220
+ Point *p; \
221
+ char *str; \
222
+ \
223
+ Data_Get_Struct(obj, Point, p); \
224
+ str = (char *)PLRUBY_DFC1(FUNCTION_, p); \
225
+ if (OBJ_TAINTED(obj)) { \
226
+ return rb_tainted_str_new2(str); \
227
+ } \
228
+ return rb_str_new2(str); \
229
+ }
230
+
231
+ TO_STRING(pl_point_to_s,point_out);
232
+
233
+ #define CHECK_CLASS(obj, a) \
234
+ if (!rb_obj_is_kind_of(a, rb_obj_class(obj))) { \
235
+ rb_raise(rb_eArgError, "invalid classes (%s, %s)", \
236
+ rb_class2name(rb_obj_class(obj)), \
237
+ rb_class2name(rb_obj_class(a))); \
238
+ }
239
+
240
+ #define POINT_CALL(NAME_,FUNCTION_) \
241
+ static VALUE \
242
+ NAME_(VALUE obj, VALUE a) \
243
+ { \
244
+ Point *p0, *p1, *pr; \
245
+ VALUE res; \
246
+ \
247
+ if (TYPE(a) == T_DATA && \
248
+ RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_point_mark) { \
249
+ Data_Get_Struct(obj, Point, p0); \
250
+ Data_Get_Struct(a, Point, p1); \
251
+ res = Data_Make_Struct(rb_obj_class(obj), Point, \
252
+ pl_point_mark, free, pr); \
253
+ CPY_FREE(pr, PLRUBY_DFC2(FUNCTION_, p0, p1), sizeof(Point)); \
254
+ if (OBJ_TAINTED(obj) || OBJ_TAINTED(a)) OBJ_TAINT(res); \
255
+ return res; \
256
+ } \
257
+ return rb_funcall(a, rb_frame_last_func(), 1, obj); \
258
+ }
259
+
260
+ POINT_CALL(pl_point_add,point_add);
261
+ POINT_CALL(pl_point_sub,point_sub);
262
+ POINT_CALL(pl_point_mul,point_mul);
263
+ POINT_CALL(pl_point_div,point_div);
264
+
265
+ #define POINT_CALL_BOOL(NAME_,FUNCTION_) \
266
+ static VALUE \
267
+ NAME_(VALUE obj, VALUE a) \
268
+ { \
269
+ Point *p0, *p1; \
270
+ \
271
+ CHECK_CLASS(obj, a); \
272
+ Data_Get_Struct(obj, Point, p0); \
273
+ Data_Get_Struct(a, Point, p1); \
274
+ if (PLRUBY_DFC2(FUNCTION_, p0, p1)) \
275
+ return Qtrue; \
276
+ return Qfalse; \
277
+ }
278
+
279
+ POINT_CALL_BOOL(pl_point_left,point_left);
280
+ POINT_CALL_BOOL(pl_point_right,point_right);
281
+ POINT_CALL_BOOL(pl_point_above,point_above);
282
+ POINT_CALL_BOOL(pl_point_below,point_below);
283
+ POINT_CALL_BOOL(pl_point_vert,point_vert);
284
+ POINT_CALL_BOOL(pl_point_horiz,point_horiz);
285
+ POINT_CALL_BOOL(pl_point_eq,point_eq);
286
+
287
+ #ifdef USE_FLOAT8_BYVAL
288
+ #define RETURN_FLOAT(obj_, function_) do { \
289
+ float8 f_; \
290
+ VALUE res_; \
291
+ f_ = DatumGetFloat8(function_); \
292
+ res_ = rb_float_new(f_); \
293
+ if (OBJ_TAINTED(obj_)) OBJ_TAINT(res_); \
294
+ return res_; \
295
+ } while (0)
296
+
297
+ #define RETURN_FLOAT2(obj_, a_, function_) do { \
298
+ float8 f_; \
299
+ VALUE res_; \
300
+ f_ = DatumGetFloat8(function_); \
301
+ res_ = rb_float_new(f_); \
302
+ if (OBJ_TAINTED(obj_) || \
303
+ OBJ_TAINTED(a_)) OBJ_TAINT(res_); \
304
+ return res_; \
305
+ } while (0)
306
+ #else
307
+ #define RETURN_FLOAT(obj_, function_) do { \
308
+ float8 *f_; \
309
+ VALUE res_; \
310
+ f_ = (float8 *)function_; \
311
+ if (!f_) res_ = rb_float_new(0.0); \
312
+ else { \
313
+ res_ = rb_float_new(*f_); \
314
+ pfree(f_); \
315
+ } \
316
+ if (OBJ_TAINTED(obj_)) OBJ_TAINT(res_); \
317
+ return res_; \
318
+ } while (0)
319
+
320
+ #define RETURN_FLOAT2(obj_, a_, function_) do { \
321
+ float8 *f_; \
322
+ VALUE res_; \
323
+ f_ = (float8 *)function_; \
324
+ if (!f_) res_ = rb_float_new(0.0); \
325
+ else { \
326
+ res_ = rb_float_new(*f_); \
327
+ pfree(f_); \
328
+ } \
329
+ if (OBJ_TAINTED(obj_) || \
330
+ OBJ_TAINTED(a_)) OBJ_TAINT(res_); \
331
+ return res_; \
332
+ } while (0)
333
+ #endif
334
+
335
+
336
+ static VALUE
337
+ pl_point_slope(VALUE obj, VALUE a)
338
+ {
339
+ Point *p0, *p1;
340
+
341
+ CHECK_CLASS(obj, a);
342
+ Data_Get_Struct(obj, Point, p0);
343
+ Data_Get_Struct(a, Point, p1);
344
+ RETURN_FLOAT2(obj, a, PLRUBY_DFC2(point_slope, p0, p1));
345
+ }
346
+
347
+ static void pl_lseg_mark(LSEG *l) {}
348
+
349
+ static VALUE
350
+ pl_lseg_s_alloc(VALUE obj)
351
+ {
352
+ LSEG *lseg;
353
+ return Data_Make_Struct(obj, LSEG, pl_lseg_mark, free, lseg);
354
+ }
355
+
356
+ INIT_COPY(pl_lseg_init_copy, LSEG, pl_lseg_mark);
357
+
358
+ static VALUE
359
+ pl_lseg_s_datum(VALUE obj, VALUE a)
360
+ {
361
+ LSEG *p0, *p1;
362
+ Oid typoid;
363
+ VALUE res;
364
+
365
+ p0 = (LSEG *)plruby_datum_get(a, &typoid);
366
+ if (typoid != LSEGOID) {
367
+ rb_raise(rb_eArgError, "unknown OID type %d", typoid);
368
+ }
369
+ p1 = ALLOC_N(LSEG, 1);
370
+ memcpy(p1, p0, sizeof(LSEG));
371
+ res = Data_Wrap_Struct(obj, pl_lseg_mark, free, p1);
372
+ OBJ_TAINT(res);
373
+ return res;
374
+ }
375
+
376
+ static VALUE
377
+ pl_lseg_to_datum(VALUE obj, VALUE a)
378
+ {
379
+ LSEG *p0, *p1;
380
+ int typoid;
381
+
382
+ typoid = plruby_datum_oid(a, 0);
383
+ if (typoid != LSEGOID) {
384
+ return Qnil;
385
+ }
386
+ Data_Get_Struct(obj, LSEG, p0);
387
+ p1 = (LSEG *)palloc(sizeof(LSEG));
388
+ memcpy(p1, p0, sizeof(LSEG));
389
+ return plruby_datum_set(a, (Datum)p1);
390
+ }
391
+
392
+ PL_MLOAD(pl_lseg_mload, lseg_recv, LSEG);
393
+ PL_MDUMP(pl_lseg_mdump, lseg_send);
394
+
395
+ static VALUE
396
+ pl_lseg_s_str(VALUE obj, VALUE a)
397
+ {
398
+ LSEG *l;
399
+ VALUE res;
400
+
401
+ a = plruby_to_s(a);
402
+ res = Data_Make_Struct(obj, LSEG, pl_lseg_mark, free, l);
403
+ CPY_FREE(l, PLRUBY_DFC1(lseg_in, RSTRING_PTR(a)), sizeof(LSEG));
404
+ if (OBJ_TAINTED(obj) || OBJ_TAINTED(a)) OBJ_TAINT(res);
405
+ return res;
406
+ }
407
+
408
+ static VALUE
409
+ pl_lseg_init(VALUE obj, VALUE a, VALUE b)
410
+ {
411
+ LSEG *l;
412
+ Point *p;
413
+
414
+ a = pl_convert(a, rb_intern("to_point"), pl_point_mark);
415
+ b = pl_convert(b, rb_intern("to_point"), pl_point_mark);
416
+ Data_Get_Struct(obj, LSEG, l);
417
+ Data_Get_Struct(a, Point, p);
418
+ l->p[0].x = p->x;
419
+ l->p[0].y = p->y;
420
+ Data_Get_Struct(b, Point, p);
421
+ l->p[1].x = p->x;
422
+ l->p[1].y = p->y;
423
+ return obj;
424
+ }
425
+
426
+ TO_STRING(pl_lseg_to_s,lseg_out);
427
+
428
+ static VALUE
429
+ pl_lseg_aref(VALUE obj, VALUE a)
430
+ {
431
+ LSEG *lseg;
432
+ Point *point;
433
+ int i;
434
+ VALUE res;
435
+
436
+ Data_Get_Struct(obj, LSEG, lseg);
437
+ i = NUM2INT(rb_Integer(a));
438
+ if (i < 0) i = -i;
439
+ switch (i) {
440
+ case 0:
441
+ res = Data_Make_Struct(pl_cPoint, Point, pl_point_mark, free, point);
442
+ point->x = lseg->p[0].x;
443
+ point->y = lseg->p[0].y;
444
+ break;
445
+
446
+ case 1:
447
+ res = Data_Make_Struct(pl_cPoint, Point, pl_point_mark, free, point);
448
+ point->x = lseg->p[1].x;
449
+ point->y = lseg->p[1].y;
450
+ break;
451
+
452
+ default:
453
+ res = Qnil;
454
+ }
455
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
456
+ return res;
457
+ }
458
+
459
+ static VALUE
460
+ pl_lseg_aset(VALUE obj, VALUE a, VALUE b)
461
+ {
462
+ LSEG *lseg;
463
+ Point *point;
464
+ int i;
465
+
466
+ Data_Get_Struct(obj, LSEG, lseg);
467
+ i = NUM2INT(rb_Integer(a));
468
+ b = pl_convert(b, rb_intern("to_point"), pl_point_mark);
469
+ Data_Get_Struct(b, Point, point);
470
+ if (i < 0) i = -i;
471
+ switch (i) {
472
+ case 0:
473
+ lseg->p[0].x = point->x;
474
+ lseg->p[0].y = point->y;
475
+ break;
476
+ case 1:
477
+ lseg->p[1].x = point->x;
478
+ lseg->p[1].y = point->y;
479
+ break;
480
+ default:
481
+ rb_raise(rb_eArgError, "[]= invalid indice");
482
+ }
483
+ return b;
484
+ }
485
+
486
+
487
+ static VALUE
488
+ pl_lseg_length(VALUE obj)
489
+ {
490
+ LSEG *l;
491
+
492
+ Data_Get_Struct(obj, LSEG, l);
493
+ RETURN_FLOAT(obj, PLRUBY_DFC1(lseg_length, l));
494
+ }
495
+
496
+ static VALUE
497
+ pl_lseg_parallel(VALUE obj, VALUE a)
498
+ {
499
+ LSEG *l0, *l1;
500
+
501
+ CHECK_CLASS(obj, a);
502
+ Data_Get_Struct(obj, LSEG, l0);
503
+ Data_Get_Struct(a, LSEG, l1);
504
+ if (PLRUBY_DFC2(lseg_parallel, l0, l1)) return Qtrue;
505
+ return Qfalse;
506
+ }
507
+
508
+ static VALUE
509
+ pl_lseg_perp(VALUE obj, VALUE a)
510
+ {
511
+ LSEG *l0, *l1;
512
+
513
+ CHECK_CLASS(obj, a);
514
+ Data_Get_Struct(obj, LSEG, l0);
515
+ Data_Get_Struct(a, LSEG, l1);
516
+ if (PLRUBY_DFC2(lseg_perp, l0, l1)) return Qtrue;
517
+ return Qfalse;
518
+ }
519
+
520
+ #define LSEG_BOOL(NAME_,FUNCTION_) \
521
+ static VALUE \
522
+ NAME_(VALUE obj) \
523
+ { \
524
+ LSEG *l; \
525
+ \
526
+ Data_Get_Struct(obj, LSEG, l); \
527
+ if (PLRUBY_DFC1(FUNCTION_, l)) return Qtrue;\
528
+ return Qfalse; \
529
+ }
530
+
531
+ LSEG_BOOL(pl_lseg_horizontal,lseg_horizontal);
532
+ LSEG_BOOL(pl_lseg_vertical,lseg_vertical);
533
+
534
+ static VALUE
535
+ pl_lseg_cmp(VALUE obj, VALUE a)
536
+ {
537
+ LSEG *l0, *l1;
538
+
539
+ if (!rb_obj_is_kind_of(a, rb_obj_class(obj))) {
540
+ return Qnil;
541
+ }
542
+ Data_Get_Struct(obj, LSEG, l0);
543
+ Data_Get_Struct(a, LSEG, l1);
544
+ if (PLRUBY_DFC2(lseg_eq, l0, l1)) return INT2NUM(0);
545
+ if (PLRUBY_DFC2(lseg_lt, l0, l1)) return INT2NUM(-1);
546
+ return INT2NUM(1);
547
+ }
548
+
549
+ static VALUE
550
+ pl_lseg_center(VALUE obj)
551
+ {
552
+ LSEG *l;
553
+ Point *p;
554
+ VALUE res;
555
+
556
+ Data_Get_Struct(obj, LSEG, l);
557
+ res = Data_Make_Struct(pl_cPoint, Point, pl_point_mark, free, p);
558
+ CPY_FREE(p, PLRUBY_DFC1(lseg_center, l), sizeof(Point));
559
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
560
+ return res;
561
+ }
562
+
563
+ static VALUE
564
+ pl_lseg_closest(VALUE obj, VALUE a)
565
+ {
566
+ LSEG *l0, *l1;
567
+ Point *p0, *p1;
568
+ VALUE res;
569
+
570
+ Data_Get_Struct(obj, LSEG, l0);
571
+ if (TYPE(a) == T_DATA) {
572
+ if (RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_point_mark) {
573
+ Point *p;
574
+
575
+ Data_Get_Struct(a, Point, p);
576
+ p0 = (Point *)PLRUBY_DFC2(close_ps, p, l0);
577
+ if (!p0) return Qnil;
578
+ res = Data_Make_Struct(pl_cPoint, Point, pl_point_mark, free, p1);
579
+ CPY_FREE(p1, p0, sizeof(Point));
580
+ if (OBJ_TAINTED(obj) || OBJ_TAINTED(a)) OBJ_TAINT(res);
581
+ return res;
582
+ }
583
+ if (RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_lseg_mark) {
584
+ Data_Get_Struct(a, LSEG, l1);
585
+ p0 = (Point *)PLRUBY_DFC2(close_lseg, l0, l1);
586
+ if (!p0) return Qnil;
587
+ res = Data_Make_Struct(pl_cPoint, Point, pl_point_mark, free, p1);
588
+ CPY_FREE(p1, p0, sizeof(Point));
589
+ if (OBJ_TAINTED(obj) || OBJ_TAINTED(a)) OBJ_TAINT(res);
590
+ return res;
591
+ }
592
+ }
593
+ return rb_funcall(a, rb_frame_last_func(), 1, obj);
594
+ }
595
+
596
+ static VALUE
597
+ pl_lseg_intersect(VALUE obj, VALUE a)
598
+ {
599
+ LSEG *l0, *l1;
600
+
601
+ Data_Get_Struct(obj, LSEG, l0);
602
+ if (TYPE(a) == T_DATA &&
603
+ RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_lseg_mark) {
604
+ Data_Get_Struct(a, LSEG, l1);
605
+ if (PLRUBY_DFC2(lseg_intersect, l0, l1)) return Qtrue;
606
+ return Qfalse;
607
+ }
608
+ return rb_funcall(a, rb_frame_last_func(), 1, obj);
609
+ }
610
+
611
+ static VALUE
612
+ pl_lseg_intersection(VALUE obj, VALUE a)
613
+ {
614
+ LSEG *l0, *l1;
615
+ Point *p0, *p1;
616
+ VALUE res;
617
+
618
+ Data_Get_Struct(obj, LSEG, l0);
619
+ if (!rb_obj_is_kind_of(a, rb_obj_class(obj))) {
620
+ rb_raise(rb_eArgError, "intersection : expected a Segment");
621
+ }
622
+ Data_Get_Struct(a, LSEG, l1);
623
+ p0 = (Point *)PLRUBY_DFC2(lseg_interpt, l0, l1);
624
+ if (!p0) return Qnil;
625
+ res = Data_Make_Struct(pl_cPoint, Point, pl_point_mark, free, p1);
626
+ CPY_FREE(p1, p0, sizeof(Point));
627
+ if (OBJ_TAINTED(obj) || OBJ_TAINTED(a)) OBJ_TAINT(res);
628
+ return res;
629
+ }
630
+
631
+ static void pl_box_mark(BOX *l) {}
632
+
633
+ static VALUE
634
+ pl_box_s_alloc(VALUE obj)
635
+ {
636
+ BOX *box;
637
+ return Data_Make_Struct(obj, BOX, pl_box_mark, free, box);
638
+ }
639
+
640
+ INIT_COPY(pl_box_init_copy, BOX, pl_box_mark);
641
+
642
+ static VALUE
643
+ pl_box_s_datum(VALUE obj, VALUE a)
644
+ {
645
+ BOX *p0, *p1;
646
+ Oid typoid;
647
+ VALUE res;
648
+
649
+ p0 = (BOX *)plruby_datum_get(a, &typoid);
650
+ if (typoid != BOXOID) {
651
+ rb_raise(rb_eArgError, "unknown OID type %d", typoid);
652
+ }
653
+ p1 = ALLOC_N(BOX, 1);
654
+ memcpy(p1, p0, sizeof(BOX));
655
+ res = Data_Wrap_Struct(obj, pl_box_mark, free, p1);
656
+ OBJ_TAINT(res);
657
+ return res;
658
+ }
659
+
660
+ static VALUE
661
+ pl_box_to_datum(VALUE obj, VALUE a)
662
+ {
663
+ BOX *p0, *p1;
664
+ int typoid;
665
+
666
+ typoid = plruby_datum_oid(a, 0);
667
+ switch (typoid) {
668
+ case BOXOID:
669
+ break;
670
+
671
+ case CIRCLEOID:
672
+ obj = pl_convert(obj, rb_intern("to_circle"), pl_circle_mark);
673
+ return rb_funcall(obj, rb_frame_last_func(), 1, a);
674
+
675
+ case POLYGONOID:
676
+ obj = pl_convert(obj, rb_intern("to_poly"), pl_poly_mark);
677
+ return rb_funcall(obj, rb_frame_last_func(), 1, a);
678
+
679
+ case POINTOID:
680
+ obj = pl_convert(obj, rb_intern("to_point"), pl_point_mark);
681
+ return rb_funcall(obj, rb_frame_last_func(), 1, a);
682
+
683
+ default:
684
+ return Qnil;
685
+ }
686
+ Data_Get_Struct(obj, BOX, p0);
687
+ p1 = (BOX *)palloc(sizeof(BOX));
688
+ memcpy(p1, p0, sizeof(BOX));
689
+ return plruby_datum_set(a, (Datum)p1);
690
+ }
691
+
692
+ PL_MLOAD(pl_box_mload, box_recv, BOX);
693
+ PL_MDUMP(pl_box_mdump, box_send);
694
+
695
+ static VALUE
696
+ pl_box_s_str(VALUE obj, VALUE a)
697
+ {
698
+ BOX *l;
699
+ VALUE res;
700
+
701
+ a = plruby_to_s(a);
702
+ res = Data_Make_Struct(obj, BOX, pl_box_mark, free, l);
703
+ CPY_FREE(l, PLRUBY_DFC1(box_in, RSTRING_PTR(a)), sizeof(BOX));
704
+ if (OBJ_TAINTED(obj) || OBJ_TAINTED(a)) OBJ_TAINT(res);
705
+ return res;
706
+ }
707
+
708
+ static void
709
+ pl_box_adjust(BOX *bx)
710
+ {
711
+ if (bx->high.x < bx->low.x) {
712
+ double x = bx->high.x;
713
+ bx->high.x = bx->low.x;
714
+ bx->low.x = x;
715
+ }
716
+ if (bx->high.y < bx->low.y) {
717
+ double y = bx->high.y;
718
+ bx->high.y = bx->low.y;
719
+ bx->low.y = y;
720
+ }
721
+ }
722
+
723
+ static VALUE
724
+ pl_box_init(int argc, VALUE *argv, VALUE obj)
725
+ {
726
+ BOX *bx;
727
+
728
+ if (argc != 2 && argc != 4) {
729
+ rb_raise(rb_eArgError, "initialize : expected 2 Points");
730
+ }
731
+ Data_Get_Struct(obj, BOX, bx);
732
+ if (argc == 2) {
733
+ Point *p0, *p1;
734
+ VALUE a, b;
735
+
736
+ a = argv[0];
737
+ b = argv[1];
738
+ if (TYPE(a) != T_DATA ||
739
+ RDATA(a)->dmark != (RUBY_DATA_FUNC)pl_point_mark) {
740
+ a = pl_convert(a, rb_intern("to_point"), pl_point_mark);
741
+ }
742
+ if (TYPE(b) != T_DATA ||
743
+ RDATA(b)->dmark != (RUBY_DATA_FUNC)pl_point_mark) {
744
+ b = pl_convert(b, rb_intern("to_point"), pl_point_mark);
745
+ }
746
+ Data_Get_Struct(a, Point, p0);
747
+ Data_Get_Struct(b, Point, p1);
748
+ bx->low.x = p0->x;
749
+ bx->low.y = p0->y;
750
+ bx->high.x = p1->x;
751
+ bx->high.y = p1->y;
752
+ }
753
+ else {
754
+ bx->low.x = RFLOAT_VALUE(rb_Float(argv[0]));
755
+ bx->low.y = RFLOAT_VALUE(rb_Float(argv[1]));
756
+ bx->high.x = RFLOAT_VALUE(rb_Float(argv[2]));
757
+ bx->high.y = RFLOAT_VALUE(rb_Float(argv[3]));
758
+ }
759
+ pl_box_adjust(bx);
760
+ return obj;
761
+ }
762
+
763
+ TO_STRING(pl_box_to_s,box_out);
764
+
765
+ static VALUE
766
+ pl_box_aref(VALUE obj, VALUE a)
767
+ {
768
+ BOX *box;
769
+ Point *point;
770
+ int i;
771
+ VALUE res;
772
+
773
+ Data_Get_Struct(obj, BOX, box);
774
+ i = NUM2INT(rb_Integer(a));
775
+ if (i < 0) i = -i;
776
+ switch (i) {
777
+ case 0:
778
+ res = Data_Make_Struct(pl_cPoint, Point, pl_point_mark, free, point);
779
+ point->x = box->low.x;
780
+ point->y = box->low.y;
781
+ break;
782
+
783
+ case 1:
784
+ res = Data_Make_Struct(pl_cPoint, Point, pl_point_mark, free, point);
785
+ point->x = box->high.x;
786
+ point->y = box->high.y;
787
+ break;
788
+
789
+ default:
790
+ res = Qnil;
791
+ }
792
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
793
+ return res;
794
+ }
795
+
796
+ static VALUE
797
+ pl_box_low(VALUE obj)
798
+ {
799
+ BOX *box;
800
+ Point *point;
801
+ VALUE res;
802
+
803
+ Data_Get_Struct(obj, BOX, box);
804
+ res = Data_Make_Struct(pl_cPoint, Point, pl_point_mark, free, point);
805
+ point->x = box->low.x;
806
+ point->y = box->low.y;
807
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
808
+ return res;
809
+ }
810
+
811
+ static VALUE
812
+ pl_box_high(VALUE obj)
813
+ {
814
+ BOX *box;
815
+ Point *point;
816
+ VALUE res;
817
+
818
+ Data_Get_Struct(obj, BOX, box);
819
+ res = Data_Make_Struct(pl_cPoint, Point, pl_point_mark, free, point);
820
+ point->x = box->high.x;
821
+ point->y = box->high.y;
822
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
823
+ return res;
824
+ }
825
+
826
+ static VALUE
827
+ pl_box_aset(VALUE obj, VALUE a, VALUE b)
828
+ {
829
+ BOX *box;
830
+ Point *point;
831
+ int i;
832
+
833
+ Data_Get_Struct(obj, BOX, box);
834
+ i = NUM2INT(rb_Integer(a));
835
+ b = pl_convert(b, rb_intern("to_point"), pl_point_mark);
836
+ Data_Get_Struct(b, Point, point);
837
+ if (i < 0) i = -i;
838
+ switch (i) {
839
+ case 0:
840
+ box->low.x = point->x;
841
+ box->low.y = point->y;
842
+ break;
843
+ case 1:
844
+ box->high.x = point->x;
845
+ box->high.y = point->y;
846
+ break;
847
+ default:
848
+ rb_raise(rb_eArgError, "[]= invalid indice");
849
+ }
850
+ pl_box_adjust(box);
851
+ return b;
852
+ }
853
+
854
+ static VALUE
855
+ pl_box_lowset(VALUE obj, VALUE a)
856
+ {
857
+ BOX *box;
858
+ Point *point;
859
+
860
+ Data_Get_Struct(obj, BOX, box);
861
+ a = pl_convert(a, rb_intern("to_point"), pl_point_mark);
862
+ Data_Get_Struct(a, Point, point);
863
+ box->low.x = point->x;
864
+ box->low.y = point->y;
865
+ pl_box_adjust(box);
866
+ return a;
867
+ }
868
+
869
+ static VALUE
870
+ pl_box_highset(VALUE obj, VALUE a)
871
+ {
872
+ BOX *box;
873
+ Point *point;
874
+
875
+ Data_Get_Struct(obj, BOX, box);
876
+ a = pl_convert(a, rb_intern("to_point"), pl_point_mark);
877
+ Data_Get_Struct(a, Point, point);
878
+ box->high.x = point->x;
879
+ box->high.y = point->y;
880
+ pl_box_adjust(box);
881
+ return a;
882
+ }
883
+
884
+ static VALUE
885
+ pl_box_cmp(VALUE obj, VALUE a)
886
+ {
887
+ BOX *l0, *l1;
888
+
889
+ if (!rb_obj_is_kind_of(a, rb_obj_class(obj))) {
890
+ return Qnil;
891
+ }
892
+ Data_Get_Struct(obj, BOX, l0);
893
+ Data_Get_Struct(a, BOX, l1);
894
+ if (PLRUBY_DFC2(box_eq, l0, l1)) return INT2NUM(0);
895
+ if (PLRUBY_DFC2(box_lt, l0, l1)) return INT2NUM(-1);
896
+ return INT2NUM(1);
897
+ }
898
+
899
+ #define BOX_BOOL(NAME_,FUNCTION_) \
900
+ static VALUE \
901
+ NAME_(VALUE obj, VALUE a) \
902
+ { \
903
+ BOX *p0, *p1; \
904
+ \
905
+ CHECK_CLASS(obj, a); \
906
+ Data_Get_Struct(obj, BOX, p0); \
907
+ Data_Get_Struct(a, BOX, p1); \
908
+ if (PLRUBY_DFC2(FUNCTION_, p0, p1)) return Qtrue; \
909
+ return Qfalse; \
910
+ }
911
+
912
+ BOX_BOOL(pl_box_same,box_same);
913
+ BOX_BOOL(pl_box_overlap,box_overlap);
914
+ BOX_BOOL(pl_box_overleft,box_overleft);
915
+ BOX_BOOL(pl_box_left,box_left);
916
+ BOX_BOOL(pl_box_right,box_right);
917
+ BOX_BOOL(pl_box_overright,box_overright);
918
+ BOX_BOOL(pl_box_contained,box_contained);
919
+ BOX_BOOL(pl_box_contain,box_contain);
920
+ BOX_BOOL(pl_box_below,box_below);
921
+ BOX_BOOL(pl_box_above,box_above);
922
+
923
+ #define BOX_CALL(NAME_,FUNCTION_) \
924
+ static VALUE \
925
+ NAME_(VALUE obj, VALUE a) \
926
+ { \
927
+ BOX *p0, *pr; \
928
+ VALUE res; \
929
+ Point *pt; \
930
+ \
931
+ Data_Get_Struct(obj, BOX, p0); \
932
+ a = pl_convert(a, rb_intern("to_point"), pl_point_mark); \
933
+ Data_Get_Struct(a, Point, pt); \
934
+ res = Data_Make_Struct(rb_obj_class(obj), BOX, \
935
+ pl_box_mark, free, pr); \
936
+ CPY_FREE(pr, PLRUBY_DFC2(FUNCTION_, p0, pt), sizeof(BOX)); \
937
+ if (OBJ_TAINTED(obj) || OBJ_TAINTED(a)) OBJ_TAINT(res); \
938
+ return res; \
939
+ }
940
+
941
+ BOX_CALL(pl_box_add,box_add);
942
+ BOX_CALL(pl_box_sub,box_sub);
943
+ BOX_CALL(pl_box_mul,box_mul);
944
+ BOX_CALL(pl_box_div,box_div);
945
+
946
+ #define BOX_FLOAT(NAME_,FUNCTION_) \
947
+ static VALUE \
948
+ NAME_(VALUE obj) \
949
+ { \
950
+ BOX *l; \
951
+ \
952
+ Data_Get_Struct(obj, BOX, l); \
953
+ RETURN_FLOAT(obj, PLRUBY_DFC1(FUNCTION_, l));\
954
+ }
955
+
956
+ BOX_FLOAT(pl_box_area,box_area);
957
+ BOX_FLOAT(pl_box_height,box_height);
958
+ BOX_FLOAT(pl_box_width,box_width);
959
+
960
+ static VALUE
961
+ pl_box_center(VALUE obj)
962
+ {
963
+ BOX *b;
964
+ Point *p0, *p1;
965
+ VALUE res;
966
+
967
+ Data_Get_Struct(obj, BOX, b);
968
+ p0 = (Point *)PLRUBY_DFC1(box_center, b);
969
+ if (!p0) return Qnil;
970
+ res = Data_Make_Struct(pl_cPoint, Point, pl_point_mark, free, p1);
971
+ CPY_FREE(p1, p0, sizeof(Point));
972
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
973
+ return res;
974
+ }
975
+
976
+ static VALUE
977
+ pl_box_closest(VALUE obj, VALUE a)
978
+ {
979
+ BOX *l0;
980
+ Point *p0, *p1;
981
+ VALUE res;
982
+
983
+ Data_Get_Struct(obj, BOX, l0);
984
+ if (TYPE(a) == T_DATA) {
985
+ if (RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_point_mark) {
986
+ Point *p;
987
+
988
+ Data_Get_Struct(a, Point, p);
989
+ p0 = (Point *)PLRUBY_DFC2(close_pb, p, l0);
990
+ if (!p0) return Qnil;
991
+ res = Data_Make_Struct(pl_cPoint, Point, pl_point_mark, free, p1);
992
+ CPY_FREE(p1, p0, sizeof(Point));
993
+ if (OBJ_TAINTED(obj) || OBJ_TAINTED(a)) OBJ_TAINT(res);
994
+ return res;
995
+ }
996
+ if (RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_lseg_mark) {
997
+ LSEG *p;
998
+
999
+ Data_Get_Struct(a, LSEG, p);
1000
+ p0 = (Point *)PLRUBY_DFC2(close_sb, p, l0);
1001
+ if (!p0) return Qnil;
1002
+ res = Data_Make_Struct(pl_cPoint, Point, pl_point_mark, free, p1);
1003
+ CPY_FREE(p1, p0, sizeof(Point));
1004
+ if (OBJ_TAINTED(obj) || OBJ_TAINTED(a)) OBJ_TAINT(res);
1005
+ return res;
1006
+ }
1007
+ }
1008
+ rb_raise(rb_eArgError, "closest : invalid argument");
1009
+ return Qnil;
1010
+ }
1011
+
1012
+ static VALUE
1013
+ pl_box_intersect(VALUE obj, VALUE a)
1014
+ {
1015
+ BOX *l0;
1016
+
1017
+ Data_Get_Struct(obj, BOX, l0);
1018
+ if (TYPE(a) == T_DATA) {
1019
+ if (RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_lseg_mark) {
1020
+ LSEG *p;
1021
+
1022
+ Data_Get_Struct(a, LSEG, p);
1023
+ if (PLRUBY_DFC2(inter_sb, p, l0)) return Qtrue;
1024
+ return Qfalse;
1025
+ }
1026
+ }
1027
+ rb_raise(rb_eArgError, "intersect : invalid argument");
1028
+ return Qnil;
1029
+ }
1030
+
1031
+ static VALUE
1032
+ pl_box_intersection(VALUE obj, VALUE a)
1033
+ {
1034
+ BOX *l0, *l1, *l2;
1035
+ VALUE res;
1036
+
1037
+ Data_Get_Struct(obj, BOX, l0);
1038
+ a = pl_convert(a, rb_intern("to_box"), pl_box_mark);
1039
+ Data_Get_Struct(a, BOX, l1);
1040
+ l1 = (BOX *)PLRUBY_DFC2(box_intersect, l0, l1);
1041
+ if (!l1) return Qnil;
1042
+ res = Data_Make_Struct(rb_obj_class(obj), BOX, pl_box_mark, free, l2);
1043
+ CPY_FREE(l2, l1, sizeof(BOX));
1044
+ if (OBJ_TAINTED(obj) || OBJ_TAINTED(a)) OBJ_TAINT(res);
1045
+ return res;
1046
+ }
1047
+
1048
+ static VALUE
1049
+ pl_box_diagonal(VALUE obj)
1050
+ {
1051
+ BOX *b;
1052
+ LSEG *l;
1053
+ VALUE res;
1054
+
1055
+ Data_Get_Struct(obj, BOX, b);
1056
+ res = Data_Make_Struct(obj, LSEG, pl_lseg_mark, free, l);
1057
+ CPY_FREE(l, PLRUBY_DFC1(box_diagonal, b), sizeof(LSEG));
1058
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
1059
+ return res;
1060
+ }
1061
+
1062
+ static void pl_path_mark(PATH *l) {}
1063
+
1064
+ #ifndef SET_VARSIZE
1065
+ #define SET_VARSIZE(p__, s__) (p__)->size = s__
1066
+ #define GET_VARSIZE(t__, p__) (p__)->size
1067
+ #else
1068
+ #define GET_VARSIZE(t__, p__) (offsetof(t__, p[0]) + sizeof(p__->p[0]) * (p__)->npts)
1069
+ #endif
1070
+
1071
+ static VALUE
1072
+ pl_path_s_alloc(VALUE obj)
1073
+ {
1074
+ PATH *path;
1075
+ VALUE res;
1076
+ int sz;
1077
+
1078
+ res = Data_Make_Struct(obj, PATH, pl_path_mark, free, path);
1079
+ sz = GET_VARSIZE(PATH, path);
1080
+ SET_VARSIZE(path, sz);
1081
+ return res;
1082
+ }
1083
+
1084
+ static VALUE
1085
+ pl_path_init_copy(VALUE copy, VALUE orig)
1086
+ {
1087
+ PATH *p0, *p1;
1088
+ int sz0, sz1;
1089
+
1090
+ if (copy == orig) return copy;
1091
+ if (TYPE(orig) != T_DATA ||
1092
+ RDATA(orig)->dmark != (RUBY_DATA_FUNC)pl_path_mark) {
1093
+ rb_raise(rb_eTypeError, "wrong argument type to clone");
1094
+ }
1095
+ Data_Get_Struct(orig, PATH, p0);
1096
+ Data_Get_Struct(copy, PATH, p1);
1097
+ sz0 = GET_VARSIZE(PATH, p0);
1098
+ sz1 = GET_VARSIZE(PATH, p1);
1099
+ if (sz0 != sz1) {
1100
+ free(p1);
1101
+ RDATA(copy)->data = 0;
1102
+ p1 = (PATH *)ALLOC_N(char, sz0);
1103
+ SET_VARSIZE(p1, sz0);
1104
+ RDATA(copy)->data = p1;
1105
+ }
1106
+ memcpy(p1, p0, sz0);
1107
+ return copy;
1108
+ }
1109
+
1110
+ static VALUE
1111
+ pl_path_s_datum(VALUE obj, VALUE a)
1112
+ {
1113
+ PATH *p0, *p1;
1114
+ Oid typoid;
1115
+ VALUE res;
1116
+ int sz0;
1117
+
1118
+ p0 = (PATH *)plruby_datum_get(a, &typoid);
1119
+ if (typoid != PATHOID) {
1120
+ rb_raise(rb_eArgError, "unknown OID type %d", typoid);
1121
+ }
1122
+ sz0 = GET_VARSIZE(PATH, p0);
1123
+ p1 = (PATH *)ALLOC_N(char, sz0);
1124
+ memcpy(p1, p0, sz0);
1125
+ res = Data_Wrap_Struct(obj, pl_path_mark, free, p1);
1126
+ OBJ_TAINT(res);
1127
+ return res;
1128
+ }
1129
+
1130
+ static VALUE
1131
+ pl_path_to_datum(VALUE obj, VALUE a)
1132
+ {
1133
+ PATH *p0, *p1;
1134
+ int typoid;
1135
+ int sz0;
1136
+
1137
+ typoid = plruby_datum_oid(a, 0);
1138
+ switch (typoid) {
1139
+ case PATHOID:
1140
+ break;
1141
+
1142
+ case POLYGONOID:
1143
+ obj = pl_convert(obj, rb_intern("to_poly"), pl_poly_mark);
1144
+ return rb_funcall(obj, rb_frame_last_func(), 1, a);
1145
+
1146
+ case POINTOID:
1147
+ obj = pl_convert(obj, rb_intern("to_point"), pl_point_mark);
1148
+ return rb_funcall(obj, rb_frame_last_func(), 1, a);
1149
+
1150
+ default:
1151
+ return Qnil;
1152
+ }
1153
+ Data_Get_Struct(obj, PATH, p0);
1154
+ sz0 = GET_VARSIZE(PATH, p0);
1155
+ p1 = (PATH *)palloc(sz0);
1156
+ memcpy(p1, p0, sz0);
1157
+ return plruby_datum_set(a, (Datum)p1);
1158
+ }
1159
+
1160
+ #define PATHSIZE(p_) GET_VARSIZE(PATH, p_)
1161
+ PL_MLOADVAR(pl_path_mload, path_recv, PATH, PATHSIZE);
1162
+ PL_MDUMP(pl_path_mdump, path_send);
1163
+
1164
+ static VALUE
1165
+ pl_path_s_str(VALUE obj, VALUE a)
1166
+ {
1167
+ PATH *p, *m;
1168
+ VALUE res;
1169
+ int sz0;
1170
+
1171
+ a = plruby_to_s(a);
1172
+ m = (PATH *)PLRUBY_DFC1(path_in, RSTRING_PTR(a));
1173
+ sz0 = GET_VARSIZE(PATH, m);
1174
+ p = (PATH *)ALLOC_N(char, sz0);
1175
+ CPY_FREE(p, m, sz0);
1176
+ res = Data_Wrap_Struct(obj, pl_path_mark, free, p);
1177
+ if (OBJ_TAINTED(obj) || OBJ_TAINTED(a)) OBJ_TAINT(res);
1178
+ return res;
1179
+ }
1180
+
1181
+ static VALUE
1182
+ pl_path_init(int argc, VALUE *argv, VALUE obj)
1183
+ {
1184
+ PATH *p;
1185
+ VALUE a;
1186
+ int i, size, closed = Qfalse;
1187
+
1188
+ if (argc < 1 || argc > 2) {
1189
+ rb_raise(rb_eArgError, "expected Array of Points");
1190
+ }
1191
+ if (argc == 2) {
1192
+ closed = RTEST(argv[1]);
1193
+ }
1194
+ a = rb_Array(argv[0]);
1195
+ Data_Get_Struct(obj, PATH, p);
1196
+ free(p);
1197
+ size = offsetof(PATH, p[0]) + sizeof(p->p[0]) * RARRAY_LEN(a);
1198
+ p = (PATH *)ALLOC_N(char, size);
1199
+ MEMZERO(p, char, size);
1200
+ p->closed = closed;
1201
+ DATA_PTR(obj) = p;
1202
+ for (i = 0; i < RARRAY_LEN(a); ++i) {
1203
+ VALUE b = RARRAY_PTR(a)[i];
1204
+ if (TYPE(b) == T_DATA &&
1205
+ RDATA(b)->dmark == (RUBY_DATA_FUNC)pl_point_mark) {
1206
+ Point *po;
1207
+
1208
+ Data_Get_Struct(b, Point, po);
1209
+ p->p[i].x = po->x;
1210
+ p->p[i].y = po->y;
1211
+ }
1212
+ else {
1213
+ VALUE tmp;
1214
+
1215
+ b = rb_Array(b);
1216
+ if (RARRAY_LEN(b) != 2) {
1217
+ rb_raise(rb_eArgError, "initialize : expected Array [x, y]");
1218
+ }
1219
+ tmp = rb_Float(RARRAY_PTR(b)[0]);
1220
+ p->p[i].x = RFLOAT_VALUE(tmp);
1221
+ tmp = rb_Float(RARRAY_PTR(b)[1]);
1222
+ p->p[i].y = RFLOAT_VALUE(tmp);
1223
+ }
1224
+ }
1225
+ p->npts = RARRAY_LEN(a);
1226
+ return obj;
1227
+ }
1228
+
1229
+ TO_STRING(pl_path_to_s, path_out);
1230
+
1231
+ static VALUE
1232
+ pl_path_cmp(VALUE obj, VALUE a)
1233
+ {
1234
+ PATH *l0, *l1;
1235
+
1236
+ if (!rb_obj_is_kind_of(a, rb_obj_class(obj))) {
1237
+ return Qnil;
1238
+ }
1239
+ Data_Get_Struct(obj, PATH, l0);
1240
+ Data_Get_Struct(a, PATH, l1);
1241
+ if (PLRUBY_DFC2(path_n_eq, l0, l1)) return INT2NUM(0);
1242
+ if (PLRUBY_DFC2(path_n_lt, l0, l1)) return INT2NUM(-1);
1243
+ return INT2NUM(1);
1244
+ }
1245
+
1246
+ static VALUE
1247
+ pl_path_npoints(VALUE obj)
1248
+ {
1249
+ PATH *p;
1250
+ Data_Get_Struct(obj, PATH, p);
1251
+ return INT2NUM(p->npts);
1252
+ }
1253
+
1254
+ static VALUE
1255
+ pl_path_close(VALUE obj)
1256
+ {
1257
+ PATH *p;
1258
+ Data_Get_Struct(obj, PATH, p);
1259
+ p->closed = Qtrue;
1260
+ return obj;
1261
+ }
1262
+
1263
+ static VALUE
1264
+ pl_path_open(VALUE obj)
1265
+ {
1266
+ PATH *p;
1267
+ Data_Get_Struct(obj, PATH, p);
1268
+ p->closed = Qfalse;
1269
+ return obj;
1270
+ }
1271
+
1272
+ static VALUE
1273
+ pl_path_closed(VALUE obj)
1274
+ {
1275
+ PATH *p;
1276
+ Data_Get_Struct(obj, PATH, p);
1277
+ return (p->closed?Qtrue:Qfalse);
1278
+ }
1279
+
1280
+ static VALUE
1281
+ pl_path_length(VALUE obj)
1282
+ {
1283
+ PATH *p;
1284
+
1285
+ Data_Get_Struct(obj, PATH, p);
1286
+ RETURN_FLOAT(obj, PLRUBY_DFC1(path_length, p));
1287
+ }
1288
+
1289
+ #define PATH_CALL(NAME_, FUNCTION_) \
1290
+ static VALUE \
1291
+ NAME_(VALUE obj, VALUE a) \
1292
+ { \
1293
+ PATH *p0, *p1, *p2; \
1294
+ int size; \
1295
+ Point *p; \
1296
+ VALUE res; \
1297
+ \
1298
+ Data_Get_Struct(obj, PATH, p0); \
1299
+ if (TYPE(a) != T_DATA || \
1300
+ RDATA(a)->dmark != (RUBY_DATA_FUNC)pl_point_mark) { \
1301
+ a = pl_convert(a, rb_intern("to_point"), pl_point_mark); \
1302
+ } \
1303
+ Data_Get_Struct(a, Point, p); \
1304
+ p1 = (PATH *)PLRUBY_DFC2(FUNCTION_, p0, p); \
1305
+ size = GET_VARSIZE(PATH, p1); \
1306
+ p2 = (PATH *)ALLOC_N(char, size); \
1307
+ CPY_FREE(p2, p1, size); \
1308
+ res = Data_Wrap_Struct(rb_obj_class(obj), pl_path_mark, free, p2); \
1309
+ if (OBJ_TAINTED(obj)|| OBJ_TAINTED(a)) OBJ_TAINT(res); \
1310
+ return res; \
1311
+ }
1312
+
1313
+ PATH_CALL(pl_path_add, path_add_pt);
1314
+ PATH_CALL(pl_path_sub, path_sub_pt);
1315
+ PATH_CALL(pl_path_mul, path_mul_pt);
1316
+ PATH_CALL(pl_path_div, path_div_pt);
1317
+
1318
+ static VALUE
1319
+ pl_path_concat(VALUE obj, VALUE a)
1320
+ {
1321
+ PATH *p0, *p1;
1322
+ Point *p;
1323
+ int sz1;
1324
+
1325
+ Data_Get_Struct(obj, PATH, p0);
1326
+ a = pl_convert(a, rb_intern("to_path"), pl_path_mark);
1327
+ Data_Get_Struct(a, Point, p);
1328
+ p1 = (PATH *)PLRUBY_DFC2(path_add_pt, p0, p);
1329
+ free(p0);
1330
+ sz1 = GET_VARSIZE(PATH, p1);
1331
+ p0 = (PATH *)ALLOC_N(char, sz1);
1332
+ CPY_FREE(p0, p1, sz1);
1333
+ RDATA(obj)->data = p0;
1334
+ return obj;
1335
+ }
1336
+
1337
+ #if PG_PL_VERSION >= 75
1338
+
1339
+ static VALUE
1340
+ pl_path_area(VALUE obj)
1341
+ {
1342
+ PATH *p0;
1343
+
1344
+ Data_Get_Struct(obj, PATH, p0);
1345
+ RETURN_FLOAT(obj, PLRUBY_DFC1(path_area, p0));
1346
+ }
1347
+
1348
+ #endif
1349
+
1350
+
1351
+ /* Extracted from geo_utils.c */
1352
+
1353
+ /*------------------------------------------------------------------
1354
+ * The following routines define a data type and operator class for
1355
+ * POLYGONS .... Part of which (the polygon's bounding box) is built on
1356
+ * top of the BOX data type.
1357
+ *
1358
+ * make_bound_box - create the bounding box for the input polygon
1359
+ *------------------------------------------------------------------*/
1360
+
1361
+ /*---------------------------------------------------------------------
1362
+ * Make the smallest bounding box for the given polygon.
1363
+ *---------------------------------------------------------------------*/
1364
+ static void
1365
+ make_bound_box(POLYGON *poly)
1366
+ {
1367
+ int i;
1368
+ double x1, y1, x2, y2;
1369
+
1370
+ if (poly->npts > 0) {
1371
+ x2 = x1 = poly->p[0].x;
1372
+ y2 = y1 = poly->p[0].y;
1373
+ for (i = 1; i < poly->npts; i++) {
1374
+ if (poly->p[i].x < x1)
1375
+ x1 = poly->p[i].x;
1376
+ if (poly->p[i].x > x2)
1377
+ x2 = poly->p[i].x;
1378
+ if (poly->p[i].y < y1)
1379
+ y1 = poly->p[i].y;
1380
+ if (poly->p[i].y > y2)
1381
+ y2 = poly->p[i].y;
1382
+ }
1383
+ poly->boundbox.low.x = x1;
1384
+ poly->boundbox.low.y = y1;
1385
+ poly->boundbox.high.x = x2;
1386
+ poly->boundbox.high.y = y2;
1387
+ pl_box_adjust(&(poly->boundbox));
1388
+ }
1389
+ else {
1390
+ rb_raise(rb_eArgError, "can't create bounding box for empty polygon");
1391
+ }
1392
+ }
1393
+
1394
+ static VALUE
1395
+ pl_poly_s_alloc(VALUE obj)
1396
+ {
1397
+ POLYGON *poly;
1398
+ VALUE res;
1399
+ int sz;
1400
+
1401
+ res = Data_Make_Struct(obj, POLYGON, pl_poly_mark, free, poly);
1402
+ sz = GET_VARSIZE(POLYGON, poly);
1403
+ SET_VARSIZE(poly, sz);
1404
+ return res;
1405
+ }
1406
+
1407
+ static VALUE
1408
+ pl_poly_init_copy(VALUE copy, VALUE orig)
1409
+ {
1410
+ POLYGON *p0, *p1;
1411
+ int sz0, sz1;
1412
+
1413
+ if (copy == orig) return copy;
1414
+ if (TYPE(orig) != T_DATA ||
1415
+ RDATA(orig)->dmark != (RUBY_DATA_FUNC)pl_poly_mark) {
1416
+ rb_raise(rb_eTypeError, "wrong argument type to clone");
1417
+ }
1418
+ Data_Get_Struct(orig, POLYGON, p0);
1419
+ Data_Get_Struct(copy, POLYGON, p1);
1420
+ sz0 = GET_VARSIZE(POLYGON, p0);
1421
+ sz1 = GET_VARSIZE(POLYGON, p1);
1422
+ if (sz0 != sz1) {
1423
+ free(p1);
1424
+ RDATA(copy)->data = 0;
1425
+ p1 = (POLYGON *)ALLOC_N(char, sz0);
1426
+ SET_VARSIZE(p1, sz0);
1427
+ RDATA(copy)->data = p1;
1428
+ }
1429
+ memcpy(p1, p0, sz0);
1430
+ return copy;
1431
+ }
1432
+
1433
+ static VALUE
1434
+ pl_poly_s_datum(VALUE obj, VALUE a)
1435
+ {
1436
+ POLYGON *p0, *p1;
1437
+ Oid typoid;
1438
+ VALUE res;
1439
+ int sz0;
1440
+
1441
+ p0 = (POLYGON *)plruby_datum_get(a, &typoid);
1442
+ if (typoid != POLYGONOID) {
1443
+ rb_raise(rb_eArgError, "unknown OID type %d", typoid);
1444
+ }
1445
+ sz0 = GET_VARSIZE(POLYGON, p0);
1446
+ p1 = (POLYGON *)ALLOC_N(char, sz0);
1447
+ memcpy(p1, p0, sz0);
1448
+ res = Data_Wrap_Struct(obj, pl_poly_mark, free, p1);
1449
+ OBJ_TAINT(res);
1450
+ return res;
1451
+ }
1452
+
1453
+ static VALUE
1454
+ pl_poly_to_datum(VALUE obj, VALUE a)
1455
+ {
1456
+ POLYGON *p0, *p1;
1457
+ int typoid;
1458
+ int sz0;
1459
+
1460
+ typoid = plruby_datum_oid(a, 0);
1461
+ switch (typoid) {
1462
+ case POLYGONOID:
1463
+ break;
1464
+
1465
+ case CIRCLEOID:
1466
+ obj = pl_convert(obj, rb_intern("to_circle"), pl_circle_mark);
1467
+ return rb_funcall(obj, rb_frame_last_func(), 1, a);
1468
+
1469
+ case PATHOID:
1470
+ obj = pl_convert(obj, rb_intern("to_path"), pl_path_mark);
1471
+ return rb_funcall(obj, rb_frame_last_func(), 1, a);
1472
+
1473
+ case BOXOID:
1474
+ obj = pl_convert(obj, rb_intern("to_box"), pl_box_mark);
1475
+ return rb_funcall(obj, rb_frame_last_func(), 1, a);
1476
+
1477
+ case POINTOID:
1478
+ obj = pl_convert(obj, rb_intern("to_point"), pl_point_mark);
1479
+ return rb_funcall(obj, rb_frame_last_func(), 1, a);
1480
+
1481
+ default:
1482
+ return Qnil;
1483
+ }
1484
+ Data_Get_Struct(obj, POLYGON, p0);
1485
+ sz0 = GET_VARSIZE(POLYGON, p0);
1486
+ p1 = (POLYGON *)palloc(sz0);
1487
+ memcpy(p1, p0, sz0);
1488
+ return plruby_datum_set(a, (Datum)p1);
1489
+ }
1490
+
1491
+ #define POLYSIZE(p_) GET_VARSIZE(POLYGON, p_)
1492
+ PL_MLOADVAR(pl_poly_mload, poly_recv, POLYGON, POLYSIZE);
1493
+ PL_MDUMP(pl_poly_mdump, poly_send);
1494
+
1495
+ static VALUE
1496
+ pl_poly_s_str(VALUE obj, VALUE a)
1497
+ {
1498
+ POLYGON *p, *m;
1499
+ VALUE res;
1500
+ int sz0;
1501
+
1502
+ a = plruby_to_s(a);
1503
+ m = (POLYGON *)PLRUBY_DFC1(poly_in, RSTRING_PTR(a));
1504
+ sz0 = GET_VARSIZE(POLYGON, m);
1505
+ p = (POLYGON *)ALLOC_N(char, sz0);
1506
+ CPY_FREE(p, m, sz0);
1507
+ res = Data_Wrap_Struct(obj, pl_poly_mark, free, p);
1508
+ if (OBJ_TAINTED(obj) || OBJ_TAINTED(a)) OBJ_TAINT(res);
1509
+ return res;
1510
+ }
1511
+
1512
+ static VALUE
1513
+ pl_poly_init(int argc, VALUE *argv, VALUE obj)
1514
+ {
1515
+ POLYGON *p;
1516
+ VALUE a;
1517
+ int i, size, closed = Qfalse;
1518
+
1519
+ if (argc < 1 || argc > 2) {
1520
+ rb_raise(rb_eArgError, "initialize : expected Array of Points");
1521
+ }
1522
+ if (argc == 2) {
1523
+ closed = RTEST(argv[1]);
1524
+ }
1525
+ a = rb_Array(argv[0]);
1526
+ Data_Get_Struct(obj, POLYGON, p);
1527
+ free(p);
1528
+ size = offsetof(POLYGON, p[0]) + sizeof(p->p[0]) * RARRAY_LEN(a);
1529
+ p = (POLYGON *)ALLOC_N(char, size);
1530
+ MEMZERO(p, char, size);
1531
+ DATA_PTR(obj) = p;
1532
+ p->npts = RARRAY_LEN(a);
1533
+ for (i = 0; i < p->npts; ++i) {
1534
+ VALUE b = RARRAY_PTR(a)[i];
1535
+ if (TYPE(b) == T_DATA &&
1536
+ RDATA(b)->dmark == (RUBY_DATA_FUNC)pl_point_mark) {
1537
+ Point *po;
1538
+
1539
+ Data_Get_Struct(b, Point, po);
1540
+ p->p[i].x = po->x;
1541
+ p->p[i].y = po->y;
1542
+ }
1543
+ else {
1544
+ VALUE tmp;
1545
+
1546
+ b = rb_Array(b);
1547
+ if (RARRAY_LEN(b) != 2) {
1548
+ rb_raise(rb_eArgError, "initialize : expected Array [x, y]");
1549
+ }
1550
+ tmp = rb_Float(RARRAY_PTR(b)[0]);
1551
+ p->p[i].x = RFLOAT_VALUE(tmp);
1552
+ tmp = rb_Float(RARRAY_PTR(b)[1]);
1553
+ p->p[i].y = RFLOAT_VALUE(tmp);
1554
+ }
1555
+ }
1556
+ make_bound_box(p);
1557
+ return obj;
1558
+ }
1559
+
1560
+ TO_STRING(pl_poly_to_s, poly_out);
1561
+
1562
+ #define POLY_BOOL(NAME_,FUNCTION_) \
1563
+ static VALUE \
1564
+ NAME_(VALUE obj, VALUE a) \
1565
+ { \
1566
+ POLYGON *p0, *p1; \
1567
+ \
1568
+ CHECK_CLASS(obj, a); \
1569
+ Data_Get_Struct(obj, POLYGON, p0); \
1570
+ Data_Get_Struct(a, POLYGON, p1); \
1571
+ if (PLRUBY_DFC2(FUNCTION_, p0, p1)) return Qtrue;\
1572
+ return Qfalse; \
1573
+ }
1574
+
1575
+ POLY_BOOL(pl_poly_same,poly_same);
1576
+ POLY_BOOL(pl_poly_overlap,poly_overlap);
1577
+ POLY_BOOL(pl_poly_overleft,poly_overleft);
1578
+ POLY_BOOL(pl_poly_left,poly_left);
1579
+ POLY_BOOL(pl_poly_right,poly_right);
1580
+ POLY_BOOL(pl_poly_overright,poly_overright);
1581
+ POLY_BOOL(pl_poly_contained,poly_contained);
1582
+
1583
+ static VALUE
1584
+ pl_poly_contain(VALUE obj, VALUE a)
1585
+ {
1586
+ POLYGON *p0;
1587
+
1588
+ Data_Get_Struct(obj, POLYGON, p0);
1589
+ if (TYPE(a) != T_DATA) {
1590
+ rb_raise(rb_eArgError, "contain : expected a geometry object");
1591
+ }
1592
+ if (RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_point_mark) {
1593
+ Point *p1;
1594
+
1595
+ Data_Get_Struct(a, Point, p1);
1596
+ if (PLRUBY_DFC2(poly_contain_pt, p0, p1)) return Qtrue;
1597
+ return Qfalse;
1598
+ }
1599
+ if (RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_poly_mark) {
1600
+ POLYGON *p1;
1601
+
1602
+ Data_Get_Struct(a, POLYGON, p1);
1603
+ if (PLRUBY_DFC2(poly_contain, p0, p1)) return Qtrue;
1604
+ return Qfalse;
1605
+ }
1606
+ rb_raise(rb_eArgError, "invalid geometry object");
1607
+ return Qnil;
1608
+ }
1609
+
1610
+ static VALUE
1611
+ pl_poly_npoints(VALUE obj)
1612
+ {
1613
+ POLYGON *p;
1614
+ Data_Get_Struct(obj, POLYGON, p);
1615
+ return INT2NUM(p->npts);
1616
+ }
1617
+
1618
+ static VALUE
1619
+ pl_poly_center(VALUE obj)
1620
+ {
1621
+ POLYGON *p;
1622
+ Point *p0, *p1;
1623
+ VALUE res;
1624
+
1625
+ Data_Get_Struct(obj, POLYGON, p);
1626
+ p0 = (Point *)PLRUBY_DFC1(poly_center, p);
1627
+ if (!p0) return Qnil;
1628
+ res = Data_Make_Struct(pl_cPoint, Point, pl_point_mark, free, p1);
1629
+ CPY_FREE(p1, p0, sizeof(Point));
1630
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
1631
+ return res;
1632
+ }
1633
+
1634
+ static VALUE pl_cPoly, pl_cBox, pl_cPath;
1635
+
1636
+ static VALUE
1637
+ pl_box_to_poly(VALUE obj)
1638
+ {
1639
+ BOX *b;
1640
+ POLYGON *p0, *p1;
1641
+ VALUE res;
1642
+ int sz0;
1643
+
1644
+ Data_Get_Struct(obj, BOX, b);
1645
+ p0 = (POLYGON *)PLRUBY_DFC1(box_poly, b);
1646
+ if (!p0) return Qnil;
1647
+ sz0 = GET_VARSIZE(POLYGON, p0);
1648
+ p1 = (POLYGON *)ALLOC_N(char, sz0);
1649
+ CPY_FREE(p1, p0, sz0);
1650
+ res = Data_Wrap_Struct(pl_cPoly, pl_poly_mark, free, p1);
1651
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
1652
+ return res;
1653
+ }
1654
+
1655
+ static VALUE
1656
+ pl_path_to_poly(VALUE obj)
1657
+ {
1658
+ PATH *b;
1659
+ POLYGON *p0, *p1;
1660
+ VALUE res;
1661
+ int sz0;
1662
+
1663
+ Data_Get_Struct(obj, PATH, b);
1664
+ p0 = (POLYGON *)PLRUBY_DFC1(path_poly, b);
1665
+ if (!p0) return Qnil;
1666
+ sz0 = GET_VARSIZE(POLYGON, p0);
1667
+ p1 = (POLYGON *)ALLOC_N(char, sz0);
1668
+ CPY_FREE(p1, p0, sz0);
1669
+ res = Data_Wrap_Struct(pl_cPoly, pl_poly_mark, free, p1);
1670
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
1671
+ return res;
1672
+ }
1673
+
1674
+ static VALUE
1675
+ pl_poly_to_path(VALUE obj)
1676
+ {
1677
+ POLYGON *b;
1678
+ PATH *p0, *p1;
1679
+ VALUE res;
1680
+ int sz0;
1681
+
1682
+ Data_Get_Struct(obj, POLYGON, b);
1683
+ p0 = (PATH *)PLRUBY_DFC1(poly_path, b);
1684
+ if (!p0) return Qnil;
1685
+ sz0 = GET_VARSIZE(PATH, p0);
1686
+ p1 = (PATH *)ALLOC_N(char, sz0);
1687
+ CPY_FREE(p1, p0, sz0);
1688
+ res = Data_Wrap_Struct(pl_cPath, pl_path_mark, free, p1);
1689
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
1690
+ return res;
1691
+ }
1692
+
1693
+ static VALUE
1694
+ pl_poly_to_box(VALUE obj)
1695
+ {
1696
+ POLYGON *b;
1697
+ BOX *p0, *p1;
1698
+ VALUE res;
1699
+
1700
+ Data_Get_Struct(obj, POLYGON, b);
1701
+ p0 = (BOX *)PLRUBY_DFC1(poly_box, b);
1702
+ if (!p0) return Qnil;
1703
+ res = Data_Make_Struct(pl_cBox, BOX, pl_box_mark, free, p1);
1704
+ CPY_FREE(p1, p0, sizeof(BOX));
1705
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
1706
+ return res;
1707
+ }
1708
+
1709
+ static VALUE
1710
+ pl_circle_s_alloc(VALUE obj)
1711
+ {
1712
+ CIRCLE *circle;
1713
+ return Data_Make_Struct(obj, CIRCLE, pl_circle_mark, free, circle);
1714
+ }
1715
+
1716
+ INIT_COPY(pl_circle_init_copy, CIRCLE, pl_circle_mark);
1717
+
1718
+ static VALUE
1719
+ pl_circle_s_datum(VALUE obj, VALUE a)
1720
+ {
1721
+ CIRCLE *p0, *p1;
1722
+ Oid typoid;
1723
+ VALUE res;
1724
+
1725
+ p0 = (CIRCLE *)plruby_datum_get(a, &typoid);
1726
+ if (typoid != CIRCLEOID) {
1727
+ rb_raise(rb_eArgError, "unknown OID type %d", typoid);
1728
+ }
1729
+ p1 = ALLOC_N(CIRCLE, 1);
1730
+ memcpy(p1, p0, sizeof(CIRCLE));
1731
+ res = Data_Wrap_Struct(obj, pl_circle_mark, free, p1);
1732
+ OBJ_TAINT(res);
1733
+ return res;
1734
+ }
1735
+
1736
+ static VALUE
1737
+ pl_circle_to_datum(VALUE obj, VALUE a)
1738
+ {
1739
+ CIRCLE *p0, *p1;
1740
+ int typoid;
1741
+
1742
+ typoid = plruby_datum_oid(a, 0);
1743
+ switch (typoid) {
1744
+ case CIRCLEOID:
1745
+ break;
1746
+
1747
+ case BOXOID:
1748
+ obj = pl_convert(obj, rb_intern("to_box"), pl_box_mark);
1749
+ return rb_funcall(obj, rb_frame_last_func(), 1, a);
1750
+
1751
+ case POLYGONOID:
1752
+ obj = pl_convert(obj, rb_intern("to_poly"), pl_poly_mark);
1753
+ return rb_funcall(obj, rb_frame_last_func(), 1, a);
1754
+
1755
+ case POINTOID:
1756
+ obj = pl_convert(obj, rb_intern("to_point"), pl_point_mark);
1757
+ return rb_funcall(obj, rb_frame_last_func(), 1, a);
1758
+
1759
+ default:
1760
+ return Qnil;
1761
+ }
1762
+ Data_Get_Struct(obj, CIRCLE, p0);
1763
+ p1 = (CIRCLE *)palloc(sizeof(CIRCLE));
1764
+ memcpy(p1, p0, sizeof(CIRCLE));
1765
+ return plruby_datum_set(a, (Datum)p1);
1766
+ }
1767
+
1768
+ PL_MLOAD(pl_circle_mload, circle_recv, CIRCLE);
1769
+ PL_MDUMP(pl_circle_mdump, circle_send);
1770
+
1771
+ static VALUE
1772
+ pl_circle_s_str(VALUE obj, VALUE a)
1773
+ {
1774
+ CIRCLE *p, *m;
1775
+ VALUE res;
1776
+
1777
+ a = plruby_to_s(a);
1778
+ m = (CIRCLE *)PLRUBY_DFC1(circle_in, RSTRING_PTR(a));
1779
+ res = Data_Make_Struct(obj, CIRCLE, pl_circle_mark, free, p);
1780
+ CPY_FREE(p, m, sizeof(CIRCLE));
1781
+ if (OBJ_TAINTED(obj) || OBJ_TAINTED(a)) OBJ_TAINT(res);
1782
+ return res;
1783
+ }
1784
+
1785
+ static VALUE
1786
+ pl_circle_init(VALUE obj, VALUE a, VALUE b)
1787
+ {
1788
+ CIRCLE *p;
1789
+
1790
+ Data_Get_Struct(obj, CIRCLE, p);
1791
+ if (TYPE(a) == T_DATA &&
1792
+ RDATA(b)->dmark == (RUBY_DATA_FUNC)pl_point_mark) {
1793
+ Point *po;
1794
+
1795
+ Data_Get_Struct(a, Point, po);
1796
+ p->center.x = po->x;
1797
+ p->center.y = po->y;
1798
+ }
1799
+ else {
1800
+ VALUE tmp;
1801
+
1802
+ a = rb_Array(a);
1803
+ if (RARRAY_LEN(a) != 2) {
1804
+ rb_raise(rb_eArgError, "initialize : expected Array [x, y]");
1805
+ }
1806
+ tmp = rb_Float(RARRAY_PTR(a)[0]);
1807
+ p->center.x = RFLOAT_VALUE(tmp);
1808
+ tmp = rb_Float(RARRAY_PTR(a)[1]);
1809
+ p->center.y = RFLOAT_VALUE(tmp);
1810
+ }
1811
+ p->radius = RFLOAT_VALUE(rb_Float(b));
1812
+ return obj;
1813
+ }
1814
+
1815
+ TO_STRING(pl_circle_to_s, circle_out);
1816
+
1817
+ #define CIRCLE_BOOL(NAME_,FUNCTION_) \
1818
+ static VALUE \
1819
+ NAME_(VALUE obj, VALUE a) \
1820
+ { \
1821
+ CIRCLE *p0, *p1; \
1822
+ \
1823
+ CHECK_CLASS(obj, a); \
1824
+ Data_Get_Struct(obj, CIRCLE, p0); \
1825
+ Data_Get_Struct(a, CIRCLE, p1); \
1826
+ if (PLRUBY_DFC2(FUNCTION_, p0, p1)) return Qtrue;\
1827
+ return Qfalse; \
1828
+ }
1829
+
1830
+ CIRCLE_BOOL(pl_circle_same,circle_same);
1831
+ CIRCLE_BOOL(pl_circle_overlap,circle_overlap);
1832
+ CIRCLE_BOOL(pl_circle_overleft,circle_overleft);
1833
+ CIRCLE_BOOL(pl_circle_left,circle_left);
1834
+ CIRCLE_BOOL(pl_circle_right,circle_right);
1835
+ CIRCLE_BOOL(pl_circle_overright,circle_overright);
1836
+ CIRCLE_BOOL(pl_circle_contained,circle_contained);
1837
+ CIRCLE_BOOL(pl_circle_below,circle_below);
1838
+ CIRCLE_BOOL(pl_circle_above,circle_above);
1839
+
1840
+ static VALUE
1841
+ pl_circle_contain(VALUE obj, VALUE a)
1842
+ {
1843
+ CIRCLE *p0;
1844
+
1845
+ Data_Get_Struct(obj, CIRCLE, p0);
1846
+ if (TYPE(a) != T_DATA) {
1847
+ rb_raise(rb_eArgError, "contain : expected a geometry object");
1848
+ }
1849
+ if (RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_point_mark) {
1850
+ Point *p1;
1851
+
1852
+ Data_Get_Struct(a, Point, p1);
1853
+ if (PLRUBY_DFC2(circle_contain_pt, p0, p1)) return Qtrue;
1854
+ return Qfalse;
1855
+ }
1856
+ if (RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_circle_mark) {
1857
+ CIRCLE *p1;
1858
+
1859
+ Data_Get_Struct(a, CIRCLE, p1);
1860
+ if (PLRUBY_DFC2(circle_contain, p0, p1)) return Qtrue;
1861
+ return Qfalse;
1862
+ }
1863
+ rb_raise(rb_eArgError, "contain : invalid geometry object");
1864
+ return Qnil;
1865
+ }
1866
+
1867
+ #define CIRCLE_CALL(NAME_,FUNCTION_) \
1868
+ static VALUE \
1869
+ NAME_(VALUE obj, VALUE a) \
1870
+ { \
1871
+ CIRCLE *p0, *pr; \
1872
+ Point *pt; \
1873
+ VALUE res; \
1874
+ \
1875
+ Data_Get_Struct(obj, CIRCLE, p0); \
1876
+ if (TYPE(a) != T_DATA || \
1877
+ RDATA(a)->dmark != (RUBY_DATA_FUNC)pl_point_mark) { \
1878
+ a = pl_convert(a, rb_intern("to_point"), pl_point_mark); \
1879
+ } \
1880
+ Data_Get_Struct(a, Point, pt); \
1881
+ res = Data_Make_Struct(rb_obj_class(obj), CIRCLE, \
1882
+ pl_circle_mark, free, pr); \
1883
+ CPY_FREE(pr, PLRUBY_DFC2(FUNCTION_, p0, pt), sizeof(CIRCLE)); \
1884
+ if (OBJ_TAINTED(obj) || OBJ_TAINTED(a)) OBJ_TAINT(res); \
1885
+ return res; \
1886
+ }
1887
+
1888
+ CIRCLE_CALL(pl_circle_add,circle_add_pt);
1889
+ CIRCLE_CALL(pl_circle_sub,circle_sub_pt);
1890
+ CIRCLE_CALL(pl_circle_mul,circle_mul_pt);
1891
+ CIRCLE_CALL(pl_circle_div,circle_div_pt);
1892
+
1893
+ #define CIRCLE_FLOAT(NAME_,FUNCTION_) \
1894
+ static VALUE \
1895
+ NAME_(VALUE obj) \
1896
+ { \
1897
+ CIRCLE *l; \
1898
+ \
1899
+ Data_Get_Struct(obj, CIRCLE, l); \
1900
+ RETURN_FLOAT(obj, PLRUBY_DFC1(FUNCTION_, l));\
1901
+ }
1902
+
1903
+ CIRCLE_FLOAT(pl_circle_area,circle_area);
1904
+ CIRCLE_FLOAT(pl_circle_radius,circle_radius);
1905
+ CIRCLE_FLOAT(pl_circle_diameter,circle_diameter);
1906
+
1907
+ static VALUE
1908
+ pl_circle_cmp(VALUE obj, VALUE a)
1909
+ {
1910
+ CIRCLE *l0, *l1;
1911
+
1912
+ if (!rb_obj_is_kind_of(a, rb_obj_class(obj))) {
1913
+ return Qnil;
1914
+ }
1915
+ Data_Get_Struct(obj, CIRCLE, l0);
1916
+ Data_Get_Struct(a, CIRCLE, l1);
1917
+ if (PLRUBY_DFC2(circle_eq, l0, l1)) return INT2NUM(0);
1918
+ if (PLRUBY_DFC2(circle_lt, l0, l1)) return INT2NUM(-1);
1919
+ return INT2NUM(1);
1920
+ }
1921
+
1922
+ static VALUE
1923
+ pl_circle_center(VALUE obj)
1924
+ {
1925
+ CIRCLE *l0;
1926
+ Point *p0, *p1;
1927
+ VALUE res;
1928
+
1929
+ Data_Get_Struct(obj, CIRCLE, l0);
1930
+ p0 = (Point *)PLRUBY_DFC1(circle_center, l0);
1931
+ if (!p0) return Qnil;
1932
+ res = Data_Make_Struct(pl_cPoint, Point, pl_point_mark, free, p1);
1933
+ CPY_FREE(p1, p0, sizeof(Point));
1934
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
1935
+ return res;
1936
+ }
1937
+
1938
+ static VALUE pl_cCircle;
1939
+
1940
+ static VALUE
1941
+ pl_box_to_circle(VALUE obj)
1942
+ {
1943
+ BOX *b;
1944
+ CIRCLE *p0, *p1;
1945
+ VALUE res;
1946
+
1947
+ Data_Get_Struct(obj, BOX, b);
1948
+ p0 = (CIRCLE *)PLRUBY_DFC1(box_circle, b);
1949
+ if (!p0) return Qnil;
1950
+ res = Data_Make_Struct(pl_cCircle, CIRCLE, pl_circle_mark, free, p1);
1951
+ CPY_FREE(p1, p0, sizeof(CIRCLE));
1952
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
1953
+ return res;
1954
+ }
1955
+
1956
+ static VALUE
1957
+ pl_poly_to_circle(VALUE obj)
1958
+ {
1959
+ POLYGON *b;
1960
+ CIRCLE *p0, *p1;
1961
+ VALUE res;
1962
+
1963
+ Data_Get_Struct(obj, POLYGON, b);
1964
+ p0 = (CIRCLE *)PLRUBY_DFC1(poly_circle, b);
1965
+ if (!p0) return Qnil;
1966
+ res = Data_Make_Struct(pl_cCircle, CIRCLE, pl_circle_mark, free, p1);
1967
+ CPY_FREE(p1, p0, sizeof(CIRCLE));
1968
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
1969
+ return res;
1970
+ }
1971
+
1972
+ static VALUE
1973
+ pl_circle_to_poly(VALUE obj, VALUE a)
1974
+ {
1975
+ CIRCLE *b;
1976
+ POLYGON *p0, *p1;
1977
+ VALUE res;
1978
+ int sz0;
1979
+
1980
+ Data_Get_Struct(obj, CIRCLE, b);
1981
+ p0 = (POLYGON *)PLRUBY_DFC2(circle_poly, Int32GetDatum(NUM2INT(a)), b);
1982
+ if (!p0) return Qnil;
1983
+ sz0 = GET_VARSIZE(POLYGON, p0);
1984
+ p1 = (POLYGON *)ALLOC_N(char, sz0);
1985
+ CPY_FREE(p1, p0, sz0);
1986
+ res = Data_Wrap_Struct(pl_cPoly, pl_poly_mark, free, p1);
1987
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
1988
+ return res;
1989
+ }
1990
+
1991
+ static VALUE
1992
+ pl_circle_to_box(VALUE obj)
1993
+ {
1994
+ CIRCLE *b;
1995
+ BOX *p0, *p1;
1996
+ VALUE res;
1997
+
1998
+ Data_Get_Struct(obj, CIRCLE, b);
1999
+ p0 = (BOX *)PLRUBY_DFC1(poly_box, b);
2000
+ if (!p0) return Qnil;
2001
+ res = Data_Make_Struct(pl_cBox, BOX, pl_box_mark, free, p1);
2002
+ CPY_FREE(p1, p0, sizeof(BOX));
2003
+ if (OBJ_TAINTED(obj)) OBJ_TAINT(res);
2004
+ return res;
2005
+ }
2006
+
2007
+ static VALUE
2008
+ pl_point_on(VALUE obj, VALUE a)
2009
+ {
2010
+ Point *p0;
2011
+
2012
+ Data_Get_Struct(obj, Point, p0);
2013
+ if (TYPE(a) != T_DATA) {
2014
+ rb_raise(rb_eArgError, "on : expected a geometry object");
2015
+ }
2016
+ if (RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_point_mark) {
2017
+ return pl_point_eq(obj, a);
2018
+ }
2019
+ if (RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_lseg_mark) {
2020
+ LSEG *l1;
2021
+
2022
+ Data_Get_Struct(a, LSEG, l1);
2023
+ if (PLRUBY_DFC2(on_ps, p0, l1)) return Qtrue;
2024
+ return Qfalse;
2025
+ }
2026
+ if (RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_box_mark) {
2027
+ BOX *l1;
2028
+
2029
+ Data_Get_Struct(a, BOX, l1);
2030
+ if (PLRUBY_DFC2(on_pb, p0, l1)) return Qtrue;
2031
+ return Qfalse;
2032
+ }
2033
+ if (RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_path_mark) {
2034
+ PATH *l1;
2035
+
2036
+ Data_Get_Struct(a, PATH, l1);
2037
+ if (PLRUBY_DFC2(on_ppath, p0, l1)) return Qtrue;
2038
+ return Qfalse;
2039
+ }
2040
+ rb_raise(rb_eArgError, "on : invalid geometry object");
2041
+ return Qnil;
2042
+ }
2043
+
2044
+ static VALUE
2045
+ pl_point_contained(VALUE obj, VALUE a)
2046
+ {
2047
+ Point *p0;
2048
+
2049
+ Data_Get_Struct(obj, Point, p0);
2050
+ if (TYPE(a) != T_DATA) {
2051
+ rb_raise(rb_eArgError, "contained : expected a geometry object");
2052
+ }
2053
+ if (RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_point_mark) {
2054
+ return pl_point_eq(obj, a);
2055
+ }
2056
+ if (RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_poly_mark) {
2057
+ POLYGON *l1;
2058
+
2059
+ Data_Get_Struct(a, POLYGON, l1);
2060
+ if (PLRUBY_DFC2(pt_contained_poly, p0, l1)) return Qtrue;
2061
+ return Qfalse;
2062
+ }
2063
+ if (RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_circle_mark) {
2064
+ CIRCLE *l1;
2065
+
2066
+ Data_Get_Struct(a, CIRCLE, l1);
2067
+ if (PLRUBY_DFC2(pt_contained_circle, p0, l1)) return Qtrue;
2068
+ return Qfalse;
2069
+ }
2070
+ rb_raise(rb_eArgError, "contained : invalid geometry object");
2071
+ return Qnil;
2072
+ }
2073
+
2074
+ static VALUE
2075
+ pl_lseg_on(VALUE obj, VALUE a)
2076
+ {
2077
+ LSEG *l0;
2078
+
2079
+ Data_Get_Struct(obj, LSEG, l0);
2080
+ if (TYPE(a) != T_DATA) {
2081
+ rb_raise(rb_eArgError, "on : expected a geometry object");
2082
+ }
2083
+ if (RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_lseg_mark) {
2084
+ a = pl_lseg_cmp(obj, a);
2085
+ if (NUM2INT(a) == 0) return Qtrue;
2086
+ return Qfalse;
2087
+ }
2088
+ if (RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_box_mark) {
2089
+ BOX *l1;
2090
+
2091
+ Data_Get_Struct(a, BOX, l1);
2092
+ if (PLRUBY_DFC2(on_sb, l0, l1)) return Qtrue;
2093
+ return Qfalse;
2094
+ }
2095
+ rb_raise(rb_eArgError, "on : invalid geometry object");
2096
+ return Qnil;
2097
+ }
2098
+
2099
+ static VALUE
2100
+ pl_geo_distance(VALUE obj, VALUE a, VALUE b)
2101
+ {
2102
+
2103
+ if (TYPE(a) != T_DATA || TYPE(b) != T_DATA) {
2104
+ rb_raise(rb_eArgError, "distance : expected 2 geometry object");
2105
+ }
2106
+ if (RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_point_mark) {
2107
+ Point *p0;
2108
+
2109
+ Data_Get_Struct(a, Point, p0);
2110
+ if (RDATA(b)->dmark == (RUBY_DATA_FUNC)pl_point_mark) {
2111
+ Point *p1;
2112
+
2113
+ Data_Get_Struct(b, Point, p1);
2114
+ RETURN_FLOAT2(a, b, PLRUBY_DFC2(point_distance, p0, p1));
2115
+ }
2116
+ return pl_geo_distance(obj, b, a);
2117
+ }
2118
+ if (RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_lseg_mark) {
2119
+ LSEG *l0;
2120
+
2121
+ Data_Get_Struct(a, LSEG, l0);
2122
+ if (RDATA(b)->dmark == (RUBY_DATA_FUNC)pl_point_mark) {
2123
+ Point *p;
2124
+
2125
+ Data_Get_Struct(b, Point, p);
2126
+ RETURN_FLOAT2(a, b, PLRUBY_DFC2(dist_ps, p, l0));
2127
+ }
2128
+ if (RDATA(b)->dmark == (RUBY_DATA_FUNC)pl_lseg_mark) {
2129
+ LSEG *l1;
2130
+
2131
+ Data_Get_Struct(a, LSEG, l1);
2132
+ RETURN_FLOAT2(a, b, PLRUBY_DFC2(lseg_distance, l0, l1));
2133
+ }
2134
+ return pl_geo_distance(obj, b, a);
2135
+ }
2136
+ if (RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_box_mark) {
2137
+ BOX *l0;
2138
+
2139
+ Data_Get_Struct(a, BOX, l0);
2140
+ if (RDATA(b)->dmark == (RUBY_DATA_FUNC)pl_point_mark) {
2141
+ Point *p;
2142
+
2143
+ Data_Get_Struct(b, Point, p);
2144
+ RETURN_FLOAT2(a, b, PLRUBY_DFC2(dist_pb, p, l0));
2145
+ }
2146
+ if (RDATA(b)->dmark == (RUBY_DATA_FUNC)pl_lseg_mark) {
2147
+ LSEG *l1;
2148
+
2149
+ Data_Get_Struct(a, LSEG, l1);
2150
+ RETURN_FLOAT2(a, b, PLRUBY_DFC2(dist_sb, l1, l0));
2151
+ }
2152
+ if (RDATA(b)->dmark == (RUBY_DATA_FUNC)pl_box_mark) {
2153
+ BOX *l1;
2154
+
2155
+ Data_Get_Struct(b, BOX, l1);
2156
+ RETURN_FLOAT2(a, a, PLRUBY_DFC2(box_distance, l0, l1));
2157
+ }
2158
+ return pl_geo_distance(obj, b, a);
2159
+ }
2160
+ if (RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_path_mark) {
2161
+ PATH *l0;
2162
+
2163
+ Data_Get_Struct(a, PATH, l0);
2164
+ if (RDATA(b)->dmark == (RUBY_DATA_FUNC)pl_point_mark) {
2165
+ Point *p;
2166
+
2167
+ Data_Get_Struct(b, Point, p);
2168
+ RETURN_FLOAT2(a, b, PLRUBY_DFC2(dist_ppath, p, l0));
2169
+ }
2170
+ if (RDATA(b)->dmark == (RUBY_DATA_FUNC)pl_path_mark) {
2171
+ PATH *l1;
2172
+
2173
+ Data_Get_Struct(b, PATH, l1);
2174
+ RETURN_FLOAT2(a, a, PLRUBY_DFC2(path_distance, l0, l1));
2175
+ }
2176
+ }
2177
+ if (RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_poly_mark) {
2178
+ POLYGON *l0;
2179
+
2180
+ Data_Get_Struct(a, POLYGON, l0);
2181
+ if (RDATA(b)->dmark == (RUBY_DATA_FUNC)pl_poly_mark) {
2182
+ POLYGON *l1;
2183
+
2184
+ Data_Get_Struct(b, POLYGON, l1);
2185
+ RETURN_FLOAT2(a, a, PLRUBY_DFC2(poly_distance, l0, l1));
2186
+ }
2187
+ }
2188
+ if (RDATA(a)->dmark == (RUBY_DATA_FUNC)pl_circle_mark) {
2189
+ CIRCLE *l0;
2190
+
2191
+ Data_Get_Struct(a, CIRCLE, l0);
2192
+ if (RDATA(b)->dmark == (RUBY_DATA_FUNC)pl_circle_mark) {
2193
+ CIRCLE *l1;
2194
+
2195
+ Data_Get_Struct(b, CIRCLE, l1);
2196
+ RETURN_FLOAT2(a, a, PLRUBY_DFC2(circle_distance, l0, l1));
2197
+ }
2198
+ }
2199
+ rb_raise(rb_eArgError, "distance : invalid geometry objects (%s, %s)",
2200
+ rb_class2name(rb_obj_class(a)), rb_class2name(rb_obj_class(b)));
2201
+ return Qnil;
2202
+ }
2203
+
2204
+ void Init_plruby_geometry()
2205
+ {
2206
+ VALUE pl_cLseg, pl_mGeo;
2207
+
2208
+ pl_mGeo = rb_define_module("Geometry");
2209
+ rb_define_module_function(pl_mGeo, "distance", pl_geo_distance, 2);
2210
+ pl_cPoint = rb_define_class("Point", rb_cObject);
2211
+ rb_undef_method(CLASS_OF(pl_cPoint), "method_missing");
2212
+ #if HAVE_RB_DEFINE_ALLOC_FUNC
2213
+ rb_define_alloc_func(pl_cPoint, pl_point_s_alloc);
2214
+ #else
2215
+ rb_define_singleton_method(pl_cPoint, "allocate", pl_point_s_alloc, 0);
2216
+ #endif
2217
+ rb_define_singleton_method(pl_cPoint, "new", plruby_s_new, -1);
2218
+ rb_define_singleton_method(pl_cPoint, "from_string", pl_point_s_str, 1);
2219
+ rb_define_singleton_method(pl_cPoint, "from_datum", pl_point_s_datum, 1);
2220
+ rb_define_method(pl_cPoint, "to_datum", pl_point_to_datum, 1);
2221
+ rb_define_method(pl_cPoint, "initialize", pl_point_init, 2);
2222
+ #ifndef HAVE_RB_INITIALIZE_COPY
2223
+ rb_define_method(pl_cPoint, "clone", plruby_clone, 0);
2224
+ #endif
2225
+ rb_define_method(pl_cPoint, "initialize_copy", pl_point_init_copy, 1);
2226
+ #if PG_PL_VERSION >= 74
2227
+ rb_define_method(pl_cPoint, "marshal_load", pl_point_mload, 1);
2228
+ rb_define_method(pl_cPoint, "marshal_dump", pl_point_mdump, -1);
2229
+ #ifndef RUBY_CAN_USE_MARSHAL_LOAD
2230
+ rb_define_singleton_method(pl_cPoint, "_load", plruby_s_load, 1);
2231
+ rb_define_alias(pl_cPoint, "_dump", "marshal_dump");
2232
+ #endif
2233
+ #endif
2234
+ rb_define_method(pl_cPoint, "x", pl_point_x, 0);
2235
+ rb_define_method(pl_cPoint, "x=", pl_point_setx, 1);
2236
+ rb_define_method(pl_cPoint, "y", pl_point_y, 0);
2237
+ rb_define_method(pl_cPoint, "y=", pl_point_sety, 1);
2238
+ rb_define_method(pl_cPoint, "[]", pl_point_aref, 1);
2239
+ rb_define_method(pl_cPoint, "[]=", pl_point_aset, 2);
2240
+ rb_define_method(pl_cPoint, "to_s", pl_point_to_s, 0);
2241
+ rb_define_method(pl_cPoint, "+", pl_point_add, 1);
2242
+ rb_define_method(pl_cPoint, "-", pl_point_sub, 1);
2243
+ rb_define_method(pl_cPoint, "*", pl_point_mul, 1);
2244
+ rb_define_method(pl_cPoint, "/", pl_point_div, 1);
2245
+ rb_define_method(pl_cPoint, "left?", pl_point_left, 1);
2246
+ rb_define_method(pl_cPoint, "right?", pl_point_right, 1);
2247
+ rb_define_method(pl_cPoint, "above?", pl_point_above, 1);
2248
+ rb_define_method(pl_cPoint, "below?", pl_point_below, 1);
2249
+ rb_define_method(pl_cPoint, "vertical?", pl_point_vert, 1);
2250
+ rb_define_method(pl_cPoint, "horizontal?", pl_point_horiz, 1);
2251
+ rb_define_method(pl_cPoint, "==", pl_point_eq, 1);
2252
+ rb_define_method(pl_cPoint, "slope", pl_point_slope, 1);
2253
+ rb_define_method(pl_cPoint, "on?", pl_point_on, 1);
2254
+ rb_define_method(pl_cPoint, "in?", pl_point_contained, 1);
2255
+ rb_define_method(pl_cPoint, "contained?", pl_point_contained, 1);
2256
+ pl_cLseg = rb_define_class("Segment", rb_cObject);
2257
+ rb_include_module(pl_cLseg, rb_mComparable);
2258
+ rb_undef_method(CLASS_OF(pl_cLseg), "method_missing");
2259
+ #if HAVE_RB_DEFINE_ALLOC_FUNC
2260
+ rb_define_alloc_func(pl_cLseg, pl_lseg_s_alloc);
2261
+ #else
2262
+ rb_define_singleton_method(pl_cLseg, "allocate", pl_lseg_s_alloc, 0);
2263
+ #endif
2264
+ rb_define_singleton_method(pl_cLseg, "new", plruby_s_new, -1);
2265
+ rb_define_singleton_method(pl_cLseg, "from_string", pl_lseg_s_str, 1);
2266
+ rb_define_singleton_method(pl_cLseg, "from_datum", pl_lseg_s_datum, 1);
2267
+ rb_define_method(pl_cLseg, "to_datum", pl_lseg_to_datum, 1);
2268
+ rb_define_method(pl_cLseg, "initialize", pl_lseg_init, 2);
2269
+ #ifndef HAVE_RB_INITIALIZE_COPY
2270
+ rb_define_method(pl_cLseg, "clone", plruby_clone, 0);
2271
+ #endif
2272
+ rb_define_method(pl_cLseg, "initialize_copy", pl_lseg_init_copy, 1);
2273
+ #if PG_PL_VERSION >= 74
2274
+ rb_define_method(pl_cLseg, "marshal_load", pl_lseg_mload, 1);
2275
+ rb_define_method(pl_cLseg, "marshal_dump", pl_lseg_mdump, -1);
2276
+ #ifndef RUBY_CAN_USE_MARSHAL_LOAD
2277
+ rb_define_singleton_method(pl_cLseg, "_load", plruby_s_load, 1);
2278
+ rb_define_alias(pl_cLseg, "_dump", "marshal_dump");
2279
+ #endif
2280
+ #endif
2281
+ rb_define_method(pl_cLseg, "[]", pl_lseg_aref, 1);
2282
+ rb_define_method(pl_cLseg, "[]=", pl_lseg_aset, 2);
2283
+ rb_define_method(pl_cLseg, "to_s", pl_lseg_to_s, 0);
2284
+ rb_define_method(pl_cLseg, "length", pl_lseg_length, 0);
2285
+ rb_define_method(pl_cLseg, "parallel?", pl_lseg_parallel, 1);
2286
+ rb_define_method(pl_cLseg, "perpendicular?", pl_lseg_perp, 1);
2287
+ rb_define_method(pl_cLseg, "vertical?", pl_lseg_vertical, 0);
2288
+ rb_define_method(pl_cLseg, "horizontal?", pl_lseg_horizontal, 0);
2289
+ rb_define_method(pl_cLseg, "<=>", pl_lseg_cmp, 1);
2290
+ rb_define_method(pl_cLseg, "center", pl_lseg_center, 0);
2291
+ rb_define_method(pl_cLseg, "closest", pl_lseg_closest, 1);
2292
+ rb_define_method(pl_cLseg, "intersect?", pl_lseg_intersect, 1);
2293
+ rb_define_method(pl_cLseg, "intersection", pl_lseg_intersection, 1);
2294
+ rb_define_method(pl_cLseg, "on?", pl_lseg_on, 1);
2295
+ rb_define_method(pl_cLseg, "to_point", pl_lseg_center, 0);
2296
+ pl_cBox = rb_define_class("Box", rb_cObject);
2297
+ rb_include_module(pl_cBox, rb_mComparable);
2298
+ rb_undef_method(CLASS_OF(pl_cBox), "method_missing");
2299
+ #if HAVE_RB_DEFINE_ALLOC_FUNC
2300
+ rb_define_alloc_func(pl_cBox, pl_box_s_alloc);
2301
+ #else
2302
+ rb_define_singleton_method(pl_cBox, "allocate", pl_box_s_alloc, 0);
2303
+ #endif
2304
+ rb_define_singleton_method(pl_cBox, "new", plruby_s_new, -1);
2305
+ rb_define_singleton_method(pl_cBox, "from_string", pl_box_s_str, 1);
2306
+ rb_define_singleton_method(pl_cBox, "from_datum", pl_box_s_datum, 1);
2307
+ rb_define_method(pl_cBox, "to_datum", pl_box_to_datum, 1);
2308
+ rb_define_method(pl_cBox, "initialize", pl_box_init, -1);
2309
+ #ifndef HAVE_RB_INITIALIZE_COPY
2310
+ rb_define_method(pl_cBox, "clone", plruby_clone, 0);
2311
+ #endif
2312
+ rb_define_method(pl_cBox, "initialize_copy", pl_box_init_copy, 1);
2313
+ #if PG_PL_VERSION >= 74
2314
+ rb_define_method(pl_cBox, "marshal_load", pl_box_mload, 1);
2315
+ rb_define_method(pl_cBox, "marshal_dump", pl_box_mdump, -1);
2316
+ #ifndef RUBY_CAN_USE_MARSHAL_LOAD
2317
+ rb_define_singleton_method(pl_cBox, "_load", plruby_s_load, 1);
2318
+ rb_define_alias(pl_cBox, "_dump", "marshal_dump");
2319
+ #endif
2320
+ #endif
2321
+ rb_define_method(pl_cBox, "low", pl_box_low, 0);
2322
+ rb_define_method(pl_cBox, "high", pl_box_high, 0);
2323
+ rb_define_method(pl_cBox, "low=", pl_box_lowset, 1);
2324
+ rb_define_method(pl_cBox, "high=", pl_box_highset, 1);
2325
+ rb_define_method(pl_cBox, "[]", pl_box_aref, 1);
2326
+ rb_define_method(pl_cBox, "[]=", pl_box_aset, 2);
2327
+ rb_define_method(pl_cBox, "to_s", pl_box_to_s, 0);
2328
+ rb_define_method(pl_cBox, "<=>", pl_box_cmp, 1);
2329
+ rb_define_method(pl_cBox, "+", pl_box_add, 1);
2330
+ rb_define_method(pl_cBox, "-", pl_box_sub, 1);
2331
+ rb_define_method(pl_cBox, "*", pl_box_mul, 1);
2332
+ rb_define_method(pl_cBox, "/", pl_box_div, 1);
2333
+ rb_define_method(pl_cBox, "same?", pl_box_same, 1);
2334
+ rb_define_method(pl_cBox, "===", pl_box_same, 1);
2335
+ rb_define_method(pl_cBox, "overlap?", pl_box_overlap, 1);
2336
+ rb_define_method(pl_cBox, "overleft?", pl_box_overleft, 1);
2337
+ rb_define_method(pl_cBox, "left?", pl_box_left, 1);
2338
+ rb_define_method(pl_cBox, "right?", pl_box_right, 1);
2339
+ rb_define_method(pl_cBox, "overright?", pl_box_overright, 1);
2340
+ rb_define_method(pl_cBox, "contained?", pl_box_contained, 1);
2341
+ rb_define_method(pl_cBox, "in?", pl_box_contained, 1);
2342
+ rb_define_method(pl_cBox, "contain?", pl_box_contain, 1);
2343
+ rb_define_method(pl_cBox, "below?", pl_box_below, 1);
2344
+ rb_define_method(pl_cBox, "above?", pl_box_above, 1);
2345
+ rb_define_method(pl_cBox, "area", pl_box_area, 0);
2346
+ rb_define_method(pl_cBox, "width", pl_box_width, 0);
2347
+ rb_define_method(pl_cBox, "height", pl_box_height, 0);
2348
+ rb_define_method(pl_cBox, "center", pl_box_center, 0);
2349
+ rb_define_method(pl_cBox, "closest", pl_box_closest, 1);
2350
+ rb_define_method(pl_cBox, "intersect?", pl_box_intersect, 1);
2351
+ rb_define_method(pl_cBox, "intersection", pl_box_intersection, 1);
2352
+ rb_define_method(pl_cBox, "diagonal", pl_box_diagonal, 0);
2353
+ rb_define_method(pl_cBox, "to_point", pl_box_center, 0);
2354
+ rb_define_method(pl_cBox, "to_segment", pl_box_diagonal, 0);
2355
+ rb_define_method(pl_cBox, "to_lseg", pl_box_diagonal, 0);
2356
+ rb_define_method(pl_cBox, "to_poly", pl_box_to_poly, 0);
2357
+ rb_define_method(pl_cBox, "to_polygon", pl_box_to_poly, 0);
2358
+ rb_define_method(pl_cBox, "to_circle", pl_box_to_circle, 0);
2359
+ pl_cPath = rb_define_class("Path", rb_cObject);
2360
+ rb_include_module(pl_cPath, rb_mComparable);
2361
+ rb_undef_method(CLASS_OF(pl_cPath), "method_missing");
2362
+ #if HAVE_RB_DEFINE_ALLOC_FUNC
2363
+ rb_define_alloc_func(pl_cPath, pl_path_s_alloc);
2364
+ #else
2365
+ rb_define_singleton_method(pl_cPath, "allocate", pl_path_s_alloc, 0);
2366
+ #endif
2367
+ rb_define_singleton_method(pl_cPath, "new", plruby_s_new, -1);
2368
+ rb_define_singleton_method(pl_cPath, "from_string", pl_path_s_str, 1);
2369
+ rb_define_singleton_method(pl_cPath, "from_datum", pl_path_s_datum, 1);
2370
+ rb_define_method(pl_cPath, "to_datum", pl_path_to_datum, 1);
2371
+ rb_define_method(pl_cPath, "initialize", pl_path_init, -1);
2372
+ #ifndef HAVE_RB_INITIALIZE_COPY
2373
+ rb_define_method(pl_cPath, "clone", plruby_clone, 0);
2374
+ #endif
2375
+ rb_define_method(pl_cPath, "initialize_copy", pl_path_init_copy, 1);
2376
+ #if PG_PL_VERSION >= 74
2377
+ rb_define_method(pl_cPath, "marshal_load", pl_path_mload, 1);
2378
+ rb_define_method(pl_cPath, "marshal_dump", pl_path_mdump, -1);
2379
+ #ifndef RUBY_CAN_USE_MARSHAL_LOAD
2380
+ rb_define_singleton_method(pl_cPath, "_load", plruby_s_load, 1);
2381
+ rb_define_alias(pl_cPath, "_dump", "marshal_dump");
2382
+ #endif
2383
+ #endif
2384
+ rb_define_method(pl_cPath, "to_s", pl_path_to_s, 0);
2385
+ rb_define_method(pl_cPath, "<=>", pl_path_cmp, 1);
2386
+ rb_define_method(pl_cPath, "npoints", pl_path_npoints, 0);
2387
+ rb_define_method(pl_cPath, "close", pl_path_close, 0);
2388
+ rb_define_method(pl_cPath, "open", pl_path_open, 0);
2389
+ rb_define_method(pl_cPath, "closed?", pl_path_closed, 0);
2390
+ rb_define_method(pl_cPath, "length", pl_path_length, 0);
2391
+ rb_define_method(pl_cPath, "<<", pl_path_concat, 1);
2392
+ rb_define_method(pl_cPath, "concat", pl_path_concat, 1);
2393
+ rb_define_method(pl_cPath, "+", pl_path_add, 1);
2394
+ rb_define_method(pl_cPath, "-", pl_path_sub, 1);
2395
+ rb_define_method(pl_cPath, "*", pl_path_mul, 1);
2396
+ rb_define_method(pl_cPath, "/", pl_path_div, 1);
2397
+ rb_define_method(pl_cPath, "to_poly", pl_path_to_poly, 0);
2398
+ rb_define_method(pl_cPath, "to_polygon", pl_path_to_poly, 0);
2399
+ #if PG_PL_VERSION >= 75
2400
+ rb_define_method(pl_cPath, "area", pl_path_area, 0);
2401
+ #endif
2402
+ pl_cPoly = rb_define_class("Polygon", rb_cObject);
2403
+ rb_undef_method(CLASS_OF(pl_cPoly), "method_missing");
2404
+ #if HAVE_RB_DEFINE_ALLOC_FUNC
2405
+ rb_define_alloc_func(pl_cPoly, pl_poly_s_alloc);
2406
+ #else
2407
+ rb_define_singleton_method(pl_cPoly, "allocate", pl_poly_s_alloc, 0);
2408
+ #endif
2409
+ rb_define_singleton_method(pl_cPoly, "new", plruby_s_new, -1);
2410
+ rb_define_singleton_method(pl_cPoly, "from_string", pl_poly_s_str, 1);
2411
+ rb_define_singleton_method(pl_cPoly, "from_datum", pl_poly_s_datum, 1);
2412
+ rb_define_method(pl_cPoly, "to_datum", pl_poly_to_datum, 1);
2413
+ rb_define_method(pl_cPoly, "initialize", pl_poly_init, -1);
2414
+ #ifndef HAVE_RB_INITIALIZE_COPY
2415
+ rb_define_method(pl_cPoly, "clone", plruby_clone, 0);
2416
+ #endif
2417
+ rb_define_method(pl_cPoly, "initialize_copy", pl_poly_init_copy, 1);
2418
+ #if PG_PL_VERSION >= 74
2419
+ rb_define_method(pl_cPoly, "marshal_load", pl_poly_mload, 1);
2420
+ rb_define_method(pl_cPoly, "marshal_dump", pl_poly_mdump, -1);
2421
+ #ifndef RUBY_CAN_USE_MARSHAL_LOAD
2422
+ rb_define_singleton_method(pl_cPoly, "_load", plruby_s_load, 1);
2423
+ rb_define_alias(pl_cPoly, "_dump", "marshal_dump");
2424
+ #endif
2425
+ #endif
2426
+ rb_define_method(pl_cPoly, "to_s", pl_poly_to_s, 0);
2427
+ rb_define_method(pl_cPoly, "left?", pl_poly_left, 1);
2428
+ rb_define_method(pl_cPoly, "overleft?", pl_poly_overleft, 1);
2429
+ rb_define_method(pl_cPoly, "right?", pl_poly_right, 1);
2430
+ rb_define_method(pl_cPoly, "overright?", pl_poly_overright, 1);
2431
+ rb_define_method(pl_cPoly, "same?", pl_poly_same, 1);
2432
+ rb_define_method(pl_cPoly, "==", pl_poly_same, 1);
2433
+ rb_define_method(pl_cPoly, "contain?", pl_poly_contain, 1);
2434
+ rb_define_method(pl_cPoly, "contained?", pl_poly_contained, 1);
2435
+ rb_define_method(pl_cPoly, "in?", pl_poly_contained, 1);
2436
+ rb_define_method(pl_cPoly, "overlap?", pl_poly_overlap, 1);
2437
+ rb_define_method(pl_cPoly, "npoints", pl_poly_npoints, 0);
2438
+ rb_define_method(pl_cPoly, "center", pl_poly_center, 0);
2439
+ rb_define_method(pl_cPoly, "to_point", pl_poly_center, 0);
2440
+ rb_define_method(pl_cPoly, "to_path", pl_poly_to_path, 0);
2441
+ rb_define_method(pl_cPoly, "to_box", pl_poly_to_box, 0);
2442
+ rb_define_method(pl_cPoly, "to_circle", pl_poly_to_circle, 0);
2443
+ pl_cCircle = rb_define_class("Circle", rb_cObject);
2444
+ rb_include_module(pl_cCircle, rb_mComparable);
2445
+ rb_undef_method(CLASS_OF(pl_cCircle), "method_missing");
2446
+ #if HAVE_RB_DEFINE_ALLOC_FUNC
2447
+ rb_define_alloc_func(pl_cCircle, pl_circle_s_alloc);
2448
+ #else
2449
+ rb_define_singleton_method(pl_cCircle, "allocate", pl_circle_s_alloc, 0);
2450
+ #endif
2451
+ rb_define_singleton_method(pl_cCircle, "new", plruby_s_new, -1);
2452
+ rb_define_singleton_method(pl_cCircle, "from_string", pl_circle_s_str, 1);
2453
+ rb_define_singleton_method(pl_cCircle, "from_datum", pl_circle_s_datum, 1);
2454
+ rb_define_method(pl_cCircle, "to_datum", pl_circle_to_datum, 1);
2455
+ rb_define_method(pl_cCircle, "initialize", pl_circle_init, 2);
2456
+ #ifndef HAVE_RB_INITIALIZE_COPY
2457
+ rb_define_method(pl_cCircle, "clone", plruby_clone, 0);
2458
+ #endif
2459
+ rb_define_method(pl_cCircle, "initialize_copy", pl_circle_init_copy, 1);
2460
+ #if PG_PL_VERSION >= 74
2461
+ rb_define_method(pl_cCircle, "marshal_load", pl_circle_mload, 1);
2462
+ rb_define_method(pl_cCircle, "marshal_dump", pl_circle_mdump, -1);
2463
+ #ifndef RUBY_CAN_USE_MARSHAL_LOAD
2464
+ rb_define_singleton_method(pl_cCircle, "_load", plruby_s_load, 1);
2465
+ rb_define_alias(pl_cCircle, "_dump", "marshal_dump");
2466
+ #endif
2467
+ #endif
2468
+ rb_define_method(pl_cCircle, "to_s", pl_circle_to_s, 0);
2469
+ rb_define_method(pl_cCircle, "left?", pl_circle_left, 1);
2470
+ rb_define_method(pl_cCircle, "overleft?", pl_circle_overleft, 1);
2471
+ rb_define_method(pl_cCircle, "right?", pl_circle_right, 1);
2472
+ rb_define_method(pl_cCircle, "overright?", pl_circle_overright, 1);
2473
+ rb_define_method(pl_cCircle, "same?", pl_circle_same, 1);
2474
+ rb_define_method(pl_cCircle, "===", pl_circle_same, 1);
2475
+ rb_define_method(pl_cCircle, "contain?", pl_circle_contain, 1);
2476
+ rb_define_method(pl_cCircle, "contained?", pl_circle_contained, 1);
2477
+ rb_define_method(pl_cCircle, "in?", pl_circle_contained, 1);
2478
+ rb_define_method(pl_cCircle, "overlap?", pl_circle_overlap, 1);
2479
+ rb_define_method(pl_cCircle, "below?", pl_circle_below, 1);
2480
+ rb_define_method(pl_cCircle, "above?", pl_circle_above, 1);
2481
+ rb_define_method(pl_cCircle, "<=>", pl_circle_cmp, 1);
2482
+ rb_define_method(pl_cCircle, "+", pl_circle_add, 1);
2483
+ rb_define_method(pl_cCircle, "-", pl_circle_sub, 1);
2484
+ rb_define_method(pl_cCircle, "*", pl_circle_mul, 1);
2485
+ rb_define_method(pl_cCircle, "/", pl_circle_div, 1);
2486
+ rb_define_method(pl_cCircle, "area", pl_circle_area, 0);
2487
+ rb_define_method(pl_cCircle, "radius", pl_circle_radius, 0);
2488
+ rb_define_method(pl_cCircle, "diameter", pl_circle_diameter, 0);
2489
+ rb_define_method(pl_cCircle, "center", pl_circle_center, 0);
2490
+ rb_define_method(pl_cCircle, "to_point", pl_circle_center, 0);
2491
+ rb_define_method(pl_cCircle, "to_poly", pl_circle_to_poly, 1);
2492
+ rb_define_method(pl_cCircle, "to_polygon", pl_circle_to_poly, 1);
2493
+ rb_define_method(pl_cCircle, "to_box", pl_circle_to_box, 0);
2494
+ }