ruby-gr 0.73.19.1 → 0.73.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 875e34444c38c15bd8d817784ded0a930e3126a3cc57ae90f8ae34e720ea7e06
4
- data.tar.gz: d3e8357786782a3da6b2256f40865a82a3408506d605d27692b8f52e5f8d787f
3
+ metadata.gz: d7b564823c22dddeb8ea0ae722a04d5339475dd85d048bb95d32116e3ffb95d4
4
+ data.tar.gz: cabe5b7131262dc2871ad4a2a4f836eba22f0a005bc77d7e97362177bd70fae6
5
5
  SHA512:
6
- metadata.gz: 6d49ab20cb176d37d092600164fb29fbb6c762d445c8b18803aca52d557f23873ba6af60126a62ece955a22c4274d7430aeb2e0ba7a31d07af8e211d7077dfda
7
- data.tar.gz: f8594bf5ea403ef7cd663ce44919e760f5d79d5d1122e2b29ac45195f9108226407c1953da225667b0f26ed788009fc6e26c983e38902b49cc196dd79860b464
6
+ metadata.gz: 3f8643a6b2f367d444c2a1d03426d514309a1a5beff5ee07541e33f6769455776d3f11fdeed3936318bf44b9f9fd772b25a569a1f11ff24ec7b6d0802c41f7fc
7
+ data.tar.gz: d3c5f8a042f3d232741dda9e52db9fc2f4abc81d45100dff3beee5007f8ea98e75616834fbd79f4b703d02f18515746d1b72ad64713a78ed06bf76e5501fcc21
data/README.md CHANGED
@@ -25,12 +25,20 @@
25
25
 
26
26
  ## Installation
27
27
 
28
- First, [install GR](#gr-installation). Then install [`gr-plot`](https://github.com/red-data-tools/gr-plot) gem.
28
+ First, [install GR](#gr-installation). If your goal is to draw plots from Ruby,
29
+ install [`gr-plot`](https://github.com/red-data-tools/gr-plot).
29
30
 
30
31
  ```sh
31
32
  gem install gr-plot
32
33
  ```
33
34
 
35
+ For low-level access to the GR, GR3, and GRM native libraries, install the
36
+ `ruby-gr` gem directly.
37
+
38
+ ```sh
39
+ gem install ruby-gr
40
+ ```
41
+
34
42
  [pkg-config](https://github.com/ruby-gnome/pkg-config) will detect the location of the shared library. Otherwise, you need to specify the environment variable.
35
43
 
36
44
  ```sh
data/lib/gr/ffi.rb CHANGED
@@ -56,12 +56,14 @@ module GR
56
56
  CpuBasedVolume2Pass = struct [
57
57
  'double dmin',
58
58
  'double dmax',
59
+ 'int action',
59
60
  'cpubasedvolume_2pass_priv_t *priv'
60
61
  ]
61
62
 
62
63
  Hexbin2Pass = struct [
63
64
  'int nc',
64
- 'int nntmax',
65
+ 'int cntmax',
66
+ 'int action',
65
67
  'hexbin_2pass_priv_t *priv'
66
68
  ]
67
69
 
@@ -77,8 +79,9 @@ module GR
77
79
  ]
78
80
 
79
81
  Axis = struct [
80
- 'double min',
81
- 'double max',
82
+ 'char *spec',
83
+ 'double min_val', # min conflict with Enumerable min
84
+ 'double max_val', # max conflict with Enumerable max
82
85
  'double tick',
83
86
  'double org',
84
87
  'double position',
@@ -94,8 +97,8 @@ module GR
94
97
  ]
95
98
 
96
99
  FormatReference = struct [
97
- 'char *format',
98
- 'int length'
100
+ 'int scientific',
101
+ 'int decimal_digits'
99
102
  ]
100
103
 
101
104
  try_extern 'void gr_initgr(void)'
@@ -103,7 +106,7 @@ module GR
103
106
  try_extern 'void gr_opengks(void)'
104
107
  try_extern 'void gr_closegks(void)'
105
108
  try_extern 'void gr_inqdspsize(double *, double *, int *, int *)'
106
- try_extern 'void gr_openws(int, char *, int)'
109
+ try_extern 'void gr_openws(int, const char *, int)'
107
110
  try_extern 'void gr_closews(int)'
108
111
  try_extern 'void gr_activatews(int)'
109
112
  try_extern 'void gr_deactivatews(int)'
@@ -112,10 +115,10 @@ module GR
112
115
  try_extern 'void gr_updatews(void)'
113
116
  try_extern 'void gr_polyline(int, double *, double *)'
114
117
  try_extern 'void gr_polymarker(int, double *, double *)'
115
- try_extern 'void gr_text(double, double, char *)'
116
- try_extern 'void gr_textx(double, double, char *, int)'
117
- try_extern 'void gr_inqtext(double, double, char *, double *, double *)'
118
- try_extern 'void gr_inqtextx(double, double, char *, int, double *, double *)'
118
+ try_extern 'void gr_text(double, double, const char *)'
119
+ try_extern 'void gr_textx(double, double, const char *, int)'
120
+ try_extern 'void gr_inqtext(double, double, const char *, double *, double *)'
121
+ try_extern 'void gr_inqtextx(double, double, const char *, int, double *, double *)'
119
122
  try_extern 'void gr_fillarea(int, double *, double *)'
120
123
  try_extern 'void gr_cellarray(double, double, double, double,' \
121
124
  ' int, int, int, int, int, int, int *)'
@@ -181,15 +184,15 @@ module GR
181
184
  try_extern 'void gr_inqspace(double *, double *, int *, int *)'
182
185
  try_extern 'int gr_setscale(int)'
183
186
  try_extern 'void gr_inqscale(int *)'
184
- try_extern 'int gr_textext(double, double, char *)'
185
- try_extern 'void gr_inqtextext(double, double, char *, double *, double *)'
187
+ try_extern 'int gr_textext(double, double, const char *)'
188
+ try_extern 'void gr_inqtextext(double, double, const char *, double *, double *)'
186
189
  try_extern 'void gr_setscientificformat(int)'
187
190
  try_extern 'void gr_axes(double, double, double, double, int, int, double)'
188
191
  try_extern 'void gr_axeslbl(double, double, double, double, int, int, double,' \
189
192
  ' void (*)(double, double, const char *, double),' \
190
193
  ' void (*)(double, double, const char *, double))'
191
- try_extern 'void gr_axis(char, axis_t *)'
192
- try_extern 'void gr_drawaxis(char, axis_t *)'
194
+ try_extern 'void gr_axis(const char *, axis_t *)'
195
+ try_extern 'void gr_drawaxis(axis_t *)'
193
196
  try_extern 'void gr_drawaxes(axis_t *, axis_t *, int)'
194
197
  try_extern 'void gr_freeaxis(axis_t *)'
195
198
  try_extern 'void gr_grid(double, double, double, double, int, int)'
@@ -199,8 +202,8 @@ module GR
199
202
  try_extern 'void gr_polyline3d(int, double *, double *, double *)'
200
203
  try_extern 'void gr_polymarker3d(int, double *, double *, double *)'
201
204
  try_extern 'void gr_axes3d(double, double, double, double, double, double, int, int, int, double)'
202
- try_extern 'void gr_titles3d(char *, char *, char *)'
203
- try_extern 'void gr_settitles3d(char *, char *, char *)'
205
+ try_extern 'void gr_titles3d(const char *, const char *, const char *)'
206
+ try_extern 'void gr_settitles3d(const char *, const char *, const char *)'
204
207
  try_extern 'void gr_surface(int, int, double *, double *, double *, int)'
205
208
  try_extern 'void gr_contour(int, int, int, double *, double *, double *, double *, int)'
206
209
  try_extern 'void gr_contourf(int, int, int, double *, double *, double *, double *, int)'
@@ -219,8 +222,8 @@ module GR
219
222
  try_extern 'int gr_validaterange(double, double)'
220
223
  try_extern 'void gr_adjustlimits(double *, double *)'
221
224
  try_extern 'void gr_adjustrange(double *, double *)'
222
- try_extern 'void gr_beginprint(char *)'
223
- try_extern 'void gr_beginprintext(char *, char *, char *, char *)'
225
+ try_extern 'void gr_beginprint(const char *)'
226
+ try_extern 'void gr_beginprintext(const char *, const char *, const char *, const char *)'
224
227
  try_extern 'void gr_endprint(void)'
225
228
  try_extern 'void gr_ndctowc(double *, double *)'
226
229
  try_extern 'void gr_wctondc(double *, double *)'
@@ -233,32 +236,36 @@ module GR
233
236
  try_extern 'void gr_setarrowstyle(int)'
234
237
  try_extern 'void gr_setarrowsize(double)'
235
238
  try_extern 'void gr_drawarrow(double, double, double, double)'
236
- try_extern 'int gr_readimage(char *, int *, int *, int **)'
239
+ try_extern 'int gr_readimage(const char *, int *, int *, int **)'
237
240
  try_extern 'void gr_drawimage(double, double, double, double, int, int, int *, int)'
238
- try_extern 'int gr_importgraphics(char *)'
241
+ try_extern 'int gr_importgraphics(const char *)'
239
242
  try_extern 'void gr_setshadow(double, double, double)'
240
243
  try_extern 'void gr_settransparency(double)'
241
244
  try_extern 'void gr_inqtransparency(double *)'
242
245
  try_extern 'void gr_setcoordxform(double[3][2])'
243
- try_extern 'void gr_begingraphics(char *)'
246
+ try_extern 'void gr_begingraphics(const char *)'
244
247
  try_extern 'void gr_endgraphics(void)'
245
248
  try_extern 'char *gr_getgraphics(void)'
246
- try_extern 'int gr_drawgraphics(char *)'
249
+ try_extern 'int gr_drawgraphics(const char *)'
247
250
  try_extern 'int gr_startlistener(void)'
248
251
  try_extern 'int gr_inqgrplotport(void)'
249
252
  try_extern 'int gr_setgrplotport(int)'
250
- try_extern 'void gr_mathtex(double, double, char *)'
251
- try_extern 'void gr_inqmathtex(double, double, char *, double *, double *)'
252
- try_extern 'void gr_mathtex3d(double, double, double, char *, int)'
253
- try_extern 'void gr_inqmathtex3d(double, double, double, char *, int, double *, double *, double *, double *)'
253
+ try_extern 'void gr_mathtex(double, double, const char *)'
254
+ try_extern 'void gr_inqmathtex(double, double, const char *, double *, double *)'
255
+ try_extern 'void gr_mathtex3d(double, double, double, const char *, int)'
256
+ try_extern 'void gr_inqmathtex3d(double, double, double, const char *, int, double *, double *, double *, double *)'
254
257
  try_extern 'void gr_beginselection(int, int)'
255
258
  try_extern 'void gr_endselection(void)'
256
- try_extern 'void gr_setbboxcallback(int, void (*)(int, double, double, double, double))'
259
+ try_extern 'void gr_setbboxcallback(int, void (*)(int, double, double, double, double),' \
260
+ ' void (*)(unsigned int, unsigned int, unsigned int *))'
257
261
  try_extern 'void gr_cancelbboxcallback(void)'
262
+ try_extern 'void gr_beginpartial(int, void (*)(int, unsigned int, unsigned int,' \
263
+ ' unsigned int, unsigned int, unsigned int *))'
264
+ try_extern 'void gr_endpartial(int)'
258
265
  try_extern 'void gr_moveselection(double, double)'
259
266
  try_extern 'void gr_resizeselection(int, double, double)'
260
267
  try_extern 'void gr_inqbbox(double *, double *, double *, double *)'
261
- try_extern 'void gr_setbackground(void)'
268
+ try_extern 'void gr_setbackground(double, double, double, double)'
262
269
  try_extern 'void gr_clearbackground(void)'
263
270
  try_extern 'double gr_precision(void)'
264
271
  try_extern 'int gr_text_maxsize(void)'
@@ -270,7 +277,7 @@ module GR
270
277
  try_extern 'void gr_selectcontext(int)'
271
278
  try_extern 'void gr_destroycontext(int)'
272
279
  try_extern 'void gr_unselectcontext(void)'
273
- try_extern 'int gr_uselinespec(char *)'
280
+ try_extern 'int gr_uselinespec(const char *)'
274
281
  try_extern 'void gr_delaunay(int, const double *, const double *, int *, int **)'
275
282
  try_extern 'void gr_reducepoints(int, const double *, const double *, int, double *, double *)'
276
283
  try_extern 'void gr_trisurface(int, double *, double *, double *)'
@@ -313,11 +320,11 @@ module GR
313
320
  try_extern 'void gr_inqscalefactors3d(double *, double *, double *)'
314
321
  try_extern 'void gr_setspace3d(double, double, double, double)'
315
322
  try_extern 'void gr_inqspace3d(int *, double *, double *, double *, double *)'
316
- try_extern 'void gr_text3d(double, double, double, char *, int axis)'
317
- try_extern 'void gr_inqtext3d(double, double, double, char *, int axis, double *, double *)'
323
+ try_extern 'void gr_text3d(double, double, double, const char *, int axis)'
324
+ try_extern 'void gr_inqtext3d(double, double, double, const char *, int axis, double *, double *)'
318
325
  try_extern 'void gr_settextencoding(int)'
319
326
  try_extern 'void gr_inqtextencoding(int *)'
320
- try_extern 'void gr_loadfont(char *, int *)'
327
+ try_extern 'void gr_loadfont(const char *, int *)'
321
328
  try_extern 'void gr_setcallback(char *(*)(const char *))'
322
329
  try_extern 'void gr_setthreadnumber(int)'
323
330
  try_extern 'void gr_setpicturesizeforvolume(int, int)'
@@ -347,5 +354,11 @@ module GR
347
354
  try_extern 'void gr_settextoffset(double xoff, double yoff)'
348
355
  try_extern 'char *gr_ftoa(char *string, double value, format_reference_t *reference)'
349
356
  try_extern 'void gr_getformat(format_reference_t *result, double origin, double min, double max, double tick_width, int major)'
357
+ try_extern 'void gr_setcolorlimits(double, double)'
358
+ try_extern 'void gr_inqcolorlimits(double *, double *)'
359
+ try_extern 'void gr_setmetadata(const char *)'
360
+ try_extern 'char *gr_getmetadata(const char *)'
361
+ typealias 'FILE', 'void'
362
+ try_extern 'char *gr_getmetadatafromstream(FILE *fp)'
350
363
  end
351
364
  end
data/lib/gr.rb CHANGED
@@ -40,7 +40,7 @@
40
40
  #
41
41
  # Fiddley is Ruby-FFI compatible API layer for Fiddle.
42
42
  #
43
- # The GR module works without Numo::Narrray.
43
+ # The GR module works without Numo::NArray.
44
44
  # GR3 and GR::Plot depends on numo-narray.
45
45
  #
46
46
  # This is a procedural interface to the GR plotting library,
@@ -60,25 +60,9 @@ module GR
60
60
  # Windows | bin/libgr.dll
61
61
  # MacOSX | lib/libGR.dylib ( <= v0.53.0 .so)
62
62
  # Ubuntu | lib/libGR.so
63
- platform = RbConfig::CONFIG['host_os']
64
- lib_names, pkg_name = \
65
- case platform
66
- when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
67
- [['libGR.dll'], 'gr']
68
- when /darwin|mac os/
69
- ENV['GKSwstype'] ||= 'gksqt'
70
- [['libGR.dylib', 'libGR.so'], 'gr']
71
- else
72
- [['libGR.so'], 'gr']
73
- end
74
-
75
63
  # On Windows + RubyInstaller,
76
64
  # the environment variable GKS_FONTPATH will be set.
77
- lib_path = GRCommons::GRLib.search(lib_names, pkg_name)
78
-
79
- raise NotFoundError, "#{lib_names} not found" if lib_path.nil?
80
-
81
- self.ffi_lib = lib_path
65
+ GRCommons::GRLib.load_library(self, pkg_name: 'gr', not_found_error: NotFoundError)
82
66
 
83
67
  require_relative 'gr/version'
84
68
  require_relative 'gr/ffi'
@@ -95,6 +79,55 @@ module GR
95
79
  # a Fiddley::MemoryPointer in the GRBase class.
96
80
  extend GRBase
97
81
 
82
+ # High-level axis/tick objects
83
+ class GRTick
84
+ attr_accessor :value, :is_major
85
+
86
+ def initialize(value:, is_major:)
87
+ @value = value
88
+ @is_major = is_major
89
+ end
90
+ end
91
+
92
+ class GRTickLabel
93
+ attr_accessor :tick, :label, :width
94
+
95
+ def initialize(tick:, label:, width:)
96
+ @tick = tick
97
+ @label = label
98
+ @width = width
99
+ end
100
+ end
101
+
102
+ class GRAxis
103
+ attr_accessor :spec, :min, :max, :tick, :org, :position,
104
+ :major_count, :num_ticks, :ticks,
105
+ :tick_size, :tick_labels, :label_position,
106
+ :draw_axis_line, :label_orientation
107
+
108
+ def initialize(spec: nil, min: Float::NAN, max: Float::NAN, tick: Float::NAN,
109
+ org: Float::NAN, position: Float::NAN,
110
+ major_count: 1, num_ticks: 0, ticks: nil,
111
+ tick_size: Float::NAN, tick_labels: nil,
112
+ label_position: Float::NAN,
113
+ draw_axis_line: 1, label_orientation: 0)
114
+ @spec = spec
115
+ @min = min
116
+ @max = max
117
+ @tick = tick
118
+ @org = org
119
+ @position = position
120
+ @major_count = major_count
121
+ @num_ticks = num_ticks
122
+ @ticks = ticks
123
+ @tick_size = tick_size
124
+ @tick_labels = tick_labels
125
+ @label_position = label_position
126
+ @draw_axis_line = draw_axis_line
127
+ @label_orientation = label_orientation
128
+ end
129
+ end
130
+
98
131
  class << self
99
132
  # @!method initgr
100
133
 
@@ -815,6 +848,10 @@ module GR
815
848
  inquiry_int { |pt| super(pt) }
816
849
  end
817
850
 
851
+ def inqnominalsize
852
+ inquiry_double { |pt| super(pt) }
853
+ end
854
+
818
855
  # Redefine an existing color index representation by specifying an RGB color
819
856
  # triplet.
820
857
  #
@@ -956,6 +993,12 @@ module GR
956
993
 
957
994
  # @!method closeseg
958
995
 
996
+ def samplelocator
997
+ inquiry %i[double double int] do |*pts|
998
+ super(*pts)
999
+ end
1000
+ end
1001
+
959
1002
  # @!method emergencyclosegks
960
1003
 
961
1004
  # @!method updategks
@@ -1116,50 +1159,36 @@ module GR
1116
1159
 
1117
1160
  alias axes2d axes
1118
1161
 
1119
- def axis(option, min: Float::NAN, max: Float::NAN, tick: Float::NAN, org: Float::NAN, position: Float::NAN, major_count: 1,
1120
- tick_size: Float::NAN, label_position: Float::NAN, draw_axis_line: 1, label_orientation: 0)
1121
- ax = FFI::Axis.malloc
1122
- ax[:min] = min
1123
- ax[:max] = max
1124
- ax[:tick] = tick
1125
- ax[:org] = org
1126
- ax[:position] = position
1127
- ax[:major_count] = major_count
1128
- ax[:tick_size] = tick_size
1129
- ax[:label_position] = label_position
1130
- ax[:draw_axis_line] = draw_axis_line
1131
- ax[:label_orientation] = label_orientation
1132
- ax[:ticks] = 0
1133
- ax[:num_ticks] = 0
1134
- ax[:tick_labels] = 0
1135
- ax[:num_tick_labels] = 0
1136
- super(option, ax)
1137
- ax
1138
- end
1139
-
1140
- def drawaxis(option, min: Float::NAN, max: Float::NAN, tick: Float::NAN, org: Float::NAN, position: Float::NAN,
1141
- major_count: 1, tick_size: Float::NAN, label_position: Float::NAN, draw_axis_line: 1, label_orientation: 0)
1142
- ax = FFI::Axis.malloc
1143
- ax[:min] = min
1144
- ax[:max] = max
1145
- ax[:tick] = tick
1146
- ax[:org] = org
1147
- ax[:position] = position
1148
- ax[:major_count] = major_count
1149
- ax[:tick_size] = tick_size
1150
- ax[:label_position] = label_position
1151
- ax[:draw_axis_line] = draw_axis_line
1152
- ax[:label_orientation] = label_orientation
1153
- ax[:ticks] = 0
1154
- ax[:num_ticks] = 0
1155
- ax[:tick_labels] = 0
1156
- ax[:num_tick_labels] = 0
1157
- super(option, ax)
1158
- ax
1159
- end
1160
-
1161
- def drawaxes(x_axis, y_axis, option = 1)
1162
- super(x_axis, y_axis, option)
1162
+ def axis(spec, **opts)
1163
+ spec = spec.to_s
1164
+ raise ArgumentError, 'axis spec must not be empty' if spec.empty?
1165
+
1166
+ axis = GRAxis.new
1167
+ opts.each do |k, v|
1168
+ setter = "#{k}="
1169
+ axis.public_send(setter, v) if axis.respond_to?(setter)
1170
+ end
1171
+
1172
+ c_axis = __axis_to_c_axis(axis, for_generation: true)
1173
+ begin
1174
+ FFI.gr_axis(spec, c_axis)
1175
+ __axis_from_c_axis(c_axis)
1176
+ ensure
1177
+ FFI.gr_freeaxis(c_axis)
1178
+ end
1179
+ end
1180
+
1181
+ def drawaxis(axis)
1182
+ raise ArgumentError, 'axis spec must not be empty' if axis.spec.to_s.empty?
1183
+
1184
+ c_axis = __axis_to_c_axis(axis)
1185
+ FFI.gr_drawaxis(c_axis)
1186
+ end
1187
+
1188
+ def drawaxes(x_axis = nil, y_axis = nil, option = 1)
1189
+ c_x = x_axis && __axis_to_c_axis(x_axis, default_spec: 'X')
1190
+ c_y = y_axis && __axis_to_c_axis(y_axis, default_spec: 'Y')
1191
+ FFI.gr_drawaxes(c_x&.to_ptr, c_y&.to_ptr, option)
1163
1192
  end
1164
1193
 
1165
1194
  # Create axes in the current workspace and supply a custom function for
@@ -1480,6 +1509,14 @@ module GR
1480
1509
  super(n, x, y, nbins)
1481
1510
  end
1482
1511
 
1512
+ def hexbin_2pass(x, y, nbins, context = nil)
1513
+ n = equal_length(x, y)
1514
+ context ||= Fiddle::NULL
1515
+ context = context.to_ptr if context.respond_to?(:to_ptr)
1516
+ result = super(n, x, y, nbins, context)
1517
+ result.null? ? nil : FFI::Hexbin2Pass.new(result)
1518
+ end
1519
+
1483
1520
  # Set the currently used colormap.
1484
1521
  #
1485
1522
  # * A list of colormaps can be found at: https://gr-framework.org/colormaps.html
@@ -1516,7 +1553,7 @@ module GR
1516
1553
  if positions.nil?
1517
1554
  positions = Fiddle::NULL
1518
1555
  elsif positions.length != n
1519
- raise
1556
+ raise ArgumentError, "positions must have length #{n} (got #{positions.length})"
1520
1557
  end
1521
1558
  super(n, r, g, b, positions)
1522
1559
  end
@@ -1788,9 +1825,9 @@ module GR
1788
1825
  data = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INTPTR_T, Fiddle::RUBY_FREE)
1789
1826
  w, h = inquiry [:int, :int] do |width, height|
1790
1827
  # data is a pointer of a pointer
1791
- super(path, width, height, data.ref)
1828
+ super(path, width, height, data)
1792
1829
  end
1793
- d = data.to_str(w * h * Fiddle::SIZEOF_INT).unpack('L*') # UInt32
1830
+ d = data.ptr.to_str(w * h * Fiddle::SIZEOF_INT).unpack('L*') # UInt32
1794
1831
  [w, h, d]
1795
1832
  end
1796
1833
 
@@ -1841,12 +1878,16 @@ module GR
1841
1878
  #
1842
1879
  # @!method settransparency
1843
1880
 
1881
+ def inqtransparency
1882
+ inquiry_double { |pt| super(pt) }
1883
+ end
1884
+
1844
1885
  # Change the coordinate transformation according to the given matrix.
1845
1886
  #
1846
1887
  # @param mat [Array, NArray] 2D transformation matrix
1847
1888
  #
1848
1889
  def setcoordxform(mat)
1849
- raise if mat.size != 6
1890
+ raise ArgumentError, "mat must have 6 elements (got #{mat.size})" if mat.size != 6
1850
1891
 
1851
1892
  super(mat)
1852
1893
  end
@@ -1886,6 +1927,12 @@ module GR
1886
1927
  end
1887
1928
  end
1888
1929
 
1930
+ def inqmathtex3d(x, y, z, string, axis)
1931
+ inquiry [{ double: 16 }, { double: 16 }, { double: 16 }, { double: 16 }] do |tbx, tby, tbz, tbw|
1932
+ super(x, y, z, string, axis, tbx, tby, tbz, tbw)
1933
+ end
1934
+ end
1935
+
1889
1936
  # @!method beginselection
1890
1937
 
1891
1938
  # @!method endselection
@@ -1928,10 +1975,10 @@ module GR
1928
1975
  triangles = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INTPTR_T, Fiddle::RUBY_FREE)
1929
1976
  dim = 3
1930
1977
  n_tri = inquiry_int do |ntri|
1931
- super(npoints, x, y, ntri, triangles.ref)
1978
+ super(npoints, x, y, ntri, triangles)
1932
1979
  end
1933
1980
  if n_tri > 0
1934
- tri = triangles.to_str(dim * n_tri * Fiddle::SIZEOF_INT).unpack('l*') # Int32
1981
+ tri = triangles.ptr.to_str(dim * n_tri * Fiddle::SIZEOF_INT).unpack('l*') # Int32
1935
1982
  # Ruby : 0-based indexing
1936
1983
  # Julia : 1-based indexing
1937
1984
  tri = tri.each_slice(dim).to_a
@@ -2232,6 +2279,12 @@ module GR
2232
2279
  inquiry_int { |pt| super(pt) }
2233
2280
  end
2234
2281
 
2282
+ def inqclip
2283
+ inquiry [:int, { double: 4 }] do |region, points|
2284
+ super(region, points)
2285
+ end
2286
+ end
2287
+
2235
2288
  # Set the projection type with this flag.
2236
2289
  #
2237
2290
  # @param flag [Integer] projection type
@@ -2373,6 +2426,12 @@ module GR
2373
2426
  #
2374
2427
  # @!method setspace3d
2375
2428
 
2429
+ def inqspace3d
2430
+ inquiry %i[int double double double double] do |*pts|
2431
+ super(*pts)
2432
+ end
2433
+ end
2434
+
2376
2435
  # @!method text3d
2377
2436
 
2378
2437
  def inqtext3d(x, y, z, string, axis)
@@ -2500,6 +2559,17 @@ module GR
2500
2559
  end
2501
2560
  end
2502
2561
 
2562
+ def inqcolorlimits
2563
+ inquiry %i[double double] do |*pts|
2564
+ super(*pts)
2565
+ end
2566
+ end
2567
+
2568
+ def getmetadata(path)
2569
+ metadata = super
2570
+ metadata.to_s unless metadata.null?
2571
+ end
2572
+
2503
2573
  def getformat(origin, min, max, tick_width, major)
2504
2574
  ref = FFI::FormatReference.malloc
2505
2575
  super(ref, origin, min, max, tick_width, major)
@@ -2511,6 +2581,128 @@ module GR
2511
2581
  super(string, value, format_ref)
2512
2582
  string.to_s
2513
2583
  end
2584
+
2585
+ private
2586
+
2587
+ # Convert high-level GRAxis into low-level FFI::Axis
2588
+ def __axis_to_c_axis(axis, for_generation: false, default_spec: nil)
2589
+ c_axis = FFI::Axis.malloc
2590
+ # Keep references to allocated memory to prevent GC
2591
+ memory_refs = []
2592
+
2593
+ spec = axis.spec || default_spec
2594
+ if !for_generation && spec
2595
+ spec_string = "#{spec}\0"
2596
+ spec_ptr = Fiddle::Pointer.malloc(spec_string.bytesize, Fiddle::RUBY_FREE)
2597
+ spec_ptr[0, spec_string.bytesize] = spec_string
2598
+ memory_refs << spec_ptr
2599
+ c_axis.spec = spec_ptr.to_i
2600
+ else
2601
+ c_axis.spec = 0
2602
+ end
2603
+
2604
+ c_axis.min_val = axis.min
2605
+ c_axis.max_val = axis.max
2606
+ c_axis.tick = axis.tick
2607
+ c_axis.org = axis.org
2608
+ c_axis.position = axis.position
2609
+ c_axis.major_count = axis.major_count
2610
+
2611
+ # ticks
2612
+ if !for_generation && axis.ticks && !axis.ticks.empty?
2613
+ count = axis.ticks.size
2614
+ mem = Fiddle::Pointer.malloc(FFI::Tick.size * count, Fiddle::RUBY_FREE)
2615
+ memory_refs << mem
2616
+ axis.ticks.each_with_index do |t, i|
2617
+ tick = FFI::Tick.new(mem + i * FFI::Tick.size)
2618
+ tick.value = t.value
2619
+ tick.is_major = t.is_major
2620
+ end
2621
+ c_axis.num_ticks = count
2622
+ c_axis.ticks = mem.to_i
2623
+ else
2624
+ c_axis.num_ticks = 0
2625
+ c_axis.ticks = 0
2626
+ end
2627
+
2628
+ c_axis.tick_size = axis.tick_size
2629
+
2630
+ # tick labels
2631
+ if !for_generation && axis.tick_labels && !axis.tick_labels.empty?
2632
+ count = axis.tick_labels.size
2633
+ mem = Fiddle::Pointer.malloc(FFI::TickLabel.size * count, Fiddle::RUBY_FREE)
2634
+ memory_refs << mem
2635
+ axis.tick_labels.each_with_index do |tl, i|
2636
+ lbl = FFI::TickLabel.new(mem + i * FFI::TickLabel.size)
2637
+ lbl.tick = tl.tick
2638
+ # Allocate persistent memory for label string
2639
+ label_str = "#{tl.label}\0"
2640
+ label_ptr = Fiddle::Pointer.malloc(label_str.bytesize, Fiddle::RUBY_FREE)
2641
+ memory_refs << label_ptr
2642
+ label_ptr[0, label_str.bytesize] = label_str
2643
+ lbl.label = label_ptr.to_i
2644
+ lbl.width = tl.width
2645
+ end
2646
+ c_axis.num_tick_labels = count
2647
+ c_axis.tick_labels = mem.to_i
2648
+ else
2649
+ c_axis.num_tick_labels = 0
2650
+ c_axis.tick_labels = 0
2651
+ end
2652
+
2653
+ c_axis.label_position = axis.label_position
2654
+ c_axis.draw_axis_line = axis.draw_axis_line
2655
+ c_axis.label_orientation = axis.label_orientation
2656
+
2657
+ # Store memory references in the axis object to prevent GC
2658
+ c_axis.instance_variable_set(:@__memory_refs, memory_refs)
2659
+
2660
+ c_axis
2661
+ end
2662
+
2663
+ # Convert low-level FFI::Axis back into high-level GRAxis
2664
+ def __axis_from_c_axis(c_axis)
2665
+ spec_ptr = Fiddle::Pointer[c_axis.spec]
2666
+ spec = spec_ptr.to_s unless spec_ptr.null?
2667
+
2668
+ ticks = if c_axis.num_ticks.positive? && !Fiddle::Pointer[c_axis.ticks].null?
2669
+ Array.new(c_axis.num_ticks) do |i|
2670
+ tick = FFI::Tick.new(c_axis.ticks + i * FFI::Tick.size)
2671
+ GRTick.new(value: tick.value, is_major: tick.is_major)
2672
+ end
2673
+ else
2674
+ []
2675
+ end
2676
+
2677
+ tick_labels = if c_axis.num_tick_labels.positive? && !Fiddle::Pointer[c_axis.tick_labels].null?
2678
+ Array.new(c_axis.num_tick_labels) do |i|
2679
+ lbl = FFI::TickLabel.new(c_axis.tick_labels + i * FFI::TickLabel.size)
2680
+ ptr = Fiddle::Pointer[lbl.label]
2681
+ next if ptr.null?
2682
+
2683
+ GRTickLabel.new(tick: lbl.tick, label: ptr.to_s, width: lbl.width)
2684
+ end.compact
2685
+ else
2686
+ []
2687
+ end
2688
+
2689
+ GRAxis.new(
2690
+ spec: spec,
2691
+ min: c_axis.min_val,
2692
+ max: c_axis.max_val,
2693
+ tick: c_axis.tick,
2694
+ org: c_axis.org,
2695
+ position: c_axis.position,
2696
+ major_count: c_axis.major_count,
2697
+ num_ticks: c_axis.num_ticks,
2698
+ ticks: ticks,
2699
+ tick_size: c_axis.tick_size,
2700
+ tick_labels: tick_labels,
2701
+ label_position: c_axis.label_position,
2702
+ draw_axis_line: c_axis.draw_axis_line,
2703
+ label_orientation: c_axis.label_orientation
2704
+ )
2705
+ end
2514
2706
  end
2515
2707
 
2516
2708
  ASF_BUNDLED = 0
data/lib/gr3/gr3base.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GR3
4
- # This module automatically converts Ruby arrays and Numo::Narray into
4
+ # This module automatically converts Ruby arrays and Numo::NArray into
5
5
  # Fiddley::MemoryPointer.
6
6
  module GR3Base
7
7
  extend GRCommons::DefineMethods
data/lib/gr3.rb CHANGED
@@ -47,10 +47,10 @@
47
47
  # * This is a opinion of kojix2 and may be changed by future maintainers.
48
48
  #
49
49
  # @note
50
- # GR3 uses Numo::Narrray.
50
+ # GR3 uses Numo::NArray.
51
51
  # * It is difficult to write GR3 modules with only Ruby arrays.
52
- # * Numo::Narray has better performance and is easier to read.
53
- # * Numo::Narray does not work with JRuby.
52
+ # * Numo::NArray has better performance and is easier to read.
53
+ # * Numo::NArray does not work with JRuby.
54
54
  # * https://github.com/ruby-numo/numo-narray/issues/147
55
55
  #
56
56
  # This is a procedural interface to the GR3 in GR plotting library,
@@ -65,30 +65,15 @@ module GR3
65
65
  end
66
66
 
67
67
  require_relative 'gr_commons/gr_commons'
68
+ require 'numo/narray'
68
69
 
69
70
  # Platforms | path
70
71
  # Windows | bin/libGR3.dll
71
72
  # MacOSX | lib/libGR3.dylib ( <= v0.53.0 .so)
72
73
  # Ubuntu | lib/libGR3.so
73
- platform = RbConfig::CONFIG['host_os']
74
- lib_names, pkg_name = \
75
- case platform
76
- when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
77
- [['libGR3.dll'], 'gr3']
78
- when /darwin|mac os/
79
- ENV['GKSwstype'] ||= 'gksqt'
80
- [['libGR3.dylib', 'libGR3.so'], 'gr3']
81
- else
82
- [['libGR3.so'], 'gr3']
83
- end
84
-
85
74
  # On Windows + RubyInstaller,
86
75
  # the environment variable GKS_FONTPATH will be set.
87
- lib_path = GRCommons::GRLib.search(lib_names, pkg_name)
88
-
89
- raise NotFoundError, "#{lib_names} not found" if lib_path.nil?
90
-
91
- self.ffi_lib = lib_path
76
+ GRCommons::GRLib.load_library(self, pkg_name: 'gr3', not_found_error: NotFoundError)
92
77
 
93
78
  require_relative 'gr3/version'
94
79
  require_relative 'gr3/ffi'
@@ -354,7 +339,11 @@ module GR3
354
339
  #
355
340
  # @return [Integer]
356
341
  #
357
- # @!method getcameraprojectionparameters
342
+ def getcameraprojectionparameters
343
+ inquiry %i[float float float] do |vfov, znear, zfar|
344
+ super(vfov, znear, zfar)
345
+ end
346
+ end
358
347
 
359
348
  # This function sets the direction of light. If it is called with (0, 0, 0),
360
349
  # the light is always pointing into the same direction as the camera.
@@ -387,10 +376,18 @@ module GR3
387
376
  # @!method setobjectid
388
377
 
389
378
  # @return [Integer]
390
- # @!method selectid
379
+ def selectid(x, y, width, height)
380
+ inquiry_int do |selection_id|
381
+ super(x, y, width, height, selection_id)
382
+ end
383
+ end
391
384
 
392
385
  # @param m [Array, NArray] the 4x4 column major view matrix
393
- # @!method getviewmatrix
386
+ def getviewmatrix
387
+ inquiry(float: 16) do |matrix|
388
+ super(matrix)
389
+ end
390
+ end
394
391
 
395
392
  # @param m [Array, NArray] the 4x4 column major view matrix
396
393
  # @!method setviewmatrix
@@ -71,7 +71,7 @@ module GRCommons
71
71
  when :uint
72
72
  str.unpack('I!*')
73
73
  when :bool
74
- str.unpack('i!*') != 0
74
+ str.unpack('i!*').map { |value| value != 0 }
75
75
  when :long
76
76
  str.unpack('l!*')
77
77
  when :ulong
@@ -115,7 +115,7 @@ module GRCommons
115
115
  when :uint
116
116
  arr.pack('I!*')
117
117
  when :bool
118
- [arr ? 1 : 0].pack('i!*')
118
+ Array(arr).map { |value| value ? 1 : 0 }.pack('i!*')
119
119
  when :long
120
120
  arr.pack('l!*')
121
121
  when :ulong
@@ -329,7 +329,7 @@ module GRCommons
329
329
 
330
330
  # added
331
331
  define_method('read_float') do
332
- __send__('get_double', 0)
332
+ __send__('get_float', 0)
333
333
  end
334
334
 
335
335
  # added
@@ -353,6 +353,7 @@ module GRCommons
353
353
  end
354
354
 
355
355
  def put_bytes(offset, str, idx = 0, len = str.bytesize - idx)
356
+ len ||= str.bytesize - idx
356
357
  @ptr[offset, len] = str[idx, len]
357
358
  end
358
359
 
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'pkg-config'
4
+ require 'rbconfig'
4
5
 
5
6
  module GRCommons
6
- # This module helps GR, GR and GRM to search the shared library.
7
+ # This module helps GR, GR3 and GRM to search the shared library.
7
8
  #
8
9
  # The order of priority:
9
10
  # 1. RubyInstaller ( for Windows only )
@@ -36,11 +37,35 @@ module GRCommons
36
37
  warn "#{lib_names} : Dir GRDIR=#{ENV['GRDIR']} not found." # return nil
37
38
  end
38
39
 
40
+ # Return default shared library names for a GR package.
41
+ def default_lib_names(pkg_name)
42
+ lib_base = "lib#{pkg_name.upcase}"
43
+ case RbConfig::CONFIG['host_os']
44
+ when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
45
+ ["#{lib_base}.dll"]
46
+ when /darwin|mac os/
47
+ ENV['GKS_WSTYPE'] ||= 'gksqt'
48
+ ["#{lib_base}.dylib", "#{lib_base}.so"]
49
+ else
50
+ ["#{lib_base}.so"]
51
+ end
52
+ end
53
+
54
+ # Search the shared library and assign it to the given module.
55
+ def load_library(mod, pkg_name:, lib_names: nil, not_found_error: LoadError)
56
+ lib_names ||= default_lib_names(pkg_name)
57
+ lib_path = search(lib_names, pkg_name)
58
+
59
+ raise not_found_error, "#{lib_names} not found" if lib_path.nil?
60
+
61
+ mod.ffi_lib = lib_path
62
+ end
63
+
39
64
  # Search the shared library.
40
65
  # @note This method does not detect the Operating System.
41
66
  #
42
67
  # @param lib_names [Array] The actual file name of the shared library.
43
- # @param pkg_name [String] The package name to be used when searching with pkg-configg
68
+ # @param pkg_name [String] The package name to be used when searching with pkg-config
44
69
  def search(lib_names, pkg_name)
45
70
  # FIXME: There may be a better way to do it...
46
71
  def lib_names.map_find(&block)
@@ -70,7 +95,7 @@ module GRCommons
70
95
  end
71
96
 
72
97
  # Windows + RubyInstaller
73
- if ruby_installer?
98
+ if ruby_installer? && lib_path
74
99
  RubyInstaller::Runtime.add_dll_directory(File.dirname(lib_path))
75
100
  # FIXME: Where should I write this code?
76
101
  ENV['GKS_FONTPATH'] ||= grdir
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GRCommons
4
- VERSION = '0.73.19.1'
4
+ VERSION = '0.73.27.0'
5
5
  end
data/lib/grm/ffi.rb CHANGED
@@ -82,7 +82,7 @@ module GRM
82
82
  try_extern 'int grm_plot(const grm_args_t *args)'
83
83
  try_extern 'int grm_render(void)'
84
84
  try_extern 'int grm_process_tree(void)'
85
- try_extern 'int grm_export(const char *file_path)'
85
+ try_extern 'int grm_export(const char *file_path, int export_xml)'
86
86
  try_extern 'int grm_switch(unsigned int id)'
87
87
  try_extern 'int grm_get_error_code()'
88
88
  try_extern 'int grm_load_graphics_tree(FILE *file)'
data/lib/grm/grmbase.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GRM
4
- # This module automatically converts Ruby arrays and Numo::Narray into
4
+ # This module automatically converts Ruby arrays and Numo::NArray into
5
5
  # Fiddley::MemoryPointer.
6
6
  module GRMBase
7
7
  extend GRCommons::DefineMethods
data/lib/grm.rb CHANGED
@@ -29,25 +29,9 @@ module GRM
29
29
  # Windows | bin/libGRM.dll
30
30
  # MacOSX | lib/libGRM.dylib ( <= v0.53.0 .so)
31
31
  # Ubuntu | lib/libGRM.so
32
- platform = RbConfig::CONFIG['host_os']
33
- lib_names, pkg_name = \
34
- case platform
35
- when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
36
- [['libGRM.dll'], 'grm']
37
- when /darwin|mac os/
38
- ENV['GKSwstype'] ||= 'gksqt'
39
- [['libGRM.dylib', 'libGRM.so'], 'grm']
40
- else
41
- [['libGRM.so'], 'grm']
42
- end
43
-
44
32
  # On Windows + RubyInstaller,
45
33
  # the environment variable GKS_FONTPATH will be set.
46
- lib_path = GRCommons::GRLib.search(lib_names, pkg_name)
47
-
48
- raise NotFoundError, "#{lib_names} not found" if lib_path.nil?
49
-
50
- self.ffi_lib = lib_path
34
+ GRCommons::GRLib.load_library(self, pkg_name: 'grm', not_found_error: NotFoundError)
51
35
 
52
36
  require_relative 'grm/version'
53
37
  require_relative 'grm/ffi'
@@ -111,7 +95,10 @@ module GRM
111
95
  GRM.args_push(@args, key, 'i', :int, value)
112
96
  when Float
113
97
  GRM.args_push(@args, key, 'd', :double, value)
98
+ when TrueClass, FalseClass
99
+ GRM.args_push(@args, key, 'i', :int, value ? 1 : 0)
114
100
  when Args
101
+ @references << value
115
102
  GRM.args_push(@args, key, 'a', :voidp, value.address)
116
103
  value.to_gr.free = nil
117
104
  when Array
@@ -138,30 +125,45 @@ module GRM
138
125
  case value[0]
139
126
  when String
140
127
  addresses = value.collect { |v| Fiddle::Pointer[v].to_i }
128
+ @references.concat(value)
129
+ packed = addresses.pack('J*')
130
+ @references << packed
141
131
  GRM.args_push(@args, key, 'nS',
142
132
  :int, value.size,
143
- :voidp, addresses.pack('J*'))
144
- when Integer
145
- GRM.args_push(@args, key, 'nI',
146
- :int, value.size,
147
- :voidp, value.pack('i*'))
148
- when Float
133
+ :voidp, packed)
134
+ when Integer, Float
135
+ if value.all? { |v| v.is_a?(Integer) }
136
+ packed = value.pack('i*')
137
+ @references << packed
138
+ GRM.args_push(@args, key, 'nI',
139
+ :int, value.size,
140
+ :voidp, packed)
141
+ return
142
+ end
143
+
144
+ packed = value.map(&:to_f).pack('d*')
145
+ @references << packed
149
146
  GRM.args_push(@args, key, 'nD',
150
147
  :int, value.size,
151
- :voidp, value.pack('d*'))
148
+ :voidp, packed)
152
149
  when Args
150
+ @references.concat(value)
151
+ packed = value.collect(&:address).pack('J*')
152
+ @references << packed
153
153
  GRM.args_push(@args, key, 'nA',
154
154
  :int, value.size,
155
- :voidp, value.collect(&:address).pack('J*'))
155
+ :voidp, packed)
156
156
  value.each do |v|
157
157
  v.to_gr.free = nil
158
158
  end
159
159
  else
160
160
  vs = value.collect { |v| Args.new(**v) }
161
161
  @references.concat(vs)
162
+ packed = vs.collect(&:address).pack('J*')
163
+ @references << packed
162
164
  GRM.args_push(@args, key, 'nA',
163
165
  :int, value.size,
164
- :voidp, vs.collect(&:address).pack('J*'))
166
+ :voidp, packed)
165
167
  vs.each do |v|
166
168
  v.to_gr.free = nil
167
169
  end
@@ -213,5 +215,9 @@ module GRM
213
215
  args = Args.try_convert(args) || args
214
216
  super(args)
215
217
  end
218
+
219
+ def export(file_path, export_xml = 0)
220
+ super(file_path, export_xml)
221
+ end
216
222
  end
217
223
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-gr
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.73.19.1
4
+ version: 0.73.27.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - kojix2
@@ -9,6 +9,20 @@ bindir: bin
9
9
  cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: base64
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
12
26
  - !ruby/object:Gem::Dependency
13
27
  name: fiddle
14
28
  requirement: !ruby/object:Gem::Requirement
@@ -99,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
113
  - !ruby/object:Gem::Version
100
114
  version: '0'
101
115
  requirements: []
102
- rubygems_version: 3.7.2
116
+ rubygems_version: 4.0.21
103
117
  specification_version: 4
104
118
  summary: GR for Ruby
105
119
  test_files: []