@@ -95,6 +95,54 @@ class << self
9595 # a Fiddley::MemoryPointer in the GRBase class.
9696 extend GRBase
9797
98+ # High-level axis/tick objects
99+ class GRTick
100+ attr_accessor :value , :is_major
101+
102+ def initialize ( value :, is_major :)
103+ @value = value
104+ @is_major = is_major
105+ end
106+ end
107+
108+ class GRTickLabel
109+ attr_accessor :tick , :label , :width
110+
111+ def initialize ( tick :, label :, width :)
112+ @tick = tick
113+ @label = label
114+ @width = width
115+ end
116+ end
117+
118+ class GRAxis
119+ attr_accessor :min , :max , :tick , :org , :position ,
120+ :major_count , :num_ticks , :ticks ,
121+ :tick_size , :tick_labels , :label_position ,
122+ :draw_axis_line , :label_orientation
123+
124+ def initialize ( min : Float ::NAN , max : Float ::NAN , tick : Float ::NAN ,
125+ org : Float ::NAN , position : Float ::NAN ,
126+ major_count : 1 , num_ticks : 0 , ticks : nil ,
127+ tick_size : Float ::NAN , tick_labels : nil ,
128+ label_position : Float ::NAN ,
129+ draw_axis_line : 1 , label_orientation : 0 )
130+ @min = min
131+ @max = max
132+ @tick = tick
133+ @org = org
134+ @position = position
135+ @major_count = major_count
136+ @num_ticks = num_ticks
137+ @ticks = ticks
138+ @tick_size = tick_size
139+ @tick_labels = tick_labels
140+ @label_position = label_position
141+ @draw_axis_line = draw_axis_line
142+ @label_orientation = label_orientation
143+ end
144+ end
145+
98146 class << self
99147 # @!method initgr
100148
@@ -1116,50 +1164,31 @@ def inqtextext(x, y, string)
11161164
11171165 alias axes2d axes
11181166
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 )
1167+ def axis ( option , **opts )
1168+ axis = GRAxis . new
1169+ opts . each do |k , v |
1170+ setter = "#{ k } ="
1171+ axis . public_send ( setter , v ) if axis . respond_to? ( setter )
1172+ end
1173+
1174+ c_axis = __axis_to_c_axis ( axis )
1175+ # accept String, Symbol or single-character option
1176+ ch = option . is_a? ( Symbol ) ? option . to_s [ 0 , 1 ] : option . to_s [ 0 , 1 ]
1177+ FFI . gr_axis ( ch . ord , c_axis )
1178+ __axis_from_c_axis ( c_axis )
1179+ end
1180+
1181+ def drawaxis ( option , axis )
1182+ c_axis = __axis_to_c_axis ( axis )
1183+ # accept String, Symbol or single-character option
1184+ ch = option . is_a? ( Symbol ) ? option . to_s [ 0 , 1 ] : option . to_s [ 0 , 1 ]
1185+ FFI . gr_drawaxis ( ch . ord , 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 )
1190+ c_y = y_axis && __axis_to_c_axis ( y_axis )
1191+ FFI . gr_drawaxes ( c_x || 0 , c_y || 0 , option )
11631192 end
11641193
11651194 # Create axes in the current workspace and supply a custom function for
@@ -2511,6 +2540,101 @@ def ftoa(value, format_ref)
25112540 super ( string , value , format_ref )
25122541 string . to_s
25132542 end
2543+
2544+ private
2545+
2546+ # Convert high-level GRAxis into low-level FFI::Axis
2547+ def __axis_to_c_axis ( axis )
2548+ c_axis = FFI ::Axis . malloc
2549+
2550+ c_axis [ :min ] = axis . min
2551+ c_axis [ :max ] = axis . max
2552+ c_axis [ :tick ] = axis . tick
2553+ c_axis [ :org ] = axis . org
2554+ c_axis [ :position ] = axis . position
2555+ c_axis [ :major_count ] = axis . major_count
2556+
2557+ # ticks
2558+ if axis . ticks && !axis . ticks . empty?
2559+ count = axis . ticks . size
2560+ mem = FFI ::Tick . malloc ( count )
2561+ axis . ticks . each_with_index do |t , i |
2562+ tick = FFI ::Tick . new ( mem . to_ptr + i * FFI ::Tick . size )
2563+ tick [ :value ] = t . value
2564+ tick [ :is_major ] = t . is_major
2565+ end
2566+ c_axis [ :num_ticks ] = count
2567+ c_axis [ :ticks ] = mem . to_ptr
2568+ else
2569+ c_axis [ :num_ticks ] = 0
2570+ c_axis [ :ticks ] = 0
2571+ end
2572+
2573+ c_axis [ :tick_size ] = axis . tick_size
2574+
2575+ # tick labels
2576+ if axis . tick_labels && !axis . tick_labels . empty?
2577+ count = axis . tick_labels . size
2578+ mem = FFI ::TickLabel . malloc ( count )
2579+ axis . tick_labels . each_with_index do |tl , i |
2580+ lbl = FFI ::TickLabel . new ( mem . to_ptr + i * FFI ::TickLabel . size )
2581+ lbl [ :tick ] = tl . tick
2582+ lbl [ :label ] = Fiddle ::Pointer [ tl . label . to_s + "\0 " ]
2583+ lbl [ :width ] = tl . width
2584+ end
2585+ c_axis [ :num_tick_labels ] = count
2586+ c_axis [ :tick_labels ] = mem . to_ptr
2587+ else
2588+ c_axis [ :num_tick_labels ] = 0
2589+ c_axis [ :tick_labels ] = 0
2590+ end
2591+
2592+ c_axis [ :label_position ] = axis . label_position
2593+ c_axis [ :draw_axis_line ] = axis . draw_axis_line
2594+ c_axis [ :label_orientation ] = axis . label_orientation
2595+
2596+ c_axis
2597+ end
2598+
2599+ # Convert low-level FFI::Axis back into high-level GRAxis
2600+ def __axis_from_c_axis ( c_axis )
2601+ ticks = if c_axis [ :num_ticks ] . positive? && !Fiddle ::Pointer [ c_axis [ :ticks ] ] . null?
2602+ Array . new ( c_axis [ :num_ticks ] ) do |i |
2603+ tick = FFI ::Tick . new ( c_axis [ :ticks ] + i * FFI ::Tick . size )
2604+ GRTick . new ( value : tick [ :value ] , is_major : tick [ :is_major ] )
2605+ end
2606+ else
2607+ [ ]
2608+ end
2609+
2610+ tick_labels = if c_axis [ :num_tick_labels ] . positive? && !Fiddle ::Pointer [ c_axis [ :tick_labels ] ] . null?
2611+ Array . new ( c_axis [ :num_tick_labels ] ) do |i |
2612+ lbl = FFI ::TickLabel . new ( c_axis [ :tick_labels ] + i * FFI ::TickLabel . size )
2613+ ptr = Fiddle ::Pointer [ lbl [ :label ] ]
2614+ next if ptr . null?
2615+
2616+ GRTickLabel . new ( tick : lbl [ :tick ] , label : ptr . to_s , width : lbl [ :width ] )
2617+ end . compact
2618+ else
2619+ [ ]
2620+ end
2621+
2622+ GRAxis . new (
2623+ min : c_axis [ :min ] ,
2624+ max : c_axis [ :max ] ,
2625+ tick : c_axis [ :tick ] ,
2626+ org : c_axis [ :org ] ,
2627+ position : c_axis [ :position ] ,
2628+ major_count : c_axis [ :major_count ] ,
2629+ num_ticks : c_axis [ :num_ticks ] ,
2630+ ticks : ticks ,
2631+ tick_size : c_axis [ :tick_size ] ,
2632+ tick_labels : tick_labels ,
2633+ label_position : c_axis [ :label_position ] ,
2634+ draw_axis_line : c_axis [ :draw_axis_line ] ,
2635+ label_orientation : c_axis [ :label_orientation ]
2636+ )
2637+ end
25142638 end
25152639
25162640 ASF_BUNDLED = 0
0 commit comments