tioga 1.6 → 1.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/Tioga_README +35 -10
  2. data/split/Dvector/dvector.c +264 -22
  3. data/split/Dvector/lib/Dvector_extras.rb +30 -2
  4. data/split/Flate/extconf.rb +1 -1
  5. data/split/Function/function.c +112 -2
  6. data/split/Tioga/figures.c +76 -77
  7. data/split/Tioga/figures.h +375 -490
  8. data/split/Tioga/generic.c +254 -0
  9. data/split/Tioga/generic.h +236 -0
  10. data/split/Tioga/init.c +434 -320
  11. data/split/Tioga/lib/Creating_Paths.rb +11 -1
  12. data/split/Tioga/lib/FigMkr.rb +263 -65
  13. data/split/Tioga/lib/Legends.rb +4 -2
  14. data/split/Tioga/lib/Markers.rb +3 -2
  15. data/split/Tioga/lib/Special_Paths.rb +22 -23
  16. data/split/Tioga/lib/TeX_Text.rb +79 -1
  17. data/split/Tioga/lib/TexPreamble.rb +14 -0
  18. data/split/Tioga/lib/Utils.rb +5 -1
  19. data/split/Tioga/pdfs.h +7 -45
  20. data/split/Tioga/{axes.c → shared/axes.c} +210 -197
  21. data/split/Tioga/{makers.c → shared/makers.c} +442 -211
  22. data/split/Tioga/{pdf_font_dicts.c → shared/pdf_font_dicts.c} +0 -0
  23. data/split/Tioga/shared/pdfcolor.c +628 -0
  24. data/split/Tioga/shared/pdfcoords.c +443 -0
  25. data/split/Tioga/{pdffile.c → shared/pdffile.c} +56 -52
  26. data/split/Tioga/{pdfimage.c → shared/pdfimage.c} +103 -211
  27. data/split/Tioga/shared/pdfpath.c +766 -0
  28. data/split/Tioga/{pdftext.c → shared/pdftext.c} +121 -99
  29. data/split/Tioga/shared/texout.c +524 -0
  30. data/split/Tioga/wrappers.c +489 -0
  31. data/split/Tioga/wrappers.h +259 -0
  32. data/split/extconf.rb +4 -0
  33. data/split/mkmf2.rb +12 -1
  34. data/tests/benchmark_dvector_reads.rb +112 -0
  35. data/tests/tc_Dvector.rb +35 -3
  36. data/tests/tc_Function.rb +32 -0
  37. metadata +65 -52
  38. data/split/Tioga/pdfcolor.c +0 -486
  39. data/split/Tioga/pdfcoords.c +0 -523
  40. data/split/Tioga/pdfpath.c +0 -913
  41. data/split/Tioga/texout.c +0 -380
@@ -44,7 +44,7 @@ Dictionary Entries
44
44
  'line_color' => a_color # defaults to self.line_color
45
45
  'line_width' => a_float # defaults to self.line_width
46
46
  'line_cap' => a_line_cap # defaults to self.line_cap
47
- 'line_type' => a_line_type # defaults to self.line_type
47
+ 'line_type' => a_line_type or 'None' # defaults to self.line_type
48
48
  'dy' => a_float # defaults to self.legend_text_dy
49
49
  'marker' => a_marker # defaults to nil
50
50
  'marker_color' => a_color # defaults to self.line_color
@@ -55,7 +55,9 @@ The dictionary holding the information is appended to the legend_info array. If
55
55
  then the marker with the given 'marker_color' and 'marker_scale' will be shown in the middle of the
56
56
  legend line. If the 'marker_dict' entry is present, it will have the values for 'x' and 'y' set to the location
57
57
  of the middle of the legend line and then it will be passed to the show_marker method. This gives you the option of using
58
- the full range of marker functionality in legends -- perhaps you'd like to use a line marker that is rotated, stretched, filled in one color, and stroked in another!
58
+ the full range of marker functionality in legends -- perhaps you'd like to use a line marker that is rotated,
59
+ stretched, filled in one color, and stroked in another! Sometimes you just want to have a marker in
60
+ the legend without a line; do this by setting line_type to 'None'.
59
61
 
60
62
  =end
61
63
  def save_legend_info(arg)
@@ -28,7 +28,7 @@ Computer Modern fonts which are likely to be around since they come with TeX. T
28
28
  in the FigureConstants module. Any character (or string of characters) from any of these fonts can be used as a marker.
29
29
 
30
30
  Because markers are sent to PDF rather than TeX, they are limited typographically but powerful graphically.
31
- In addition to specifying color, scale, and rotatation, as you can for TeX text, you can also stretch
31
+ In addition to specifying color, scale, and rotation, as you can for TeX text, you can also stretch
32
32
  the characters either along the baseline ('horizontal_scale') or perpendicular to it ('vertical_scale').
33
33
  You can slant the individual characters ('italic_angle') or shift the baseline along the text ('ascent_angle').
34
34
  Finally, you can specify the 'rendering_mode' for the marker to be any combination of #fill, #stroke, and #clip.
@@ -64,6 +64,7 @@ Dictionary Entries
64
64
  'rendering_mode' => a_rendering_mode # see below
65
65
  'stroke_width' => a_float # to be used for stroked markers
66
66
  'mode' # alias for 'rendering_mode'
67
+ 'legend' => a_dict or a_string # for adding marker to legend
67
68
 
68
69
 
69
70
  Examples
@@ -109,7 +110,7 @@ link:images/Marker_Shadow_Effect.png
109
110
  def show_marker(dict)
110
111
  end
111
112
 
112
- # Returns an array with [_width_, <i>dx_left</i>, <i>dx_right</i>, <i>dy_down</i>, <i>dy_up</i>] given in
113
+ # Returns an array with [_width_, <i>dx_left</i>, <i>dy_down</i>, <i>dx_right</i>, <i>dy_up</i>] given in
113
114
  # figure coordinates. The first is the width in figure x coordinates, the remainder is the bounding box
114
115
  # relative to the reference point for showing the string.
115
116
  def marker_string_info(font_number, string, scale)
@@ -11,7 +11,8 @@ Creates a path following a contour in a two dimensional table of data using an a
11
11
  Gri[http://gri.sourceforge.net/] done by Dan Kelley.
12
12
  (There is also an option to use the
13
13
  CONREC[http://local.wasp.uwa.edu.au/~pbourke/papers/conrec/] algorithm of Paul D. Bourke.)
14
- See show_contour.
14
+ The results are returned in 2-element array with first element a vector of the x values for
15
+ the contour and second element a vector of the y values. See show_contour.
15
16
 
16
17
  Dictionary Entries
17
18
  'zs' => a_dtable # The data table
@@ -19,8 +20,8 @@ Dictionary Entries
19
20
  'xs' => a_dvector # The x figure coordinates for the columns of data
20
21
  'ys' => a_dvector # The y figure coordinates for the rows of data
21
22
  'legit' => a_dtable # Optional table, same size as zs, non-zero means corresponding data is okay.
22
- 'dest_xs' => a_dvector # The contour x values will be placed in this Dvector.
23
- 'dest_ys' => a_dvector # The contour y values will be placed in this Dvector.
23
+ 'dest_xs' => a_dvector # The contour x values will be placed in this vector (optional).
24
+ 'dest_ys' => a_dvector # The contour y values will be placed in this vector (optional).
24
25
  'gaps' => an_array # Indices for gaps will be placed in this Array.
25
26
  'z_level' => a_float # The contour level
26
27
  'z' # Alias for 'z_level'
@@ -34,14 +35,11 @@ Example
34
35
  clip_press_image
35
36
  t.stroke_color = SlateGray
36
37
  t.line_width = 1
37
- dest_xs = Dvector.new; dest_ys = Dvector.new; gaps = Array.new
38
- dict = { 'dest_xs' => dest_xs, 'dest_ys' => dest_ys, 'gaps' => gaps,
39
- 'xs' => @eos_logRHOs, 'ys' => @eos_logTs,
40
- 'data' => @pres_data }
38
+ dict = { 'gaps' => gaps, 'xs' => @eos_logRHOs, 'ys' => @eos_logTs, 'data' => @pres_data }
41
39
  levels.each do |level|
42
40
  dict['level'] = level
43
- t.make_contour(dict)
44
- t.append_points_with_gaps_to_path(dest_xs, dest_ys, gaps, true)
41
+ pts_array = t.make_contour(dict)
42
+ t.append_points_with_gaps_to_path(pts_array[0], pts_array[1], gaps, true)
45
43
  t.stroke
46
44
  end
47
45
  end
@@ -53,7 +51,9 @@ link:images/Contours.png
53
51
  end
54
52
 
55
53
  =begin rdoc
56
- Creates a 'staircase' path with steps matching the given data points.
54
+ Creates a 'staircase' path with steps matching the given data points;
55
+ returns 2-element array with first element a vector of the x values for
56
+ the steps and second element a vector of the y values.
57
57
 
58
58
  Dictionary Entries
59
59
  'xfirst' => a_float # x location for the start of the steps
@@ -66,12 +66,13 @@ Dictionary Entries
66
66
  'y_last' # Alias for 'ylast'
67
67
  'xs' => a_dvector # The data x in figure coordinates
68
68
  'ys' => a_dvector # The data y in figure coordinates
69
- 'dest_xs' => a_dvector # The x values for the steps will go here.
70
- 'dest_ys' => a_dvector # The y values for the steps will go here.
69
+ 'dest_xs' => a_dvector # The x values for the steps will go here (optional).
70
+ 'dest_ys' => a_dvector # The y values for the steps will go here (optional).
71
71
 
72
72
  The widths of steps are determined by 'xfirst', 'xs', and 'xlast'; the heights of steps are
73
73
  determined by 'yfirst', 'ys', and 'ylast'. The steps up and down occur at the midpoints between
74
- the given x locations.
74
+ the given x locations. If 'dest_xs' are given in the dictionary, that vector will be set to
75
+ the x values for the steps. Similarly for 'dest_ys'.
75
76
 
76
77
  Example
77
78
 
@@ -83,16 +84,15 @@ Example
83
84
  x_first = 0.0; x_last = 18.0; y_first = y_last = 2.5
84
85
  x_results = Dvector[]
85
86
  y_results = Dvector[]
86
- t.make_steps(
87
+ stps = t.make_steps(
87
88
  'xs' => xs, 'ys' => ys,
88
- 'dest_xs' => x_results, 'dest_ys' => y_results,
89
89
  'x_first' => x_first, 'y_first' => y_first,
90
90
  'x_last' => x_last, 'y_last' => y_last)
91
91
  t.show_plot('boundaries' => [-1, 19, 8, 2]) do
92
92
  t.fill_color = FloralWhite
93
93
  t.fill_frame
94
94
  t.stroke_color = Blue
95
- t.append_points_to_path(x_results, y_results)
95
+ t.append_points_to_path(stps[0], stps[1])
96
96
  t.stroke
97
97
  t.show_marker('Xs' => xs, 'Ys' => ys, 'marker' => Bullet,
98
98
  'scale' => 0.6, 'color' => Red);
@@ -108,6 +108,7 @@ link:images/Steps.png
108
108
  Creates an interpolated series of points smoothly connecting the given data points.
109
109
  See also append_interpolant_to_path for creating smooth paths based on
110
110
  Bezier curves rather than on sampled points joined by straight line segments.
111
+ Returns a vector of the y values corresponding to the requested 'sample_ys'.
111
112
 
112
113
  Dictionary Entries
113
114
  'start_slope' => a_float # optional
@@ -115,12 +116,12 @@ Dictionary Entries
115
116
  'xs' => a_dvector # The data x in figure coordinates
116
117
  'ys' => a_dvector # The data y in figure coordinates
117
118
  'sample_xs' => a_dvector # The x values where will interpolate
118
- 'result_ys' => a_dvector # The y values will be placed here.
119
+ 'result_ys' => a_dvector # The y values will be placed here (optional).
119
120
 
120
121
  A cubic spline interpolant is created (see make_interpolant) using 'start_slope', 'end_slope', 'xs', and
121
122
  'ys'. At each x location in 'sample_xs', the interpolant is used to find the corresponding y location
122
- which is then placed in the 'result_ys' vector. The results can passed to routines such as
123
- append_points_to_path or show_polyline.
123
+ which is then returned as the value (and optionally also placed in the 'result_ys' vector).
124
+ The results can passed to routines such as append_points_to_path or show_polyline.
124
125
 
125
126
  Example
126
127
 
@@ -143,10 +144,8 @@ Example
143
144
  smooth_pts = 4*(data_pts-1) + 1
144
145
  dx = (xs[data_pts-1] - xs[0])/(smooth_pts-1)
145
146
  sample_xs = Dvector.new(smooth_pts) { |i| i*dx + xs[0] }
146
- result_ys = Dvector.new
147
- t.make_spline_interpolated_points(
148
- 'sample_xs' => sample_xs, 'result_ys' => result_ys,
149
- 'xs' => xs, 'ys' => ys,
147
+ result_ys = t.make_spline_interpolated_points(
148
+ 'sample_xs' => sample_xs, 'xs' => xs, 'ys' => ys,
150
149
  'start_slope' => 2.5*(ys[1]-ys[0])/(xs[1]-xs[0]))
151
150
  t.stroke_color = Blue
152
151
  t.append_points_to_path(sample_xs, result_ys)
@@ -61,6 +61,10 @@ With double quotes, Ruby uses backslash for a variety of escape characters such
61
61
  so the backslashes for TeX need to be entered as \\ pairs to be safe.
62
62
  Compare '$\nu\sim\tau$' to the equivalent form "$\\\\nu\\\\sim\\\\tau$" and the incorrect form "$\nu\sim\tau$".
63
63
 
64
+ Starting from Tioga 1.7, Tioga can measure the TeX text it typesets. For
65
+ that purpose, provide #show_text with a 'measure' dictionnary entry that
66
+ serves as a key to retrieve the information using #get_text_size.
67
+
64
68
  Dictionary Entries
65
69
  'text' => a_string # to be processed by TeX
66
70
  'side' => a_side # TOP, BOTTOM, LEFT, or RIGHT
@@ -77,7 +81,8 @@ Dictionary Entries
77
81
  'angle' => a_float # degrees to rotate. default 0
78
82
  'alignment' => an_alignment # see discussion of alignment
79
83
  'justification' => a_justification # see discussion of justification
80
-
84
+ 'measure' => a_string # the name of the measure
85
+
81
86
  Examples
82
87
 
83
88
  def math_typesetting
@@ -204,6 +209,79 @@ link:images/Framebox.png
204
209
  def show_text(dict)
205
210
  end
206
211
 
212
+ =begin rdoc
213
+ Returns information about the text measure named _name_. It returns a hash
214
+ with the following information:
215
+
216
+ * _[xy][tb][lr]_ the X/Y coordinates of the Top/Bottom Left/Right point of the
217
+ box around the text (top, left, right and bottom are relative to the text
218
+ natural orientation)
219
+ * _just_ the text justification
220
+ * _angle_ the text's angle, in degrees
221
+ * _tex_measured_depth_, _tex_measured_height_, tex_measured_width_, the
222
+ text's depth, width and height as measured by TeX,
223
+ (does not take scaling into accound)
224
+ * _xanchor_, _yanchor_: the page coordinates of the position of the text
225
+ (the ones that were given to #show_text)
226
+ * _points_ an array of (x,y) coordinates of the points that make the box,
227
+ in the order bottom left, bottom right, top right, top left.
228
+ * _depth_, _width_, _height_ : the size of the text.
229
+ * _align_ the alignment of the text
230
+
231
+ All the measures are given in postscript points, which means you need
232
+ to multiply by 10 before using the with
233
+ Page_Frame_Bounds#convert_output_to_figure_x
234
+ Page_Frame_Bounds#convert_output_to_figure_y. See the example
235
+
236
+ Please make sure you test the presence of one key before using it, as
237
+ any code using measures has to run *twice*: one first time to typeset the
238
+ text and ask LaTeX for information about its size, and the second time to
239
+ actually use the information. You don't need to call the code twice as it
240
+ is done automatically, but keep in mind that in the first run, the returned
241
+ hash will be empty.
242
+
243
+ def text_size_with_rotation
244
+ t.stroke_rect(0,0,1,1)
245
+ t.rescale(0.5)
246
+
247
+ equation = '\int_{-\infty}^{\infty} \! e^{-x^{2}}\, \! dx = \sqrt{\pi}'
248
+ text = "\\fbox{$\\displaystyle #{equation}$}"
249
+
250
+ nb = 5
251
+ nb.times do |i|
252
+ scale = 0.5 + i * 0.2
253
+ angle = i * 37
254
+ x = (i+1)/(nb+1.0)
255
+ y = x
256
+ color = [1.0 - i * 0.2, i*0.2, 0]
257
+ t.show_text('text' => text, 'color' => color, 'x' => x,
258
+ 'y' => x,
259
+ 'alignment' => ALIGNED_AT_MIDHEIGHT,
260
+ 'scale' => scale , 'measure' => "box#{i}",
261
+ 'angle' => angle )
262
+ size = t.get_text_size("box#{i}")
263
+ if size.key? 'points'
264
+ xs = Dvector.new
265
+ ys = Dvector.new
266
+ for x,y in size['points']
267
+ xs << t.convert_output_to_figure_x(x)
268
+ ys << t.convert_output_to_figure_y(y)
269
+ end
270
+ t.stroke_color = color
271
+ t.line_type = Line_Type_Dashes
272
+ t.stroke_rect(xs.min, ys.min,
273
+ (xs.max - xs.min),(ys.max - ys.min))
274
+ end
275
+ end
276
+ end
277
+
278
+ link:images/Text_size_with_rotation.png
279
+
280
+ =end
281
+
282
+ def get_text_size(name)
283
+ end
284
+
207
285
  # Changes the default_text_scale attribute by multiplying it times _scale_.
208
286
  # This also updates the default_text_height_dx and default_text_height_dy
209
287
  # attributes to match the new setting for default_text_scale.
@@ -152,6 +152,20 @@ module Tioga
152
152
  % personnaly doubt it would really come in useful ;-)...
153
153
  \newcommand\tiogasetfont{\reset@font\SetTiogaFontInfo%
154
154
  \selectfont}%
155
+
156
+
157
+ % This commands typesets its second argument while sending to the
158
+ % standard output successively the width, height and depth of the
159
+ % box produced.
160
+ %
161
+ % These informations are collected when Tioga runs pdflatex.
162
+ \newlength{\tiogatempdim}
163
+ \newcommand{\tiogameasure}[2]{%
164
+ \settowidth{\tiogatempdim}{#2}\typeout{#1[0]=\the\tiogatempdim}%
165
+ \settoheight{\tiogatempdim}{#2}\typeout{#1[1]=\the\tiogatempdim}%
166
+ \settodepth{\tiogatempdim}{#2}\typeout{#1[2]=\the\tiogatempdim}%
167
+ {#2}}
168
+
155
169
  \makeatother
156
170
  End_of_preamble
157
171
  COLOR_PREAMBLE = <<'End_of_preamble'
@@ -54,7 +54,7 @@ module Tioga
54
54
  }
55
55
 
56
56
  # Returns the value of the given TeX dimension in postscript points.
57
- def tex_dimension_to_bp(dim)
57
+ def self.tex_dimension_to_bp(dim)
58
58
  for unit, val in DIMENSION_CONVERSION
59
59
  if dim =~ /^\s*([\d.]+)\s*#{unit}$/
60
60
  return $1.to_f * val
@@ -69,6 +69,10 @@ module Tioga
69
69
  raise "'#{dim}' is not a valid TeX dimension"
70
70
  end
71
71
 
72
+ def tex_dimension_to_bp(dim)
73
+ return Utils::tex_dimension_to_bp(dim)
74
+ end
75
+
72
76
 
73
77
  end
74
78
  end
@@ -24,18 +24,9 @@
24
24
 
25
25
  #include <namespace.h>
26
26
 
27
- #include "flate.h"
28
-
29
- extern VALUE rb_Integer_class, rb_Numeric_class;
30
- extern ID save_dir_ID, model_number_ID, add_model_number_ID, quiet_mode_ID;
31
- extern ID tex_preview_documentclass_ID, tex_preview_preamble_ID, tex_preview_pagestyle_ID;
32
- extern ID tex_preview_left_margin_ID, tex_preview_right_margin_ID, tex_preview_top_margin_ID;
33
- extern ID tex_preview_bottom_margin_ID, tex_preview_left_fudge_ID, tex_preview_top_fudge_ID;
34
- extern ID do_cmd_ID, data_dir_ID, initialized_ID, tex_xoffset_ID, tex_yoffset_ID;
35
-
36
- extern long int *obj_offsets, capacity_obj_offsets, stream_start, stream_end, length_offset, xref_offset;
37
- extern int num_objects, next_available_object_number, next_available_gs_number, next_available_xo_number;
38
- extern int next_available_shade_number, next_available_font_number;
27
+ extern long *obj_offsets, capacity_obj_offsets, stream_start, stream_end, length_offset, xref_offset;
28
+ extern long num_objects, next_available_object_number, next_available_gs_number, next_available_xo_number;
29
+ extern long next_available_shade_number, next_available_font_number;
39
30
  extern void Record_Object_Offset(int obj_number);
40
31
  extern char *predefined_Fonts[];
41
32
  extern int num_pdf_standard_fonts, num_predefined_fonts;
@@ -75,6 +66,8 @@ typedef struct jpg_info {
75
66
  int mask_obj_num;
76
67
  char *filename;
77
68
  } JPG_Info;
69
+ extern void Write_JPG(JPG_Info *xo, int *ierr);
70
+ extern void Free_JPG(JPG_Info *xo);
78
71
 
79
72
  typedef struct sampled_info {
80
73
  // start must match start of xobj_info
@@ -96,6 +89,8 @@ typedef struct sampled_info {
96
89
  int lookup_len;
97
90
  unsigned char *lookup;
98
91
  } Sampled_Info;
92
+ extern void Write_Sampled(Sampled_Info *xo, int *ierr);
93
+ extern void Free_Sampled(Sampled_Info *xo);
99
94
 
100
95
  #define JPG_SUBTYPE 1
101
96
  #define SAMPLED_SUBTYPE 2
@@ -186,44 +181,11 @@ extern Old_Font_Dictionary *old_font_dictionaries;
186
181
 
187
182
  #define RADIANS_TO_DEGREES (180.0 / PI)
188
183
 
189
- extern bool Used_Any_Fonts(void);
190
- extern void Clear_Fonts_In_Use_Flags(void);
191
- extern void Write_Font_Dictionaries(void);
192
- extern void Write_Font_Descriptors(void);
193
- extern void Write_Font_Widths(void);
194
- extern void Write_Functions(void);
195
- extern void Write_Stroke_Opacity_Objects(void);
196
- extern void Write_Fill_Opacity_Objects(void);
197
- extern void Write_Shadings(void);
198
- extern void Write_JPG(JPG_Info *xo);
199
- extern void Write_Sampled(Sampled_Info *xo);
200
- extern void Free_Stroke_Opacities(void);
201
- extern void Free_Shadings();
202
- extern void Free_Functions();
203
- extern void Free_JPG(JPG_Info *xo);
204
- extern void Free_Sampled(Sampled_Info *xo);
205
- extern void Free_Fill_Opacities(void);
206
-
207
- extern void c_append_rect(FM *p, double x, double y, double width, double height);
208
- extern void c_clip(FM *p);
209
-
210
184
  extern bool have_current_point, constructing_path, writing_file;
211
- extern double bbox_llx, bbox_lly, bbox_urx, bbox_ury;
212
185
 
213
186
  extern FILE *OF; // for the PDF file
214
187
  extern FILE *TF; // for the temp file holding the uncompressed stream
215
188
 
216
- extern void Unpack_RGB(VALUE rgb, double *rp, double *gp, double *bp);
217
-
218
- extern void Start_Axis_Standard_State(FM *p, VALUE color, double line_width);
219
- extern void End_Axis_Standard_State(void);
220
-
221
- extern void Write_gsave(void);
222
- extern void Write_grestore(void);
223
-
224
- extern void c_private_set_default_font_size(FM *p, double size);
225
-
226
- void Init_Font_Dictionary(void);
227
189
 
228
190
  #endif /* __pdfs_H__ */
229
191
 
@@ -25,22 +25,24 @@ typedef struct {
25
25
  int type;
26
26
  int other_axis_type;
27
27
  double line_width;
28
- VALUE stroke_color;
28
+ double stroke_color_R;
29
+ double stroke_color_G;
30
+ double stroke_color_B;
29
31
  double major_tick_width; // same units as line_width
30
32
  double minor_tick_width; // same units as line_width
31
33
  double major_tick_length; // in units of numeric label char heights
32
34
  double minor_tick_length; // in units of numeric label char heights
33
- bool log_values;
35
+ bool log_vals;
34
36
  bool ticks_inside; // inside frame or toward larger x or y value for specific location
35
37
  bool ticks_outside; // inside frame or toward smaller x or y value for specific location
36
38
  double tick_interval; // set to 0 to use default
37
39
  double min_between_major_ticks; // in units of numeric label char heights
38
40
  int number_of_minor_intervals; // set to 0 to use default
39
- VALUE locations_for_major_ticks; // set to nil to use defaults
40
- VALUE locations_for_minor_ticks; // set to nil to use defaults
41
+ OBJ_PTR locations_for_major_ticks; // set to nil to use defaults
42
+ OBJ_PTR locations_for_minor_ticks; // set to nil to use defaults
41
43
  bool use_fixed_pt;
42
44
  int digits_max;
43
- VALUE tick_labels; // set to nil to use defaults
45
+ OBJ_PTR tick_labels; // set to nil to use defaults
44
46
  double numeric_label_scale;
45
47
  double numeric_label_shift; // in char heights, positive for out from edge (or toward larger x or y value)
46
48
  double numeric_label_angle;
@@ -65,62 +67,62 @@ typedef struct {
65
67
  int location;
66
68
  } PlotAxis;
67
69
 
68
- static void Init_PlotAxis_struct(PlotAxis *s) {
69
- s->free_majors = s->free_strings_for_labels = false;
70
- s->stroke_color = s->locations_for_major_ticks = s->locations_for_minor_ticks = s->tick_labels = Qnil;
71
- s->majors = NULL;
72
- s->labels = NULL;
73
- }
74
-
75
- static void axis_stroke(FM *p);
76
- void figure_moveto(FM *p, double x, double y) // figure coords
70
+ static void figure_moveto(OBJ_PTR fmkr, FM *p, double x, double y, int *ierr) // figure coords
77
71
  {
78
- c_moveto(p, convert_figure_to_output_x(p,x), convert_figure_to_output_y(p,y));
72
+ c_moveto(fmkr, p, convert_figure_to_output_x(p,x), convert_figure_to_output_y(p,y), ierr);
79
73
  }
80
74
 
81
- void figure_lineto(FM *p, double x, double y) // figure coords
75
+ static void figure_lineto(OBJ_PTR fmkr, FM *p, double x, double y, int *ierr) // figure coords
82
76
  {
83
- c_lineto(p, convert_figure_to_output_x(p,x), convert_figure_to_output_y(p,y));
77
+ c_lineto(fmkr, p, convert_figure_to_output_x(p,x), convert_figure_to_output_y(p,y), ierr);
84
78
  }
85
79
 
86
- void figure_join(FM *p, double x0, double y0, double x1, double y1) // figure coords
80
+ static void figure_join(OBJ_PTR fmkr, FM *p,
81
+ double x0, double y0, double x1, double y1, int *ierr) // figure coords
87
82
  {
88
- figure_moveto(p, x0, y0);
89
- figure_lineto(p, x1, y1);
83
+ figure_moveto(fmkr, p, x0, y0, ierr);
84
+ figure_lineto(fmkr, p, x1, y1, ierr);
90
85
  }
91
86
 
92
- static void axis_stroke(FM *p)
87
+ static void axis_stroke(OBJ_PTR fmkr, FM *p, int *ierr)
93
88
  {
94
- FM_stroke(p->fm);
89
+ c_stroke(fmkr,p, ierr);
95
90
  }
96
91
 
97
- void figure_join_and_stroke(FM *p, double x0, double y0, double x1, double y1) // figure coords
92
+ static void figure_join_and_stroke(OBJ_PTR fmkr, FM *p,
93
+ double x0, double y0, double x1, double y1, int *ierr) // figure coords
98
94
  {
99
- figure_join(p, x0, y0, x1, y1);
100
- FM_stroke(p->fm);
95
+ figure_join(fmkr, p, x0, y0, x1, y1, ierr);
96
+ c_stroke(fmkr,p, ierr);
101
97
  }
102
98
 
103
- static void Get_xaxis_Specs(FM *p, PlotAxis *s)
99
+ static void Get_xaxis_Specs(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr)
104
100
  {
101
+ s->free_majors = s->free_strings_for_labels = false;
102
+ s->stroke_color_R = 0.0; s->stroke_color_G = 0.0; s->stroke_color_B = 0.0;
103
+ s->majors = NULL;
104
+ s->labels = NULL;
105
105
  s->type = p->xaxis_type;
106
106
  s->other_axis_type = p->yaxis_type;
107
107
  s->line_width = p->xaxis_line_width; // for axis line
108
- s->stroke_color = p->xaxis_stroke_color; // for axis line and tick marks
108
+ s->stroke_color_R = p->xaxis_stroke_color_R; // for axis line and tick marks
109
+ s->stroke_color_G = p->xaxis_stroke_color_G;
110
+ s->stroke_color_B = p->xaxis_stroke_color_B;
109
111
  s->major_tick_width = p->xaxis_major_tick_width; // same units as line_width
110
112
  s->minor_tick_width = p->xaxis_minor_tick_width; // same units as line_width
111
113
  s->major_tick_length = p->xaxis_major_tick_length; // in units of numeric label char heights
112
114
  s->minor_tick_length = p->xaxis_minor_tick_length; // in units of numeric label char heights
113
- s->log_values = p->xaxis_log_values;
115
+ s->log_vals = p->xaxis_log_values;
114
116
  s->ticks_inside = p->xaxis_ticks_inside; // inside frame or toward larger x or y value for specific location
115
117
  s->ticks_outside = p->xaxis_ticks_outside; // inside frame or toward smaller x or y value for specific location
116
118
  s->tick_interval = p->xaxis_tick_interval; // set to 0 to use default
117
119
  s->min_between_major_ticks = p->xaxis_min_between_major_ticks; // in units of numeric label char heights
118
- s->number_of_minor_intervals = p->xaxis_number_of_minor_intervals; // set to 0 to use default
119
- s->locations_for_major_ticks = p->xaxis_locations_for_major_ticks; // set to nil to use defaults
120
- s->locations_for_minor_ticks = p->xaxis_locations_for_minor_ticks; // set to nil to use defaults
120
+ s->number_of_minor_intervals = p->xaxis_number_of_minor_intervals; // set to 0 to use default
121
+ s->locations_for_major_ticks = Get_xaxis_locations_for_major_ticks(fmkr, ierr);
122
+ s->locations_for_minor_ticks = Get_xaxis_locations_for_minor_ticks(fmkr, ierr);
121
123
  s->use_fixed_pt = p->xaxis_use_fixed_pt;
122
124
  s->digits_max = p->xaxis_digits_max;
123
- s->tick_labels = p->xaxis_tick_labels; // set to nil to use defaults. else must have a label for each major tick
125
+ s->tick_labels = Get_xaxis_tick_labels(fmkr, ierr);
124
126
  s->numeric_label_decimal_digits = p->xaxis_numeric_label_decimal_digits; // set to negative to use default
125
127
  s->numeric_label_scale = p->xaxis_numeric_label_scale;
126
128
  s->numeric_label_shift = p->xaxis_numeric_label_shift; // in char heights, positive for out from edge (or toward larger x or y value)
@@ -131,27 +133,33 @@ static void Get_xaxis_Specs(FM *p, PlotAxis *s)
131
133
  s->numeric_label_phase = p->xaxis_numeric_label_phase;
132
134
  }
133
135
 
134
- static void Get_yaxis_Specs(FM *p, PlotAxis *s)
136
+ static void Get_yaxis_Specs(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr)
135
137
  {
138
+ s->free_majors = s->free_strings_for_labels = false;
139
+ s->stroke_color_R = 0.0; s->stroke_color_G = 0.0; s->stroke_color_B = 0.0;
140
+ s->majors = NULL;
141
+ s->labels = NULL;
136
142
  s->type = p->yaxis_type;
137
143
  s->other_axis_type = p->xaxis_type;
138
144
  s->line_width = p->yaxis_line_width; // for axis line
139
- s->stroke_color = p->yaxis_stroke_color; // for axis line and tick marks
145
+ s->stroke_color_R = p->yaxis_stroke_color_R; // for axis line and tick marks
146
+ s->stroke_color_G = p->yaxis_stroke_color_G;
147
+ s->stroke_color_B = p->yaxis_stroke_color_B;
140
148
  s->major_tick_width = p->yaxis_major_tick_width; // same units as line_width
141
149
  s->minor_tick_width = p->yaxis_minor_tick_width; // same units as line_width
142
150
  s->major_tick_length = p->yaxis_major_tick_length; // in units of numeric label char heights
143
151
  s->minor_tick_length = p->yaxis_minor_tick_length; // in units of numeric label char heights
144
- s->log_values = p->yaxis_log_values;
152
+ s->log_vals = p->yaxis_log_values;
145
153
  s->ticks_inside = p->yaxis_ticks_inside; // inside frame or toward larger x or y value for specific location
146
154
  s->ticks_outside = p->yaxis_ticks_outside; // inside frame or toward smaller x or y value for specific location
147
155
  s->tick_interval = p->yaxis_tick_interval; // set to 0 to use default
148
156
  s->min_between_major_ticks = p->yaxis_min_between_major_ticks; // in units of numeric label char heights
149
- s->number_of_minor_intervals = p->yaxis_number_of_minor_intervals; // set to 0 to use default
150
- s->locations_for_major_ticks = p->yaxis_locations_for_major_ticks; // set to nil to use defaults
151
- s->locations_for_minor_ticks = p->yaxis_locations_for_minor_ticks; // set to nil to use defaults
157
+ s->number_of_minor_intervals = p->yaxis_number_of_minor_intervals; // set to 0 to use default
158
+ s->locations_for_major_ticks = Get_yaxis_locations_for_major_ticks(fmkr, ierr);
159
+ s->locations_for_minor_ticks = Get_yaxis_locations_for_minor_ticks(fmkr, ierr);
160
+ s->tick_labels = Get_yaxis_tick_labels(fmkr, ierr);
152
161
  s->use_fixed_pt = p->yaxis_use_fixed_pt;
153
162
  s->digits_max = p->yaxis_digits_max;
154
- s->tick_labels = p->yaxis_tick_labels; // set to nil to use defaults. else must have a label for each major tick
155
163
  s->numeric_label_decimal_digits = p->yaxis_numeric_label_decimal_digits; // set to negative to use default
156
164
  s->numeric_label_scale = p->yaxis_numeric_label_scale;
157
165
  s->numeric_label_shift = p->yaxis_numeric_label_shift; // in char heights, positive for out from edge (or toward larger x or y value)
@@ -164,7 +172,7 @@ static void Get_yaxis_Specs(FM *p, PlotAxis *s)
164
172
 
165
173
  /*======================================================================*/
166
174
 
167
- static void draw_axis_line(FM *p, int location, PlotAxis *s)
175
+ static void draw_axis_line(OBJ_PTR fmkr, FM *p, int location, PlotAxis *s, int *ierr)
168
176
  {
169
177
  switch (location) {
170
178
  case LEFT:
@@ -246,58 +254,58 @@ static void draw_axis_line(FM *p, int location, PlotAxis *s)
246
254
  s->top_or_right = false;
247
255
  break;
248
256
  }
249
- c_line_width_set(p, s->line_width);
250
- figure_join_and_stroke(p, s->x0, s->y0, s->x1, s->y1);
257
+ c_line_width_set(fmkr, p, s->line_width, ierr);
258
+ figure_join_and_stroke(fmkr, p, s->x0, s->y0, s->x1, s->y1, ierr);
251
259
  }
252
260
 
253
- static char *Create_Label(double value, int scale, int prec, bool log_values, bool use_fixed_pt, char *postfix, PlotAxis *s)
254
- { // value in figure coords
255
- char buff[100], *string;
256
- int exponent = ROUND(value);
261
+ static char *Create_Label(double val, int scale, int prec,
262
+ bool log_vals, bool use_fixed_pt, char *postfix, PlotAxis *s, int *ierr)
263
+ { // val in figure coords
264
+ char buff[100], form[100], *string;
265
+ int exponent = ROUND(val);
257
266
  buff[0] = 0;
258
- if (log_values && use_fixed_pt) { /* Logarithmic */
259
- double sav_val = value, pow_val;
260
- value = pow(10.0, exponent);
267
+ if (log_vals && use_fixed_pt) { /* Logarithmic */
268
+ double sav_val = val, pow_val;
269
+ val = pow(10.0, exponent);
261
270
  pow_val = pow(10.0, sav_val);
262
271
  if (exponent < 0) {
263
- char form[60];
264
272
  int numdig = ABS(exponent)+1;
265
- sprintf(form, (s->vertical)? "\\tiogayaxisnumericlabel{%%.%df}" : "\\tiogaxaxisnumericlabel{%%.%df}", numdig);
266
- sprintf(buff, form, pow_val);
267
- } else if (abs(value - pow_val) > 0.1) {
268
- sprintf(buff, (s->vertical)? "\\tiogayaxisnumericlabel{%0.2f}" : "\\tiogaxaxisnumericlabel{%0.2f}", pow_val);
273
+ snprintf(form, sizeof(form), (s->vertical)? "\\tiogayaxisnumericlabel{%%.%df}" : "\\tiogaxaxisnumericlabel{%%.%df}", numdig);
274
+ snprintf(buff, sizeof(buff), form, pow_val);
275
+ } else if (abs(val - pow_val) > 0.1) {
276
+ snprintf(buff, sizeof(buff), (s->vertical)? "\\tiogayaxisnumericlabel{%0.2f}" : "\\tiogaxaxisnumericlabel{%0.2f}", pow_val);
269
277
  } else {
270
- sprintf(buff, (s->vertical)? "\\tiogayaxisnumericlabel{%d}" : "\\tiogaxaxisnumericlabel{%d}", (int) value);
278
+ snprintf(buff, sizeof(buff), (s->vertical)? "\\tiogayaxisnumericlabel{%d}" : "\\tiogaxaxisnumericlabel{%d}", (int) val);
271
279
  }
272
- } else if (log_values) {
280
+ } else if (log_vals) {
273
281
  /* Exponential, i.e. 10^-1, 1, 10, 10^2, etc */
274
- double abs_diff = fabs(value - exponent);
275
- if (abs_diff > 0.1) sprintf(buff, (s->vertical)? "\\tiogayaxisnumericlabel{10^{%0.1f}}" : "\\tiogaxaxisnumericlabel{10^{%0.1f}}", value);
282
+ double abs_diff = fabs(val - exponent);
283
+ if (abs_diff > 0.1) snprintf(buff, sizeof(buff), (s->vertical)? "\\tiogayaxisnumericlabel{10^{%0.1f}}" : "\\tiogaxaxisnumericlabel{10^{%0.1f}}", val);
276
284
  else if (exponent == 0) strcpy(buff, "1");
277
285
  else if (exponent == 1) strcpy(buff, "10");
278
- else sprintf(buff, (s->vertical)? "\\tiogayaxisnumericlabel{10^{%d}}" : "\\tiogaxaxisnumericlabel{10^{%d}}", exponent);
286
+ else snprintf(buff, sizeof(buff), (s->vertical)? "\\tiogayaxisnumericlabel{10^{%d}}" : "\\tiogaxaxisnumericlabel{10^{%d}}", exponent);
279
287
  } else { /* Linear */
280
- char form[10];
281
288
  double scale2;
282
289
  int precis = s->numeric_label_decimal_digits; // use this precision if it is >= 0
283
290
  if (precis >= 0) prec = precis;
284
- if (scale) value /= pow(10.,(double)scale);
291
+ if (scale) val /= pow(10.,(double)scale);
285
292
  /* This is necessary to prevent labels like "-0.0" on some systems */
286
293
  scale2 = pow(10., prec);
287
- value = floor((value * scale2) + .5) / scale2;
288
- sprintf(form, (s->vertical)? "\\tiogayaxisnumericlabel{%%.%df}" : "\\tiogaxaxisnumericlabel{%%.%df}", (int) prec);
289
- sprintf(buff, form, value);
294
+ val = floor((val * scale2) + .5) / scale2;
295
+ snprintf(form, sizeof(form), (s->vertical)? "\\tiogayaxisnumericlabel{%%.%df}" : "\\tiogaxaxisnumericlabel{%%.%df}", (int) prec);
296
+ snprintf(buff, sizeof(buff), form, val);
290
297
  }
291
298
  int len = strlen(buff);
292
299
  if (postfix != NULL) { strcpy(buff+len, postfix); len = strlen(buff); }
293
- string = ALLOC_N(char, len+1);
300
+ string = ALLOC_N_char(len+1);
294
301
  strcpy(string, buff);
295
302
  return string;
296
303
  }
297
304
 
298
- char *Get_String(VALUE ary, int index) {
299
- VALUE string = rb_ary_entry(ary, index);
300
- return StringValuePtr(string);
305
+ char *Get_String(OBJ_PTR ary, int index, int *ierr) {
306
+ OBJ_PTR s = Array_Entry(ary,index,ierr);
307
+ if (*ierr != 0) return NULL;
308
+ return String_Ptr(s,ierr);
301
309
  }
302
310
 
303
311
  #define MAX_FIXDIG_POS 6
@@ -305,7 +313,7 @@ char *Get_String(VALUE ary, int index) {
305
313
  #define DIGMAX_DEF 6
306
314
 
307
315
  static void Pick_Label_Precision(double vmin, double vmax, double tick, bool use_fixed_pt,
308
- int *mode, int *prec, int digmax, int *scale) {
316
+ int *mode, int *prec, int digmax, int *scale, int *ierr) {
309
317
  double chosen, notchosen, vmod, t0, shifted;
310
318
  int msd, notmsd, np, digmin, digfix;
311
319
  *mode = *scale = 0;
@@ -383,23 +391,25 @@ static void Pick_Label_Precision(double vmin, double vmax, double tick, bool use
383
391
 
384
392
  }
385
393
 
386
- static char **Get_Labels(FM *p, PlotAxis *s)
394
+ static char **Get_Labels(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr)
387
395
  {
388
- char **labels = (char **)ALLOC_N(char *, s->nmajors);
396
+ char **labels = (char **)ALLOC_N_pointer(s->nmajors);
389
397
  char postfix[50], *ps;
390
398
  int i, k, j;
391
399
  k = s->numeric_label_frequency;
392
400
  j = s->numeric_label_phase;
393
- if (s->tick_labels==Qnil) { // create label strings
401
+ if (s->tick_labels==OBJ_NIL) { // create label strings
394
402
  int mode, prec, scale;
395
- Pick_Label_Precision(s->axis_min, s->axis_max, s->interval, s->use_fixed_pt, &mode, &prec, s->digits_max, &scale);
403
+ Pick_Label_Precision(s->axis_min, s->axis_max, s->interval,
404
+ s->use_fixed_pt, &mode, &prec, s->digits_max, &scale, ierr);
405
+ if (*ierr != 0) return NULL;
396
406
  int i;
397
407
  int upper_right = (s->reversed)? 0 : s->nmajors-1;
398
408
  int lower_left = (s->reversed)? s->nmajors-1 : 0;
399
409
  for (i = 0; i < s->nmajors; i++) {
400
410
  ps = NULL;
401
- if (i == upper_right && !s->log_values && mode && scale)
402
- sprintf(ps = postfix,
411
+ if (i == upper_right && !s->log_vals && mode && scale)
412
+ snprintf(ps = postfix, sizeof(postfix),
403
413
  (s->vertical)? "$\\times$\\tiogayaxisnumericlabel{10^{%d}}" : "$\\times$\\tiogaxaxisnumericlabel{10^{%d}}",
404
414
  scale);
405
415
  if ((i+j) % k != 0) {
@@ -410,23 +420,29 @@ static char **Get_Labels(FM *p, PlotAxis *s)
410
420
  s->other_axis_type == AXIS_WITH_TICKS_AND_NUMERIC_LABELS)) {
411
421
  labels[i] = NULL;
412
422
  } else {
413
- labels[i] = Create_Label(s->majors[i], scale, prec, s->log_values, s->use_fixed_pt, ps, s);
423
+ labels[i] = Create_Label(s->majors[i], scale, prec, s->log_vals, s->use_fixed_pt, ps, s, ierr);
424
+ if (*ierr != 0) return NULL;
414
425
  }
415
426
  }
416
427
  s->free_strings_for_labels = true;
417
428
  } else { // use the given label strings
418
- VALUE ary = rb_Array(s->tick_labels);
419
- if (RARRAY(ary)->len != s->nmajors)
420
- rb_raise(rb_eArgError, "Sorry: must have same number of labels as major ticks");
429
+ int len = Array_Len(s->tick_labels,ierr);
430
+ if (*ierr != 0) return NULL;
431
+ if (len != s->nmajors) {
432
+ RAISE_ERROR("Sorry: must have same number of labels as major ticks", ierr);
433
+ return NULL;
434
+ }
421
435
  for (i = 0; i < s->nmajors; i++) {
422
- labels[i] = Get_String(ary, i);
436
+ labels[i] = Get_String(s->tick_labels, i, ierr);
437
+ if (*ierr != 0) return NULL;
423
438
  }
424
439
  s->free_strings_for_labels = false;
425
440
  }
426
441
  return labels;
427
442
  }
428
443
 
429
- static double *Pick_Locations_for_Major_Ticks(double interval, double axis_min, double axis_max, int *num_locations)
444
+ static double *Pick_Locations_for_Major_Ticks(double interval,
445
+ double axis_min, double axis_max, int *num_locations, int *ierr)
430
446
  {
431
447
  double next_tick, prev_tick, starting_tick;
432
448
  double *majors;
@@ -445,7 +461,7 @@ static double *Pick_Locations_for_Major_Ticks(double interval, double axis_min,
445
461
  if (nmajors > 1) break;
446
462
  interval *= 0.5;
447
463
  }
448
- majors = ALLOC_N(double, nmajors);
464
+ majors = ALLOC_N_double(nmajors);
449
465
  prev_tick = starting_tick;
450
466
  for (i=0; i < nmajors; i++) {
451
467
  majors[i] = prev_tick += interval;
@@ -454,7 +470,7 @@ static double *Pick_Locations_for_Major_Ticks(double interval, double axis_min,
454
470
  return majors;
455
471
  }
456
472
 
457
- static int Pick_Number_of_Minor_Intervals(double length)
473
+ static int Pick_Number_of_Minor_Intervals(double length, int *ierr)
458
474
  {
459
475
  double t1, fuzz, newlen;
460
476
  int np, num_subintervals, inewlen;
@@ -482,7 +498,8 @@ static int Pick_Number_of_Minor_Intervals(double length)
482
498
  return num_subintervals;
483
499
  }
484
500
 
485
- static void Pick_Major_Tick_Interval(FM *p, double tick_min, double tick_gap, double length, bool log_values, double *tick)
501
+ static void Pick_Major_Tick_Interval(OBJ_PTR fmkr, FM *p,
502
+ double tick_min, double tick_gap, double length, bool log_vals, double *tick, int *ierr)
486
503
  {
487
504
  double t1, t2, tick_reasonable, base_interval;
488
505
  int np, i;
@@ -497,7 +514,7 @@ static void Pick_Major_Tick_Interval(FM *p, double tick_min, double tick_gap, do
497
514
  else if (t1 > 1.5) { t2 = 5.0; np--; }
498
515
  else { t2 = 2.0; np--; }
499
516
  /* Now compute reasonable tick spacing */
500
- if (log_values) {
517
+ if (log_vals) {
501
518
  tick_reasonable = 1.0;
502
519
  } else {
503
520
  base_interval = pow(10.0, (double) np);
@@ -513,17 +530,19 @@ static void Pick_Major_Tick_Interval(FM *p, double tick_min, double tick_gap, do
513
530
  else { // check the given interval compared to the default
514
531
  *tick = ABS(*tick);
515
532
  if(*tick < 1.e-4*tick_reasonable) {
516
- rb_raise(rb_eArgError, "Sorry: magnitude of specified tick interval (%g) is too small", *tick);
533
+ RAISE_ERROR_g("Sorry: magnitude of specified tick interval (%g) is too small", *tick, ierr);
534
+ return;
517
535
  }
518
536
  }
519
537
  }
520
538
 
521
- static void draw_major_ticks(FM *p, PlotAxis *s)
539
+ static void draw_major_ticks(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr)
522
540
  {
523
541
  s->num_minors = s->number_of_minor_intervals;
524
- if (s->locations_for_major_ticks != Qnil) {
542
+ if (s->locations_for_major_ticks != OBJ_NIL) {
525
543
  long len;
526
- s->majors = Dvector_Data_for_Read(s->locations_for_major_ticks, &len);
544
+ s->majors = Vector_Data_for_Read(s->locations_for_major_ticks, &len, ierr);
545
+ if (*ierr != 0) return;
527
546
  s->nmajors = len;
528
547
  if (len > 1) {
529
548
  s->interval = s->majors[1] - s->majors[0];
@@ -534,8 +553,10 @@ static void draw_major_ticks(FM *p, PlotAxis *s)
534
553
  double height = ((s->vertical)? p->default_text_height_dy : p->default_text_height_dx);
535
554
  double tick_min = s->min_between_major_ticks * height;
536
555
  double tick_gap = 10.0 * height;
537
- Pick_Major_Tick_Interval(p, tick_min, tick_gap, s->length, s->log_values, &s->interval);
538
- s->majors = Pick_Locations_for_Major_Ticks(s->interval, s->axis_min, s->axis_max, &s->nmajors);
556
+ Pick_Major_Tick_Interval(fmkr, p, tick_min, tick_gap, s->length, s->log_vals, &s->interval, ierr);
557
+ if (*ierr != 0) return;
558
+ s->majors = Pick_Locations_for_Major_Ticks(s->interval, s->axis_min, s->axis_max, &s->nmajors, ierr);
559
+ if (*ierr != 0) return;
539
560
  s->free_majors = true;
540
561
  }
541
562
  int i;
@@ -545,51 +566,64 @@ static void draw_major_ticks(FM *p, PlotAxis *s)
545
566
  if (s->ticks_inside) inside = length;
546
567
  if (s->ticks_outside) outside = length;
547
568
  if (s->top_or_right) { inside = -inside; outside = -outside; }
548
- if (s->line_width != s->major_tick_width)
549
- c_line_width_set(p, s->line_width = s->major_tick_width);
569
+ if (s->line_width != s->major_tick_width) {
570
+ c_line_width_set(fmkr, p, s->line_width = s->major_tick_width, ierr);
571
+ if (*ierr != 0) return;
572
+ }
550
573
  for (i=0; i < s->nmajors; i++) {
551
574
  if (s->vertical)
552
- figure_join(p, s->x0+inside, s->majors[i], s->x0+outside, s->majors[i]);
575
+ figure_join(fmkr, p, s->x0+inside, s->majors[i], s->x0+outside, s->majors[i], ierr);
553
576
  else
554
- figure_join(p, s->majors[i], s->y0+inside, s->majors[i], s->y0+outside);
577
+ figure_join(fmkr, p, s->majors[i], s->y0+inside, s->majors[i], s->y0+outside, ierr);
555
578
  did_line = true;
579
+ if (*ierr != 0) return;
556
580
  }
557
- if (did_line) axis_stroke(p);
581
+ if (did_line) axis_stroke(fmkr,p, ierr);
558
582
  }
559
583
 
560
- static double log_subintervals[8] =
561
- {
562
- 0.301030, 0.477121, 0.602060, 0.698970,
563
- 0.778151, 0.845098, 0.903090, 0.954243
564
- };
565
-
566
- static void draw_minor_ticks(FM *p, PlotAxis *s)
584
+ static void draw_minor_ticks(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr)
567
585
  {
568
586
  if (s->number_of_minor_intervals <= 0) {
569
- if (s->log_values) {
587
+ if (s->log_vals) {
570
588
  double interval = s->majors[1] - s->majors[0];
571
589
  s->number_of_minor_intervals = (abs(interval) != 1.0 || s->nmajors > 10)? 1 : 9;
572
- } else s->number_of_minor_intervals = Pick_Number_of_Minor_Intervals(s->interval);
590
+ } else {
591
+ s->number_of_minor_intervals = Pick_Number_of_Minor_Intervals(s->interval, ierr);
592
+ if (*ierr != 0) return;
593
+ }
573
594
  }
574
595
  int i, j, nsub = s->number_of_minor_intervals;
575
596
  double inside=0.0, outside=0.0, length;
576
597
  bool did_line = false;
577
- if (s->log_values && nsub > 9) nsub = 9;
598
+ double log_subintervals[8];
599
+ log_subintervals[0] = 0.301030;
600
+ log_subintervals[1] = 0.477121;
601
+ log_subintervals[2] = 0.602060;
602
+ log_subintervals[3] = 0.698970;
603
+ log_subintervals[4] = 0.778151;
604
+ log_subintervals[5] = 0.845098;
605
+ log_subintervals[6] = 0.903090;
606
+ log_subintervals[7] = 0.954243;
607
+ if (s->log_vals && nsub > 9) nsub = 9;
578
608
  length = s->minor_tick_length * ((s->vertical)? p->default_text_height_dx : p->default_text_height_dy);
579
609
  if (s->ticks_inside) inside = length;
580
610
  if (s->ticks_outside) outside = length;
581
611
  if (s->top_or_right) { inside = -inside; outside = -outside; }
582
- if (s->line_width != s->minor_tick_width)
583
- c_line_width_set(p, s->line_width = s->minor_tick_width);
584
- if (s->locations_for_minor_ticks != Qnil) {
612
+ if (s->line_width != s->minor_tick_width) {
613
+ c_line_width_set(fmkr, p, s->line_width = s->minor_tick_width, ierr);
614
+ if (*ierr != 0) return;
615
+ }
616
+ if (s->locations_for_minor_ticks != OBJ_NIL) {
585
617
  long cnt;
586
- double *locs = Dvector_Data_for_Read(s->locations_for_minor_ticks, &cnt);
618
+ double *locs = Vector_Data_for_Read(s->locations_for_minor_ticks, &cnt, ierr);
619
+ if (*ierr != 0) return;
587
620
  for (i=0; i < cnt; i++) {
588
621
  if (s->vertical)
589
- figure_join(p, s->x0+inside, locs[i], s->x0+outside, locs[i]);
622
+ figure_join(fmkr, p, s->x0+inside, locs[i], s->x0+outside, locs[i], ierr);
590
623
  else
591
- figure_join(p, locs[i], s->y0+inside, locs[i], s->y0+outside);
624
+ figure_join(fmkr, p, locs[i], s->y0+inside, locs[i], s->y0+outside, ierr);
592
625
  did_line = true;
626
+ if (*ierr != 0) return;
593
627
  }
594
628
  } else {
595
629
  for (i=0; i <= s->nmajors; i++) {
@@ -598,54 +632,66 @@ static void draw_minor_ticks(FM *p, PlotAxis *s)
598
632
  double subinterval = (next_loc - loc) / nsub;
599
633
  if (subinterval <= 0.0) continue;
600
634
  for (j = 1; j < nsub; j++) {
601
- double subloc = loc + ((!s->log_values) ? (j * subinterval) : log_subintervals[j-1]);
635
+ double subloc = loc + ((!s->log_vals) ? (j * subinterval) : log_subintervals[j-1]);
602
636
  if (subloc >= next_loc) break;
603
637
  if (subloc <= s->axis_min || subloc >= s->axis_max) continue;
604
638
  if (s->vertical)
605
- figure_join(p, s->x0+inside, subloc, s->x0+outside, subloc);
639
+ figure_join(fmkr, p, s->x0+inside, subloc, s->x0+outside, subloc, ierr);
606
640
  else
607
- figure_join(p, subloc, s->y0+inside, subloc, s->y0+outside);
641
+ figure_join(fmkr, p, subloc, s->y0+inside, subloc, s->y0+outside, ierr);
608
642
  did_line = true;
643
+ if (*ierr != 0) return;
609
644
  }
610
645
  }
611
646
  }
612
- if (did_line) axis_stroke(p);
647
+ if (did_line) axis_stroke(fmkr,p, ierr);
613
648
  }
614
649
 
615
- static void show_numeric_label(FM *p , VALUE fmkr, PlotAxis *s, char *text, int location, double position, double shift)
650
+ static void show_numeric_label(OBJ_PTR fmkr, FM *p, PlotAxis *s,
651
+ char *text, int location, double position, double shift, int *ierr)
616
652
  { // position is in figure coords and must be converted to frame coords
617
653
  double pos = ((!s->reversed)? (position - s->axis_min) : (s->axis_max - position)) / s->length;
618
- c_show_rotated_text(p, text, location, shift, pos,
619
- s->numeric_label_scale, s->numeric_label_angle, s->numeric_label_justification, s->numeric_label_alignment);
654
+ c_show_rotated_text(fmkr, p, text, location, shift, pos,
655
+ s->numeric_label_scale, s->numeric_label_angle, s->numeric_label_justification, s->numeric_label_alignment, OBJ_NIL, ierr);
620
656
  }
621
657
 
622
- static void draw_numeric_labels(FM *p , VALUE fmkr, int location, PlotAxis *s)
658
+ static void draw_numeric_labels(OBJ_PTR fmkr, FM *p, int location, PlotAxis *s, int *ierr)
623
659
  {
624
660
  int i;
625
661
  double shift = (s->ticks_outside) ? s->major_tick_length : 0.5; // default shift
626
662
  shift += s->numeric_label_shift;
627
- s->labels = Get_Labels(p, s);
663
+ s->labels = Get_Labels(fmkr, p, s, ierr);
628
664
  for (i=0; i < s->nmajors; i++) {
629
- if (s->labels[i] != NULL) show_numeric_label(p, fmkr, s, s->labels[i], location, s->majors[i], shift);
665
+ if (s->labels[i] != NULL) {
666
+ show_numeric_label(fmkr, p, s, s->labels[i], location, s->majors[i], shift, ierr);
667
+ if (*ierr != 0) return;
668
+ }
630
669
  }
631
670
  }
632
671
 
633
- static void c_show_side(VALUE fmkr, FM *p, PlotAxis *s) {
672
+ static void c_show_side(OBJ_PTR fmkr, FM *p, PlotAxis *s, int *ierr) {
634
673
  int i;
635
674
  if (s->type == AXIS_HIDDEN) return;
636
- Start_Axis_Standard_State(p, s->stroke_color, s->line_width * p->default_line_scale);
637
- // gsave, set line type and stroke color
638
- draw_axis_line(p, s->location, s);
675
+ Start_Axis_Standard_State(fmkr, p,
676
+ s->stroke_color_R, s->stroke_color_G, s->stroke_color_B,
677
+ s->line_width * p->default_line_scale, ierr);
678
+ if (*ierr != 0) return;
679
+ draw_axis_line(fmkr, p, s->location, s, ierr);
680
+ if (*ierr != 0) return;
639
681
  if (s->type == AXIS_LINE_ONLY) goto done;
640
- draw_major_ticks(p, s);
682
+ draw_major_ticks(fmkr, p, s, ierr);
683
+ if (*ierr != 0) return;
641
684
  if (s->type == AXIS_WITH_MAJOR_TICKS_ONLY) goto done;
642
685
  if (s->type == AXIS_WITH_MAJOR_TICKS_AND_NUMERIC_LABELS) {
643
- draw_numeric_labels(p, fmkr, s->location, s);
686
+ draw_numeric_labels(fmkr, p, s->location, s, ierr);
687
+ if (*ierr != 0) return;
644
688
  goto done;
645
689
  }
646
- draw_minor_ticks(p, s);
690
+ draw_minor_ticks(fmkr, p, s, ierr);
691
+ if (*ierr != 0) return;
647
692
  if (s->type == AXIS_WITH_TICKS_ONLY) goto done;
648
- draw_numeric_labels(p, fmkr, s->location, s);
693
+ draw_numeric_labels(fmkr, p, s->location, s, ierr);
694
+ if (*ierr != 0) return;
649
695
  done:
650
696
  End_Axis_Standard_State(); // grestore
651
697
  if (s->free_majors) free(s->majors);
@@ -658,128 +704,95 @@ static void c_show_side(VALUE fmkr, FM *p, PlotAxis *s) {
658
704
  }
659
705
  }
660
706
 
661
- VALUE FM_show_axis(VALUE fmkr, VALUE loc)
707
+
708
+ void c_show_axis(OBJ_PTR fmkr, FM *p, int location, int *ierr)
662
709
  {
663
- FM *p = Get_FM(fmkr);
664
710
  PlotAxis axis;
665
- int location;
666
- Init_PlotAxis_struct(&axis);
667
- loc = rb_Integer(loc);
668
- location = NUM2INT(loc);
669
711
  if (location == LEFT || location == RIGHT || location == AT_X_ORIGIN) {
670
- if (!p->yaxis_visible) goto done;
671
- Get_yaxis_Specs(p, &axis);
712
+ if (!p->yaxis_visible) return;
713
+ Get_yaxis_Specs(fmkr, p, &axis, ierr);
672
714
  } else if (location == TOP || location == BOTTOM || location == AT_Y_ORIGIN) {
673
- if (!p->xaxis_visible) goto done;
674
- Get_xaxis_Specs(p, &axis);
675
- } else rb_raise(rb_eArgError,
676
- "Sorry: invalid 'loc' for axis: must be one of LEFT, RIGHT, TOP, BOTTOM, AT_X_ORIGIN, or AT_Y_ORIGIN: is (%i)", location);
715
+ if (!p->xaxis_visible) return;
716
+ Get_xaxis_Specs(fmkr, p, &axis, ierr);
717
+ } else RAISE_ERROR_i(
718
+ "Sorry: invalid 'loc' for axis: must be one of LEFT, RIGHT, TOP, BOTTOM, AT_X_ORIGIN, or AT_Y_ORIGIN: is (%i)", location, ierr);
719
+ if (*ierr != 0) return;
677
720
  axis.location = location;
678
- c_show_side(fmkr, p, &axis);
679
- done:
680
- return fmkr;
721
+ c_show_side(fmkr, p, &axis, ierr);
681
722
  }
682
723
 
683
- VALUE FM_show_edge(VALUE fmkr, VALUE loc) {
684
- FM *p = Get_FM(fmkr);
724
+ void c_show_edge(OBJ_PTR fmkr, FM *p, int location, int *ierr)
725
+ {
685
726
  PlotAxis axis;
686
- int location;
687
- Init_PlotAxis_struct(&axis);
688
- loc = rb_Integer(loc);
689
- location = NUM2INT(loc);
690
727
  switch (location) {
691
728
  case LEFT:
692
- if (!p->left_edge_visible) goto done;
693
- Get_yaxis_Specs(p, &axis); axis.type = p->left_edge_type;
729
+ if (!p->left_edge_visible) return;
730
+ Get_yaxis_Specs(fmkr, p, &axis, ierr); axis.type = p->left_edge_type;
694
731
  break;
695
732
  case RIGHT:
696
- if (!p->right_edge_visible) goto done;
697
- Get_yaxis_Specs(p, &axis); axis.type = p->right_edge_type;
733
+ if (!p->right_edge_visible) return;
734
+ Get_yaxis_Specs(fmkr, p, &axis, ierr); axis.type = p->right_edge_type;
698
735
  break;
699
736
  case BOTTOM:
700
- if (!p->bottom_edge_visible) goto done;
701
- Get_xaxis_Specs(p, &axis); axis.type = p->bottom_edge_type;
737
+ if (!p->bottom_edge_visible) return;
738
+ Get_xaxis_Specs(fmkr, p, &axis, ierr); axis.type = p->bottom_edge_type;
702
739
  break;
703
740
  case TOP:
704
- if (!p->top_edge_visible) goto done;
705
- Get_xaxis_Specs(p, &axis); axis.type = p->top_edge_type;
741
+ if (!p->top_edge_visible) return;
742
+ Get_xaxis_Specs(fmkr, p, &axis, ierr); axis.type = p->top_edge_type;
706
743
  break;
707
- default: rb_raise(rb_eArgError,
708
- "Sorry: invalid 'loc' for edge: must be one of LEFT, RIGHT, TOP, or BOTTOM: is (%i)", location);
744
+ default:
745
+ RAISE_ERROR_i(
746
+ "Sorry: invalid 'loc' for edge: must be one of LEFT, RIGHT, TOP, or BOTTOM: is (%i)", location, ierr);
709
747
  }
748
+ if (*ierr != 0) return;
710
749
  axis.location = location;
711
- c_show_side(fmkr, p, &axis);
712
- done:
713
- return fmkr;
750
+ c_show_side(fmkr, p, &axis, ierr);
714
751
  }
715
752
 
716
753
 
717
- VALUE FM_no_title(VALUE fmkr)
754
+ void c_no_title(OBJ_PTR fmkr, FM *p, int *ierr)
718
755
  {
719
- FM *p = Get_FM(fmkr);
720
756
  p->title_visible = false;
721
- return fmkr;
722
757
  }
723
758
 
724
- VALUE FM_no_xlabel(VALUE fmkr)
759
+ void c_no_xlabel(OBJ_PTR fmkr, FM *p, int *ierr)
725
760
  {
726
- FM *p = Get_FM(fmkr);
727
761
  p->xlabel_visible = false;
728
- return fmkr;
729
762
  }
730
763
 
731
-
732
- VALUE FM_no_ylabel(VALUE fmkr)
764
+ void c_no_ylabel(OBJ_PTR fmkr, FM *p, int *ierr)
733
765
  {
734
- FM *p = Get_FM(fmkr);
735
766
  p->ylabel_visible = false;
736
- return fmkr;
737
767
  }
738
768
 
739
-
740
- VALUE FM_no_xaxis(VALUE fmkr)
769
+ void c_no_xaxis(OBJ_PTR fmkr, FM *p, int *ierr)
741
770
  {
742
- FM *p = Get_FM(fmkr);
743
771
  p->xaxis_visible = false;
744
- return fmkr;
745
772
  }
746
773
 
747
-
748
- VALUE FM_no_yaxis(VALUE fmkr)
774
+ void c_no_yaxis(OBJ_PTR fmkr, FM *p, int *ierr)
749
775
  {
750
- FM *p = Get_FM(fmkr);
751
776
  p->yaxis_visible = false;
752
- return fmkr;
753
777
  }
754
778
 
755
-
756
- VALUE FM_no_left_edge(VALUE fmkr)
779
+ void c_no_left_edge(OBJ_PTR fmkr, FM *p, int *ierr)
757
780
  {
758
- FM *p = Get_FM(fmkr);
759
781
  p->left_edge_visible = false;
760
- return fmkr;
761
782
  }
762
783
 
763
-
764
- VALUE FM_no_right_edge(VALUE fmkr)
784
+ void c_no_right_edge(OBJ_PTR fmkr, FM *p, int *ierr)
765
785
  {
766
- FM *p = Get_FM(fmkr);
767
786
  p->right_edge_visible = false;
768
- return fmkr;
769
787
  }
770
788
 
771
-
772
- VALUE FM_no_top_edge(VALUE fmkr)
789
+ void c_no_top_edge(OBJ_PTR fmkr, FM *p, int *ierr)
773
790
  {
774
- FM *p = Get_FM(fmkr);
775
791
  p->top_edge_visible = false;
776
- return fmkr;
777
792
  }
778
793
 
779
- VALUE FM_no_bottom_edge(VALUE fmkr)
794
+ void c_no_bottom_edge(OBJ_PTR fmkr, FM *p, int *ierr)
780
795
  {
781
- FM *p = Get_FM(fmkr);
782
796
  p->bottom_edge_visible = false;
783
- return fmkr;
784
797
  }
785
798