ruby-gr 0.0.24 → 0.61.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/gr.rb CHANGED
@@ -48,23 +48,37 @@
48
48
  module GR
49
49
  class Error < StandardError; end
50
50
 
51
+ class NotFoundError < Error; end
52
+
51
53
  class << self
52
54
  attr_accessor :ffi_lib
53
55
  end
54
56
 
55
57
  require_relative 'gr_commons/gr_commons'
56
- extend GRCommons::SearchSharedLibrary
57
58
 
58
59
  # Platforms | path
59
60
  # Windows | bin/libgr.dll
60
- # MacOSX | lib/libGR.so (NOT .dylib)
61
+ # MacOSX | lib/libGR.dylib ( <= v0.53.0 .so)
61
62
  # Ubuntu | lib/libGR.so
62
- self.ffi_lib = case RbConfig::CONFIG['host_os']
63
- when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
64
- search_shared_library('libgr.dll', 'gr')
65
- else
66
- search_shared_library('libGR.so', 'gr')
67
- end
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
+ # On Windows + RubyInstaller,
76
+ # 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
68
82
 
69
83
  require_relative 'gr/version'
70
84
  require_relative 'gr/ffi'
@@ -165,30 +179,78 @@ module GR
165
179
  # Draw a polyline using the current line attributes,
166
180
  # starting from the first data point and ending at the last data point.
167
181
  #
168
- # @param x [Array, NArray] A list containing the X coordinates
169
- # @param y [Array, NArray] A list containing the Y coordinates
182
+ # @param x [Array, NArray] A list containing the X coordinates
183
+ # @param y [Array, NArray] A list containing the Y coordinates
184
+ # @param linewidth [Array, NArray, Numeric] A list containing the line widths
185
+ # @param line_z [Array, NArray, Numeric] A list to be converted to colors
170
186
  #
171
187
  # The values for x and y are in world coordinates.
172
188
  # The attributes that control the appearance of a polyline are linetype,
173
189
  # linewidth and color index.
174
190
  #
175
- def polyline(x, y)
191
+ def polyline(x, y, linewidth = nil, line_z = nil)
192
+ # GR.jl - Multiple dispatch
176
193
  n = equal_length(x, y)
177
- super(n, x, y)
194
+ if linewidth.nil? && line_z.nil?
195
+ super(n, x, y)
196
+ else
197
+ linewidth ||= GR.inqlinewidth
198
+ linewidth = if linewidth.is_a?(Numeric)
199
+ Array.new(n, linewidth * 100)
200
+ else
201
+ raise ArgumentError if n != linewidth.length
202
+
203
+ linewidth.map { |i| (100 * i).round }
204
+ end
205
+ line_z ||= GR.inqcolor(989) # FIXME
206
+ color = if line_z.is_a?(Numeric)
207
+ Array.new(n, line_z)
208
+ else
209
+ raise ArgumentError if n != line_z.length
210
+
211
+ to_rgb_color(line_z)
212
+ end
213
+ z = linewidth.to_a.zip(color).flatten # to_a : NArray
214
+ gdp(x, y, GDP_DRAW_LINES, z)
215
+ end
178
216
  end
179
217
 
180
218
  # Draw marker symbols centered at the given data points.
181
219
  #
182
- # @param x [Array, NArray] A list containing the X coordinates
183
- # @param y [Array, NArray] A list containing the Y coordinates
220
+ # @param x [Array, NArray] A list containing the X coordinates
221
+ # @param y [Array, NArray] A list containing the Y coordinates
222
+ # @param markersize [Array, NArray, Numeric] A list containing the marker sizes
223
+ # @param marker_z [Array, NArray, Numeric] A list to be converted to colors
184
224
  #
185
225
  # The values for x and y are in world coordinates.
186
226
  # The attributes that control the appearance of a polymarker are marker type,
187
227
  # marker size scale factor and color index.
188
228
  #
189
- def polymarker(x, y)
229
+ def polymarker(x, y, markersize = nil, marker_z = nil)
230
+ # GR.jl - Multiple dispatch
190
231
  n = equal_length(x, y)
191
- super(n, x, y)
232
+ if markersize.nil? && marker_z.nil?
233
+ super(n, x, y)
234
+ else
235
+ markersize ||= GR.inqmarkersize
236
+ markersize = if markersize.is_a?(Numeric)
237
+ Array.new(n, markersize * 100)
238
+ else
239
+ raise ArgumentError if n != markersize.length
240
+
241
+ markersize.map { |i| (100 * i).round }
242
+ end
243
+ marker_z ||= GR.inqcolor(989) # FIXME
244
+ color = if marker_z.is_a?(Numeric)
245
+ Array.new(n, marker_z)
246
+ else
247
+ raise ArgumentError if n != marker_z.length
248
+
249
+ to_rgb_color(marker_z)
250
+ end
251
+ z = markersize.to_a.zip(color).flatten # to_a : NArray
252
+ gdp(x, y, GDP_DRAW_MARKERS, z)
253
+ end
192
254
  end
193
255
 
194
256
  # Draw a text at position `x`, `y` using the current text attributes.
@@ -259,7 +321,9 @@ module GR
259
321
  def nonuniformcellarray(x, y, dimx, dimy, color)
260
322
  raise ArgumentError unless x.length == dimx + 1 && y.length == dimy + 1
261
323
 
262
- super(x, y, dimx, dimy, 1, 1, dimx, dimy, int(color))
324
+ nx = dimx == x.length ? -dimx : dimx
325
+ ny = dimy == y.length ? -dimy : dimy
326
+ super(x, y, nx, ny, 1, 1, dimx, dimy, int(color))
263
327
  end
264
328
 
265
329
  # Display a two dimensional color index array mapped to a disk using polar
@@ -270,9 +334,9 @@ module GR
270
334
  # raidus. The center point of the resulting disk is located at `xorg`, `yorg`
271
335
  # and the radius of the disk is `rmax`.
272
336
  #
273
- # @param xorg [Numeric] X coordinate of the disk center in world
337
+ # @param x_org [Numeric] X coordinate of the disk center in world
274
338
  # coordinates
275
- # @param yorg [Numeric] Y coordinate of the disk center in world
339
+ # @param y_org [Numeric] Y coordinate of the disk center in world
276
340
  # coordinates
277
341
  # @param phimin [Numeric] start angle of the disk sector in degrees
278
342
  # @param phimax [Numeric] end angle of the disk sector in degrees
@@ -280,7 +344,7 @@ module GR
280
344
  # coordinates
281
345
  # @param rmax [Numeric] outer radius of the punctured disk in world
282
346
  # coordinates
283
- # @param dimiphi [Integer] Phi (X) dimension of the color index array
347
+ # @param dimphi [Integer] Phi (X) dimension of the color index array
284
348
  # @param dimr [Integer] iR (Y) dimension of the color index array
285
349
  # @param color [Array, NArray] Color index array
286
350
  #
@@ -308,6 +372,27 @@ module GR
308
372
  super(x_org, y_org, phimin, phimax, rmin, rmax, dimphi, dimr, 1, 1, dimphi, dimr, int(color))
309
373
  end
310
374
 
375
+ # Display a two dimensional color index array mapped to a disk using polar
376
+ # coordinates with nonuniform cell sizes.
377
+ #
378
+ # @param phi [Array, NArray] array with the angles of the disk sector in degrees
379
+ # @param r [Array, NArray] array with the radii of the disk in world coordinates
380
+ # @param ncol [Integer] total number of columns in the color index array and the angle array
381
+ # @param nrow [Integer] total number of rows in the color index array and the radii array
382
+ # @param color [Integer] color index array
383
+ #
384
+ # The mapping of the polar coordinates and the drawing is performed simialr
385
+ # to `gr_polarcellarray` with the difference that the individual cell sizes
386
+ # are specified allowing nonuniform sized cells.
387
+ #
388
+ def nonuniformpolarcellarray(phi, r, ncol, nrow, color)
389
+ raise ArgumentError unless (ncol..(ncol + 1)).include?(phi.length) && (nrow..(nrow + 1)).include?(r.length)
390
+
391
+ dimphi = ncol == phi.length ? -ncol : ncol
392
+ dimr = nrow == r.length ? -nrow : nrow
393
+ super(0, 0, phi, r, dimphi, dimr, 1, 1, ncol, nrow, int(color))
394
+ end
395
+
311
396
  # Generates a generalized drawing primitive (GDP) of the type you specify,
312
397
  # using specified points and any additional information contained in a data
313
398
  # record.
@@ -320,7 +405,7 @@ module GR
320
405
  def gdp(x, y, primid, datrec)
321
406
  n = equal_length(x, y)
322
407
  ldr = datrec.length
323
- super(n, x, y, primid, ldr, datrec)
408
+ super(n, x, y, primid, ldr, int(datrec))
324
409
  end
325
410
 
326
411
  # Generate a cubic spline-fit,
@@ -777,7 +862,7 @@ module GR
777
862
 
778
863
  # Set the clipping indicator.
779
864
  #
780
- # @params indicator [Integer] An indicator specifying whether clipping is on
865
+ # @param indicator [Integer] An indicator specifying whether clipping is on
781
866
  # or off.
782
867
  # * 0 : Clipping is off. Data outside of the window will be drawn.
783
868
  # * 1 : Clipping is on. Data outside of the window will not be drawn.
@@ -1296,7 +1381,7 @@ module GR
1296
1381
  # @param x [Array, NArray] A list containing the X coordinates
1297
1382
  # @param y [Array, NArray] A list containing the Y coordinates
1298
1383
  # @param z [Array, NArray] A list containing the Z coordinates
1299
- # @param lavels [Array, NArray] A list of contour levels
1384
+ # @param levels [Array, NArray] A list of contour levels
1300
1385
  #
1301
1386
  def tricontour(x, y, z, levels)
1302
1387
  npoints = x.length # equal_length ?
@@ -1355,6 +1440,16 @@ module GR
1355
1440
  super(n, r, g, b, positions)
1356
1441
  end
1357
1442
 
1443
+ # Inquire the color index range of the current colormap.
1444
+ #
1445
+ # @return [Array] first_color_ind The color index of the first color,
1446
+ # last_color_ind The color index of the last color
1447
+ def inqcolormapinds
1448
+ inquiry %i[int int] do |first_color_ind, last_color_ind|
1449
+ super(first_color_ind, last_color_ind)
1450
+ end
1451
+ end
1452
+
1358
1453
  # @!method colorbar
1359
1454
 
1360
1455
  def inqcolor(color)
@@ -1413,7 +1508,15 @@ module GR
1413
1508
  # * .webm : WebM video file
1414
1509
  # * .ogg : Ogg video file
1415
1510
  #
1416
- # @!method beginprint
1511
+ # @note Ruby feature - you can use block to call endprint automatically.
1512
+
1513
+ def beginprint(file_path)
1514
+ super(file_path)
1515
+ if block_given?
1516
+ yield
1517
+ endprint
1518
+ end
1519
+ end
1417
1520
 
1418
1521
  # Open and activate a print device with the given layout attributes.
1419
1522
  #
@@ -1534,14 +1637,14 @@ module GR
1534
1637
  # curves.
1535
1638
  #
1536
1639
  # @param points [Array, NArray] (N, 2) array of (x, y) vertices
1537
- # @parm codes [Array, NArray] N-length array of path codes
1640
+ # @param codes [Array, NArray] N-length array of path codes
1538
1641
  # * STOP : end the entire path
1539
1642
  # * MOVETO : move to the given vertex
1540
1643
  # * LINETO : draw a line from the current position to the given vertex
1541
1644
  # * CURVE3 : draw a quadratic Bézier curve
1542
1645
  # * CURVE4 : draw a cubic Bézier curve
1543
1646
  # * CLOSEPOLY : draw a line segment to the start point of the current path
1544
- # @parm fill [Integer]
1647
+ # @param fill [Integer]
1545
1648
  # A flag indication whether resulting path is to be filled or not
1546
1649
  #
1547
1650
  def drawpath(points, codes, fill)
@@ -1601,7 +1704,7 @@ module GR
1601
1704
  def readimage(path)
1602
1705
  # Feel free to make a pull request if you catch a mistake
1603
1706
  # or you have an idea to improve it.
1604
- data = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INTPTR_T)
1707
+ data = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INTPTR_T, Fiddle::RUBY_FREE)
1605
1708
  w, h = inquiry [:int, :int] do |width, height|
1606
1709
  # data is a pointer of a pointer
1607
1710
  super(path, width, height, data.ref)
@@ -1739,7 +1842,7 @@ module GR
1739
1842
  # Feel free to make a pull request if you catch a mistake
1740
1843
  # or you have an idea to improve it.
1741
1844
  npoints = equal_length(x, y)
1742
- triangles = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INTPTR_T)
1845
+ triangles = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INTPTR_T, Fiddle::RUBY_FREE)
1743
1846
  dim = 3
1744
1847
  n_tri = inquiry_int do |ntri|
1745
1848
  super(npoints, x, y, ntri, triangles.ref)
@@ -1829,7 +1932,8 @@ module GR
1829
1932
  # * 3 : INTERP2_CUBIC - Cubic interpolation
1830
1933
  # @param extrapval [Numeric] The extrapolation value
1831
1934
  #
1832
- def interp2(x, y, z, xq, yq, method, extrapval) # flatten
1935
+ # flatten
1936
+ def interp2(x, y, z, xq, yq, method, extrapval)
1833
1937
  nx = x.length
1834
1938
  ny = y.length
1835
1939
  # nz = z.length
@@ -2003,6 +2107,18 @@ module GR
2003
2107
  super(n, x, y, codes)
2004
2108
  end
2005
2109
 
2110
+ # @param z [Array, NArray]
2111
+ # @return [Array, NArray]
2112
+ def to_rgb_color(z)
2113
+ zmin, zmax = z.minmax
2114
+ return Array.new(z.length, 0) if zmax == zmin
2115
+
2116
+ z.map do |i|
2117
+ zi = (i - zmin) / (zmax - zmin).to_f
2118
+ inqcolor(1000 + (zi * 255).round)
2119
+ end
2120
+ end
2121
+
2006
2122
  # Define the border width of subsequent path output primitives.
2007
2123
  #
2008
2124
  # @param width [Numeric] The border width scale factor
@@ -2023,13 +2139,19 @@ module GR
2023
2139
  inquiry_int { |pt| super(pt) }
2024
2140
  end
2025
2141
 
2142
+ # @!method selectclipxform
2143
+
2144
+ def inqclipxform
2145
+ inquiry_int { |pt| super(pt) }
2146
+ end
2147
+
2026
2148
  # Set the projection type with this flag.
2027
2149
  #
2028
2150
  # @param flag [Integer] projection type
2029
2151
  # The available options are:
2030
- # * 0 : GR_PROJECTION_DEFAULT - default
2031
- # * 1 : GR_PROJECTION_ORTHOGRAPHIC - orthographic
2032
- # * 2 : GR_PROJECTION_PERSPECTIVE - perspective
2152
+ # * 0 : PROJECTION_DEFAULT - default
2153
+ # * 1 : PROJECTION_ORTHOGRAPHIC - orthographic
2154
+ # * 2 : PROJECTION_PERSPECTIVE - perspective
2033
2155
  #
2034
2156
  # @!method setprojectiontype
2035
2157
 
@@ -2179,6 +2301,90 @@ module GR
2179
2301
  super(encoding)
2180
2302
  end
2181
2303
  end
2304
+
2305
+ # Load a font file from a given filename.
2306
+ #
2307
+ # This function loads a font from a given absolute filename and assigns a
2308
+ # font index to it. To use the loaded font call `gr_settextfontprec` using
2309
+ # the resulting font index and precision 3.
2310
+ #
2311
+ # @param filename [String] The absolute filename of the font
2312
+ #
2313
+ def loadfont(str)
2314
+ inquiry_int do |font|
2315
+ super(str, font)
2316
+ end
2317
+ end
2318
+
2319
+ # Set the number of threads which can run parallel.
2320
+ # The default value is the number of threads the cpu has.
2321
+ #
2322
+ # @param num [Integer] num number of threads
2323
+ #
2324
+ # @!method setthreadnumber
2325
+
2326
+ # Set the width and height of the resulting picture.
2327
+ # These values are only used for gr_volume and gr_cpubasedvolume.
2328
+ # The default values are 1000 for both.
2329
+ #
2330
+ # @param width [Integer] width of the resulting image
2331
+ # @param height [Integer] height of the resulting image
2332
+ #
2333
+ # @!method setpicturesizeforvolume
2334
+
2335
+ # Set the gr_volume border type with this flag.
2336
+ # This inflicts how the volume is calculated. When the flag is set to
2337
+ # GR_VOLUME_WITH_BORDER the border will be calculated the same as the points
2338
+ # inside the volume.
2339
+ #
2340
+ # @param flag [Integer] calculation of the gr_volume border
2341
+ # The available options are:
2342
+ # * 0 : VOLUME_WITHOUT_BORDER - default value
2343
+ # * 1 : VOLUME_WITH_BORDER - gr_volume with border
2344
+ #
2345
+ # @!method setvolumebordercalculation # @!method setthreadnumber
2346
+
2347
+ # Set if gr_cpubasedvolume is calculated approximative or exact.
2348
+ # To use the exact calculation set approximative_calculation to 0.
2349
+ # The default value is the approximative version, which can be set with the
2350
+ # number 1.
2351
+ #
2352
+ # @param approximative_calculation [Integer] exact or approximative calculation
2353
+ # of the volume
2354
+ #
2355
+ # @!method setapproximativecalculation
2356
+
2357
+ # Inquire the parameters which can be set for cpubasedvolume.
2358
+ # The size of the resulting image, the way the volumeborder is calculated and
2359
+ # the amount of threads which are used.
2360
+ #
2361
+ # @return [Array]
2362
+ # * border - flag which tells how the border is calculated
2363
+ # * max_threads - number of threads
2364
+ # * picture_width - width of the resulting image
2365
+ # * picture_height - height of the resulting image
2366
+ # * approximative_calculation - exact or approximative calculation of gr_cpubasedvolume
2367
+ #
2368
+ def inqvolumeflags
2369
+ inquiry([:int] * 5) do |*pts|
2370
+ super(*pts)
2371
+ end
2372
+ end
2373
+
2374
+ # FIXME! (#61)
2375
+ # @!method cpubasedvolume
2376
+
2377
+ def inqvpsize
2378
+ inquiry %i[int int double] do |*pts|
2379
+ super(*pts)
2380
+ end
2381
+ end
2382
+
2383
+ def polygonmesh3d(px, py, pz, connections, colors)
2384
+ n_points = equal_length(px, py, pz)
2385
+ n_connections = colors.length
2386
+ super(n_points, px, py, pz, n_connections, int(connections), int(colors))
2387
+ end
2182
2388
  end
2183
2389
 
2184
2390
  ASF_BUNDLED = 0
@@ -2387,6 +2593,10 @@ module GR
2387
2593
  PATH_CURVE4 = 0x04
2388
2594
  PATH_CLOSEPOLY = 0x4f
2389
2595
 
2596
+ GDP_DRAW_PATH = 1
2597
+ GDP_DRAW_LINES = 2
2598
+ GDP_DRAW_MARKERS = 3
2599
+
2390
2600
  MPL_SUPPRESS_CLEAR = 1
2391
2601
  MPL_POSTPONE_UPDATE = 2
2392
2602
 
data/lib/gr3/ffi.rb CHANGED
@@ -15,7 +15,7 @@ module GR3
15
15
  raise LoadError, 'Could not find GR Framework'
16
16
  end
17
17
 
18
- extend GRCommons::Extern
18
+ extend GRCommons::TryExtern
19
19
 
20
20
  # https://github.com/sciapp/gr/blob/master/lib/gr3/gr3.h
21
21
  # keep same order
@@ -91,6 +91,8 @@ module GR3
91
91
  'double offset_x, double offset_y, double offset_z)'
92
92
  try_extern 'int gr3_createsurfacemesh(int *mesh, int nx, int ny, ' \
93
93
  'float *px, float *py, float *pz, int option)'
94
+ try_extern 'int gr3_createsurface3dmesh(int *mesh, int ncols, int nrows, ' \
95
+ 'float *px, float *py, float *pz);'
94
96
  try_extern 'void gr3_drawmesh_grlike(int mesh, int n, ' \
95
97
  'const float *positions, const float *directions, const float *ups, ' \
96
98
  'const float *colors, const float *scales)'
@@ -138,5 +140,9 @@ module GR3
138
140
  # try_extern 'void gr3_drawtrianglesurface(int n, const float *triangles)'
139
141
  try_extern 'void gr_volume(int nx, int ny, int nz, double *data, ' \
140
142
  'int algorithm, double *dmin_ptr, double *dmax_ptr)'
143
+ try_extern 'void gr3_setorthographicprojection' \
144
+ '(float left, float right, float bottom, float top, float znear, float zfar)'
145
+ try_extern 'void gr3_setsurfaceoption(int option)'
146
+ try_extern 'int gr3_getsurfaceoption(void)'
141
147
  end
142
148
  end
data/lib/gr3.rb CHANGED
@@ -58,23 +58,37 @@
58
58
  module GR3
59
59
  class Error < StandardError; end
60
60
 
61
+ class NotFoundError < Error; end
62
+
61
63
  class << self
62
64
  attr_accessor :ffi_lib
63
65
  end
64
66
 
65
67
  require_relative 'gr_commons/gr_commons'
66
- extend GRCommons::SearchSharedLibrary
67
68
 
68
69
  # Platforms | path
69
70
  # Windows | bin/libGR3.dll
70
- # MacOSX | lib/libGR3.so (NOT .dylib)
71
+ # MacOSX | lib/libGR3.dylib ( <= v0.53.0 .so)
71
72
  # Ubuntu | lib/libGR3.so
72
- self.ffi_lib = case RbConfig::CONFIG['host_os']
73
- when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
74
- search_shared_library('libGR3.dll', 'gr3')
75
- else
76
- search_shared_library('libGR3.so', 'gr3')
77
- end
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
+ # On Windows + RubyInstaller,
86
+ # 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
78
92
 
79
93
  require_relative 'gr3/version'
80
94
  require_relative 'gr3/ffi'
@@ -813,6 +827,7 @@ module GR3
813
827
  IA_END_OF_LIST = 0
814
828
  IA_FRAMEBUFFER_WIDTH = 1
815
829
  IA_FRAMEBUFFER_HEIGHT = 2
830
+ IA_NUM_THREADS = 3
816
831
 
817
832
  # Error
818
833
  ERROR_NONE = 0
@@ -843,6 +858,11 @@ module GR3
843
858
  DRAWABLE_OPENGL = 1
844
859
  DRAWABLE_GKS = 2
845
860
 
861
+ # Projection
862
+ PROJECTION_PERSPECTIVE = 0
863
+ PROJECTION_PARALLEL = 1
864
+ PROJECTION_ORTHOGRAPHIC = 2
865
+
846
866
  # SurfaceOption
847
867
  SURFACE_DEFAULT = 0
848
868
  SURFACE_NORMALS = 1
@@ -16,9 +16,9 @@ module GRCommons
16
16
  args.map! do |arg|
17
17
  case arg
18
18
  when Array
19
- GRCommons::GRCommonUtils.public_send(default_type, arg)
19
+ GRCommonUtils.public_send(default_type, arg)
20
20
  when ->(x) { defined?(Numo::NArray) && x.is_a?(Numo::NArray) }
21
- GRCommons::GRCommonUtils.public_send(default_type, arg)
21
+ GRCommonUtils.public_send(default_type, arg)
22
22
  else
23
23
  arg
24
24
  end
@@ -188,7 +188,7 @@ module GRCommons
188
188
  @size = @ptr.size
189
189
  else
190
190
  @size = type2size(type) * num
191
- @ptr = Fiddle::Pointer.malloc(@size)
191
+ @ptr = Fiddle::Pointer.malloc(@size, Fiddle::RUBY_FREE)
192
192
  end
193
193
  end
194
194
 
@@ -43,7 +43,7 @@ module GRCommons
43
43
  if narray?(data)
44
44
  Numo::Int32.cast(data).to_binary
45
45
  else
46
- Fiddley::Utils.array2str(:int32, data.to_a.flatten) # TODO
46
+ Fiddley::Utils.array2str(:int32, data.to_a.flatten)
47
47
  end
48
48
  end
49
49
 
@@ -52,7 +52,7 @@ module GRCommons
52
52
  if narray?(data)
53
53
  Numo::UInt32.cast(data).to_binary
54
54
  else
55
- Fiddley::Utils.array2str(:uint, data.to_a.flatten) # TODO
55
+ Fiddley::Utils.array2str(:uint32, data.to_a.flatten)
56
56
  end
57
57
  end
58
58
 
@@ -7,8 +7,8 @@ end
7
7
  # Change the default encoding to UTF-8.
8
8
  ENV['GKS_ENCODING'] ||= 'utf8'
9
9
 
10
- require_relative 'search_shared_library'
11
- require_relative 'extern'
10
+ require_relative 'gr_lib'
11
+ require_relative 'try_extern'
12
12
  require_relative 'define_methods'
13
13
  require_relative 'gr_common_utils'
14
14
  require_relative 'jupyter_support'
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pkg-config'
4
+
5
+ module GRCommons
6
+ # This module helps GR, GR and GRM to search the shared library.
7
+ #
8
+ # The order of priority:
9
+ # 1. RubyInstaller ( for Windows only )
10
+ # 2. Environment variable GRDIR
11
+ # 3. pkg-config : https://github.com/ruby-gnome/pkg-config
12
+ # The following packages (should) support pkg-config.
13
+ # - Linux
14
+ # - Red Data Tools https://github.com/red-data-tools/packages.red-data-tools.org
15
+ # - libgr-dev
16
+ # - libgr3-dev
17
+ # - libgrm-dev
18
+ # - Mac
19
+ # - Homebrew https://github.com/Homebrew/homebrew-core
20
+ # - libgr
21
+ # - Windows
22
+ # - MinGW https://github.com/msys2/MINGW-packages
23
+ # - mingw-w64-gr
24
+ module GRLib
25
+ class << self
26
+ # Check if using RubyInstaller or not.
27
+ def ruby_installer?
28
+ Object.const_defined?(:RubyInstaller)
29
+ end
30
+
31
+ # Return the directory path from the GRDIR environment variable.
32
+ def get_grdir_from_env(lib_names)
33
+ return nil unless ENV['GRDIR']
34
+ return ENV['GRDIR'] if Dir.exist?(ENV['GRDIR'])
35
+
36
+ warn "#{lib_names} : Dir GRDIR=#{ENV['GRDIR']} not found." # return nil
37
+ end
38
+
39
+ # Search the shared library.
40
+ # @note This method does not detect the Operating System.
41
+ #
42
+ # @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
44
+ def search(lib_names, pkg_name)
45
+ # FIXME: There may be a better way to do it...
46
+ def lib_names.map_find(&block)
47
+ lazy.map(&block).find { |path| path }
48
+ end
49
+
50
+ # ENV['GRDIR']
51
+ # Verify that the directory exists.
52
+ grdir = get_grdir_from_env(lib_names)
53
+
54
+ # Windows + RubyInstaller
55
+ if ruby_installer?
56
+ grdir ||= File.join(RubyInstaller::Runtime.msys2_installation.msys_path,
57
+ RubyInstaller::Runtime.msys2_installation.mingwarch)
58
+ end
59
+
60
+ # Search grdir
61
+ if grdir
62
+ lib_path = lib_names.map_find do |lib_name|
63
+ recursive_search(lib_name, grdir)
64
+ end
65
+ end
66
+
67
+ # Search with pkg-config
68
+ lib_path ||= lib_names.map_find do |lib_name|
69
+ pkg_config_search(lib_name, pkg_name)
70
+ end
71
+
72
+ # Windows + RubyInstaller
73
+ if ruby_installer?
74
+ RubyInstaller::Runtime.add_dll_directory(File.dirname(lib_path))
75
+ # FIXME: Where should I write this code?
76
+ ENV['GKS_FONTPATH'] ||= grdir
77
+ end
78
+
79
+ lib_path
80
+ end
81
+
82
+ # Recursive file search in directories
83
+ # @param name [String] File to search for
84
+ # @param base_dir [String] Directory to search
85
+ # @return path [String, NilClass] Returns the first path found.
86
+ # If not found, nil is returned.
87
+ def recursive_search(name, base_dir)
88
+ Dir.chdir(base_dir) do
89
+ paths = Dir["**/#{name}"].sort
90
+ warn "More than one file found: #{paths}" if paths.size > 1
91
+ path = paths.first
92
+ File.expand_path(path) if path
93
+ end
94
+ end
95
+
96
+ # Use pkg-config to search for shared libraries
97
+ def pkg_config_search(lib_name, pkg_name)
98
+ PKGConfig.variable(pkg_name, 'sopath')
99
+ rescue PackageConfig::NotFoundError => e
100
+ warn "#{e.message} Cannot find #{lib_name}. "
101
+ end
102
+ end
103
+ end
104
+ end