ruby-gr 0.73.19.1 → 0.73.24.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: 160f844394c8d7094012ff62b591a217cc427b8a39c5750bd9b092829e632795
4
+ data.tar.gz: ec2cb05bb3a9b4997691d0e2db4faf88e5c69873f31986a24add3a7f2f8bb9f9
5
5
  SHA512:
6
- metadata.gz: 6d49ab20cb176d37d092600164fb29fbb6c762d445c8b18803aca52d557f23873ba6af60126a62ece955a22c4274d7430aeb2e0ba7a31d07af8e211d7077dfda
7
- data.tar.gz: f8594bf5ea403ef7cd663ce44919e760f5d79d5d1122e2b29ac45195f9108226407c1953da225667b0f26ed788009fc6e26c983e38902b49cc196dd79860b464
6
+ metadata.gz: 077e1c882ccdea72597faf657dd41de18f3a3c004b3236f9fe96de81857cf4838ff46f3a43dd75784d157ca096475d39885a49ef2784733ddea6aac1ffa21cc2
7
+ data.tar.gz: 6d82381e5d6c8172361d4a0af3bc6a4c747d5d7498d6671d95ebe291c190d2bb10e17539850cf1b4e0d8def478dfee8bebc434b2a14e73246353cdae9749ed6e
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,8 @@ module GR
77
79
  ]
78
80
 
79
81
  Axis = struct [
80
- 'double min',
81
- 'double max',
82
+ 'double min_val', # min conflict with Enumerable min
83
+ 'double max_val', # max conflict with Enumerable max
82
84
  'double tick',
83
85
  'double org',
84
86
  'double position',
@@ -253,12 +255,16 @@ module GR
253
255
  try_extern 'void gr_inqmathtex3d(double, double, double, char *, int, double *, double *, double *, double *)'
254
256
  try_extern 'void gr_beginselection(int, int)'
255
257
  try_extern 'void gr_endselection(void)'
256
- try_extern 'void gr_setbboxcallback(int, void (*)(int, double, double, double, double))'
258
+ try_extern 'void gr_setbboxcallback(int, void (*)(int, double, double, double, double),' \
259
+ ' void (*)(unsigned int, unsigned int, unsigned int *))'
257
260
  try_extern 'void gr_cancelbboxcallback(void)'
261
+ try_extern 'void gr_beginpartial(int, void (*)(int, unsigned int, unsigned int,' \
262
+ ' unsigned int, unsigned int, unsigned int *))'
263
+ try_extern 'void gr_endpartial(int)'
258
264
  try_extern 'void gr_moveselection(double, double)'
259
265
  try_extern 'void gr_resizeselection(int, double, double)'
260
266
  try_extern 'void gr_inqbbox(double *, double *, double *, double *)'
261
- try_extern 'void gr_setbackground(void)'
267
+ try_extern 'void gr_setbackground(double, double, double, double)'
262
268
  try_extern 'void gr_clearbackground(void)'
263
269
  try_extern 'double gr_precision(void)'
264
270
  try_extern 'int gr_text_maxsize(void)'
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,54 @@ 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 :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(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
+ @min = min
115
+ @max = max
116
+ @tick = tick
117
+ @org = org
118
+ @position = position
119
+ @major_count = major_count
120
+ @num_ticks = num_ticks
121
+ @ticks = ticks
122
+ @tick_size = tick_size
123
+ @tick_labels = tick_labels
124
+ @label_position = label_position
125
+ @draw_axis_line = draw_axis_line
126
+ @label_orientation = label_orientation
127
+ end
128
+ end
129
+
98
130
  class << self
99
131
  # @!method initgr
100
132
 
@@ -815,6 +847,10 @@ module GR
815
847
  inquiry_int { |pt| super(pt) }
816
848
  end
817
849
 
850
+ def inqnominalsize
851
+ inquiry_double { |pt| super(pt) }
852
+ end
853
+
818
854
  # Redefine an existing color index representation by specifying an RGB color
819
855
  # triplet.
820
856
  #
@@ -956,6 +992,12 @@ module GR
956
992
 
957
993
  # @!method closeseg
958
994
 
995
+ def samplelocator
996
+ inquiry %i[double double int] do |*pts|
997
+ super(*pts)
998
+ end
999
+ end
1000
+
959
1001
  # @!method emergencyclosegks
960
1002
 
961
1003
  # @!method updategks
@@ -1116,50 +1158,35 @@ module GR
1116
1158
 
1117
1159
  alias axes2d axes
1118
1160
 
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)
1161
+ def axis(option, **opts)
1162
+ axis = GRAxis.new
1163
+ opts.each do |k, v|
1164
+ setter = "#{k}="
1165
+ axis.public_send(setter, v) if axis.respond_to?(setter)
1166
+ end
1167
+
1168
+ c_axis = __axis_to_c_axis(axis)
1169
+
1170
+ str = option.to_s
1171
+ raise ArgumentError, "axis option must be a single character, got #{str.inspect}" unless str.length == 1
1172
+
1173
+ FFI.gr_axis(str.ord, c_axis)
1174
+ __axis_from_c_axis(c_axis)
1175
+ end
1176
+
1177
+ def drawaxis(option, axis)
1178
+ c_axis = __axis_to_c_axis(axis)
1179
+
1180
+ str = option.to_s
1181
+ raise ArgumentError, "axis option must be a single character, got #{str.inspect}" unless str.length == 1
1182
+
1183
+ FFI.gr_drawaxis(str.ord, c_axis)
1184
+ end
1185
+
1186
+ def drawaxes(x_axis = nil, y_axis = nil, option = 1)
1187
+ c_x = x_axis && __axis_to_c_axis(x_axis)
1188
+ c_y = y_axis && __axis_to_c_axis(y_axis)
1189
+ FFI.gr_drawaxes(c_x&.to_ptr, c_y&.to_ptr, option)
1163
1190
  end
1164
1191
 
1165
1192
  # Create axes in the current workspace and supply a custom function for
@@ -1480,6 +1507,14 @@ module GR
1480
1507
  super(n, x, y, nbins)
1481
1508
  end
1482
1509
 
1510
+ def hexbin_2pass(x, y, nbins, context = nil)
1511
+ n = equal_length(x, y)
1512
+ context ||= Fiddle::NULL
1513
+ context = context.to_ptr if context.respond_to?(:to_ptr)
1514
+ result = super(n, x, y, nbins, context)
1515
+ result.null? ? nil : FFI::Hexbin2Pass.new(result)
1516
+ end
1517
+
1483
1518
  # Set the currently used colormap.
1484
1519
  #
1485
1520
  # * A list of colormaps can be found at: https://gr-framework.org/colormaps.html
@@ -1516,7 +1551,7 @@ module GR
1516
1551
  if positions.nil?
1517
1552
  positions = Fiddle::NULL
1518
1553
  elsif positions.length != n
1519
- raise
1554
+ raise ArgumentError, "positions must have length #{n} (got #{positions.length})"
1520
1555
  end
1521
1556
  super(n, r, g, b, positions)
1522
1557
  end
@@ -1788,9 +1823,9 @@ module GR
1788
1823
  data = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INTPTR_T, Fiddle::RUBY_FREE)
1789
1824
  w, h = inquiry [:int, :int] do |width, height|
1790
1825
  # data is a pointer of a pointer
1791
- super(path, width, height, data.ref)
1826
+ super(path, width, height, data)
1792
1827
  end
1793
- d = data.to_str(w * h * Fiddle::SIZEOF_INT).unpack('L*') # UInt32
1828
+ d = data.ptr.to_str(w * h * Fiddle::SIZEOF_INT).unpack('L*') # UInt32
1794
1829
  [w, h, d]
1795
1830
  end
1796
1831
 
@@ -1841,12 +1876,16 @@ module GR
1841
1876
  #
1842
1877
  # @!method settransparency
1843
1878
 
1879
+ def inqtransparency
1880
+ inquiry_double { |pt| super(pt) }
1881
+ end
1882
+
1844
1883
  # Change the coordinate transformation according to the given matrix.
1845
1884
  #
1846
1885
  # @param mat [Array, NArray] 2D transformation matrix
1847
1886
  #
1848
1887
  def setcoordxform(mat)
1849
- raise if mat.size != 6
1888
+ raise ArgumentError, "mat must have 6 elements (got #{mat.size})" if mat.size != 6
1850
1889
 
1851
1890
  super(mat)
1852
1891
  end
@@ -1886,6 +1925,12 @@ module GR
1886
1925
  end
1887
1926
  end
1888
1927
 
1928
+ def inqmathtex3d(x, y, z, string, axis)
1929
+ inquiry [{ double: 16 }, { double: 16 }, { double: 16 }, { double: 16 }] do |tbx, tby, tbz, tbw|
1930
+ super(x, y, z, string, axis, tbx, tby, tbz, tbw)
1931
+ end
1932
+ end
1933
+
1889
1934
  # @!method beginselection
1890
1935
 
1891
1936
  # @!method endselection
@@ -1928,10 +1973,10 @@ module GR
1928
1973
  triangles = Fiddle::Pointer.malloc(Fiddle::SIZEOF_INTPTR_T, Fiddle::RUBY_FREE)
1929
1974
  dim = 3
1930
1975
  n_tri = inquiry_int do |ntri|
1931
- super(npoints, x, y, ntri, triangles.ref)
1976
+ super(npoints, x, y, ntri, triangles)
1932
1977
  end
1933
1978
  if n_tri > 0
1934
- tri = triangles.to_str(dim * n_tri * Fiddle::SIZEOF_INT).unpack('l*') # Int32
1979
+ tri = triangles.ptr.to_str(dim * n_tri * Fiddle::SIZEOF_INT).unpack('l*') # Int32
1935
1980
  # Ruby : 0-based indexing
1936
1981
  # Julia : 1-based indexing
1937
1982
  tri = tri.each_slice(dim).to_a
@@ -2232,6 +2277,12 @@ module GR
2232
2277
  inquiry_int { |pt| super(pt) }
2233
2278
  end
2234
2279
 
2280
+ def inqclip
2281
+ inquiry [:int, { double: 4 }] do |region, points|
2282
+ super(region, points)
2283
+ end
2284
+ end
2285
+
2235
2286
  # Set the projection type with this flag.
2236
2287
  #
2237
2288
  # @param flag [Integer] projection type
@@ -2373,6 +2424,12 @@ module GR
2373
2424
  #
2374
2425
  # @!method setspace3d
2375
2426
 
2427
+ def inqspace3d
2428
+ inquiry %i[int double double double double] do |*pts|
2429
+ super(*pts)
2430
+ end
2431
+ end
2432
+
2376
2433
  # @!method text3d
2377
2434
 
2378
2435
  def inqtext3d(x, y, z, string, axis)
@@ -2511,6 +2568,113 @@ module GR
2511
2568
  super(string, value, format_ref)
2512
2569
  string.to_s
2513
2570
  end
2571
+
2572
+ private
2573
+
2574
+ # Convert high-level GRAxis into low-level FFI::Axis
2575
+ def __axis_to_c_axis(axis)
2576
+ c_axis = FFI::Axis.malloc
2577
+ # Keep references to allocated memory to prevent GC
2578
+ memory_refs = []
2579
+
2580
+ c_axis.min_val = axis.min
2581
+ c_axis.max_val = axis.max
2582
+ c_axis.tick = axis.tick
2583
+ c_axis.org = axis.org
2584
+ c_axis.position = axis.position
2585
+ c_axis.major_count = axis.major_count
2586
+
2587
+ # ticks
2588
+ if axis.ticks && !axis.ticks.empty?
2589
+ count = axis.ticks.size
2590
+ mem = Fiddle::Pointer.malloc(FFI::Tick.size * count, Fiddle::RUBY_FREE)
2591
+ memory_refs << mem
2592
+ axis.ticks.each_with_index do |t, i|
2593
+ tick = FFI::Tick.new(mem + i * FFI::Tick.size)
2594
+ tick.value = t.value
2595
+ tick.is_major = t.is_major
2596
+ end
2597
+ c_axis.num_ticks = count
2598
+ c_axis.ticks = mem.to_i
2599
+ else
2600
+ c_axis.num_ticks = 0
2601
+ c_axis.ticks = 0
2602
+ end
2603
+
2604
+ c_axis.tick_size = axis.tick_size
2605
+
2606
+ # tick labels
2607
+ if axis.tick_labels && !axis.tick_labels.empty?
2608
+ count = axis.tick_labels.size
2609
+ mem = Fiddle::Pointer.malloc(FFI::TickLabel.size * count, Fiddle::RUBY_FREE)
2610
+ memory_refs << mem
2611
+ axis.tick_labels.each_with_index do |tl, i|
2612
+ lbl = FFI::TickLabel.new(mem + i * FFI::TickLabel.size)
2613
+ lbl.tick = tl.tick
2614
+ # Allocate persistent memory for label string
2615
+ label_str = tl.label.to_s + "\0"
2616
+ label_ptr = Fiddle::Pointer.malloc(label_str.bytesize, Fiddle::RUBY_FREE)
2617
+ memory_refs << label_ptr
2618
+ label_ptr[0, label_str.bytesize] = label_str
2619
+ lbl.label = label_ptr.to_i
2620
+ lbl.width = tl.width
2621
+ end
2622
+ c_axis.num_tick_labels = count
2623
+ c_axis.tick_labels = mem.to_i
2624
+ else
2625
+ c_axis.num_tick_labels = 0
2626
+ c_axis.tick_labels = 0
2627
+ end
2628
+
2629
+ c_axis.label_position = axis.label_position
2630
+ c_axis.draw_axis_line = axis.draw_axis_line
2631
+ c_axis.label_orientation = axis.label_orientation
2632
+
2633
+ # Store memory references in the axis object to prevent GC
2634
+ c_axis.instance_variable_set(:@__memory_refs, memory_refs)
2635
+
2636
+ c_axis
2637
+ end
2638
+
2639
+ # Convert low-level FFI::Axis back into high-level GRAxis
2640
+ def __axis_from_c_axis(c_axis)
2641
+ ticks = if c_axis.num_ticks.positive? && !Fiddle::Pointer[c_axis.ticks].null?
2642
+ Array.new(c_axis.num_ticks) do |i|
2643
+ tick = FFI::Tick.new(c_axis.ticks + i * FFI::Tick.size)
2644
+ GRTick.new(value: tick.value, is_major: tick.is_major)
2645
+ end
2646
+ else
2647
+ []
2648
+ end
2649
+
2650
+ tick_labels = if c_axis.num_tick_labels.positive? && !Fiddle::Pointer[c_axis.tick_labels].null?
2651
+ Array.new(c_axis.num_tick_labels) do |i|
2652
+ lbl = FFI::TickLabel.new(c_axis.tick_labels + i * FFI::TickLabel.size)
2653
+ ptr = Fiddle::Pointer[lbl.label]
2654
+ next if ptr.null?
2655
+
2656
+ GRTickLabel.new(tick: lbl.tick, label: ptr.to_s, width: lbl.width)
2657
+ end.compact
2658
+ else
2659
+ []
2660
+ end
2661
+
2662
+ GRAxis.new(
2663
+ min: c_axis.min_val,
2664
+ max: c_axis.max_val,
2665
+ tick: c_axis.tick,
2666
+ org: c_axis.org,
2667
+ position: c_axis.position,
2668
+ major_count: c_axis.major_count,
2669
+ num_ticks: c_axis.num_ticks,
2670
+ ticks: ticks,
2671
+ tick_size: c_axis.tick_size,
2672
+ tick_labels: tick_labels,
2673
+ label_position: c_axis.label_position,
2674
+ draw_axis_line: c_axis.draw_axis_line,
2675
+ label_orientation: c_axis.label_orientation
2676
+ )
2677
+ end
2514
2678
  end
2515
2679
 
2516
2680
  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.24.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.24.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - kojix2
@@ -99,7 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
99
  - !ruby/object:Gem::Version
100
100
  version: '0'
101
101
  requirements: []
102
- rubygems_version: 3.7.2
102
+ rubygems_version: 4.0.10
103
103
  specification_version: 4
104
104
  summary: GR for Ruby
105
105
  test_files: []