tioga 1.6 → 1.7
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.
- data/Tioga_README +35 -10
- data/split/Dvector/dvector.c +264 -22
- data/split/Dvector/lib/Dvector_extras.rb +30 -2
- data/split/Flate/extconf.rb +1 -1
- data/split/Function/function.c +112 -2
- data/split/Tioga/figures.c +76 -77
- data/split/Tioga/figures.h +375 -490
- data/split/Tioga/generic.c +254 -0
- data/split/Tioga/generic.h +236 -0
- data/split/Tioga/init.c +434 -320
- data/split/Tioga/lib/Creating_Paths.rb +11 -1
- data/split/Tioga/lib/FigMkr.rb +263 -65
- data/split/Tioga/lib/Legends.rb +4 -2
- data/split/Tioga/lib/Markers.rb +3 -2
- data/split/Tioga/lib/Special_Paths.rb +22 -23
- data/split/Tioga/lib/TeX_Text.rb +79 -1
- data/split/Tioga/lib/TexPreamble.rb +14 -0
- data/split/Tioga/lib/Utils.rb +5 -1
- data/split/Tioga/pdfs.h +7 -45
- data/split/Tioga/{axes.c → shared/axes.c} +210 -197
- data/split/Tioga/{makers.c → shared/makers.c} +442 -211
- data/split/Tioga/{pdf_font_dicts.c → shared/pdf_font_dicts.c} +0 -0
- data/split/Tioga/shared/pdfcolor.c +628 -0
- data/split/Tioga/shared/pdfcoords.c +443 -0
- data/split/Tioga/{pdffile.c → shared/pdffile.c} +56 -52
- data/split/Tioga/{pdfimage.c → shared/pdfimage.c} +103 -211
- data/split/Tioga/shared/pdfpath.c +766 -0
- data/split/Tioga/{pdftext.c → shared/pdftext.c} +121 -99
- data/split/Tioga/shared/texout.c +524 -0
- data/split/Tioga/wrappers.c +489 -0
- data/split/Tioga/wrappers.h +259 -0
- data/split/extconf.rb +4 -0
- data/split/mkmf2.rb +12 -1
- data/tests/benchmark_dvector_reads.rb +112 -0
- data/tests/tc_Dvector.rb +35 -3
- data/tests/tc_Function.rb +32 -0
- metadata +65 -52
- data/split/Tioga/pdfcolor.c +0 -486
- data/split/Tioga/pdfcoords.c +0 -523
- data/split/Tioga/pdfpath.c +0 -913
- data/split/Tioga/texout.c +0 -380
data/split/Tioga/lib/Legends.rb
CHANGED
@@ -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,
|
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)
|
data/split/Tioga/lib/Markers.rb
CHANGED
@@ -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
|
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>
|
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
|
-
|
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
|
23
|
-
'dest_ys' => a_dvector # The contour y values will be placed in this
|
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
|
-
|
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(
|
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(
|
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.
|
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 =
|
147
|
-
|
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)
|
data/split/Tioga/lib/TeX_Text.rb
CHANGED
@@ -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'
|
data/split/Tioga/lib/Utils.rb
CHANGED
@@ -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
|
data/split/Tioga/pdfs.h
CHANGED
@@ -24,18 +24,9 @@
|
|
24
24
|
|
25
25
|
#include <namespace.h>
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
extern
|
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
|
-
|
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
|
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
|
-
|
40
|
-
|
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
|
-
|
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
|
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,
|
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
|
-
|
89
|
+
c_stroke(fmkr,p, ierr);
|
95
90
|
}
|
96
91
|
|
97
|
-
void figure_join_and_stroke(FM *p,
|
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
|
-
|
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->
|
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->
|
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 =
|
120
|
-
s->locations_for_minor_ticks =
|
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 =
|
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->
|
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->
|
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 =
|
151
|
-
s->locations_for_minor_ticks =
|
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
|
254
|
-
|
255
|
-
|
256
|
-
|
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 (
|
259
|
-
double sav_val =
|
260
|
-
|
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
|
-
|
266
|
-
|
267
|
-
} else if (abs(
|
268
|
-
|
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
|
-
|
278
|
+
snprintf(buff, sizeof(buff), (s->vertical)? "\\tiogayaxisnumericlabel{%d}" : "\\tiogaxaxisnumericlabel{%d}", (int) val);
|
271
279
|
}
|
272
|
-
} else if (
|
280
|
+
} else if (log_vals) {
|
273
281
|
/* Exponential, i.e. 10^-1, 1, 10, 10^2, etc */
|
274
|
-
double abs_diff = fabs(
|
275
|
-
if (abs_diff > 0.1)
|
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
|
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)
|
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
|
-
|
288
|
-
|
289
|
-
|
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 =
|
300
|
+
string = ALLOC_N_char(len+1);
|
294
301
|
strcpy(string, buff);
|
295
302
|
return string;
|
296
303
|
}
|
297
304
|
|
298
|
-
char *Get_String(
|
299
|
-
|
300
|
-
|
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 **)
|
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==
|
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,
|
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->
|
402
|
-
|
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->
|
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
|
-
|
419
|
-
if (
|
420
|
-
|
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(
|
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,
|
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 =
|
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,
|
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 (
|
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
|
-
|
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 !=
|
542
|
+
if (s->locations_for_major_ticks != OBJ_NIL) {
|
525
543
|
long len;
|
526
|
-
s->majors =
|
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->
|
538
|
-
|
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
|
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->
|
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
|
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
|
-
|
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
|
-
|
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 =
|
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->
|
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
|
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
|
-
|
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
|
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)
|
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(
|
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(
|
637
|
-
|
638
|
-
|
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(
|
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(
|
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
|
-
|
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)
|
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)
|
674
|
-
Get_xaxis_Specs(p, &axis);
|
675
|
-
} else
|
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
|
-
|
684
|
-
|
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)
|
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)
|
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)
|
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)
|
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:
|
708
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
|