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
@@ -23,10 +23,20 @@ class Creating_Paths < Doc < FigureMaker
23
23
  def append_point_to_path(x, y)
24
24
  end
25
25
 
26
+
27
+ # Computes bezier control points corresponding to a given cubic.
28
+ # The cubic, y(x), is defined from x0 to x0+delta_x.
29
+ # At location x = x0 + dx, with dx between 0 and delta_x, define y = a*dx^3 + b*dx^2 + c*dx + y0.
30
+ # This routine returns [x1, y1, x2, y2, x3, y3], the Bezier control points to match this cubic.
31
+
32
+ def bezier_control_points(x0, y0, delta_x, a, b, c)
33
+ end
34
+
35
+
26
36
  # Append a cubic Bezier curve to the current path. The curve extends from the current
27
37
  # path end to the point given by the figure coordinates (x3, y3), using (x1, y1) and
28
38
  # (x2, y2) as the Bezier control points (also in figure coordinates). The new path
29
- # end is (x3, y3).
39
+ # end is (x3, y3). See also bezier_control_points.
30
40
  #
31
41
  # The illustration shows in dark blue the curve that is added for the control points given in red.
32
42
  #
@@ -21,6 +21,7 @@
21
21
  =end
22
22
 
23
23
  require 'Tioga/FigureConstants.rb'
24
+ require 'Tioga/Utils.rb'
24
25
 
25
26
  module Tioga
26
27
  class FigureMaker
@@ -30,21 +31,20 @@ class FigureMaker
30
31
  @@default_figure_maker = nil
31
32
  @@which_pdflatex = nil
32
33
  @@initialized = false # set true by the C code when first make a figure
33
-
34
34
 
35
- # The tag used for cvs export
36
- CVS_TAG = "rel_1_6" # now manually cheating...
37
-
38
- # Version now uses the CVS_TAG to create the version number. CVS_TAG should
39
- # look like 'rel_1_1_0' for the 1.1.0 release.
35
+ # This URL will contain tioga-(...) when it is exported from the
36
+ # SVN repository. This is where we'll look for version information.
37
+ SVN_URL = '$HeadURL: svn+ssh://rubyforge.org/var/svn/tioga/tags/tioga/Tioga%201.7/split/Tioga/lib/FigMkr.rb $'
38
+
39
+ TIOGA_VERSION = if SVN_URL =~ /tags\/tioga\/Tioga%20([^\/]+)/
40
+ $1
41
+ else
42
+ "SVN version"
43
+ end
44
+
45
+
40
46
  def FigureMaker.version
41
- CVS_TAG =~ /\D+(.*?)\s*\$?$/
42
- version = $1.tr("-_", "..")
43
- if version.length > 0
44
- return version
45
- else
46
- return "SVN $Revision: 385 $" # Can't do better than that.
47
- end
47
+ TIOGA_VERSION
48
48
  end
49
49
 
50
50
 
@@ -58,12 +58,12 @@ class FigureMaker
58
58
  end
59
59
 
60
60
  def FigureMaker.pdflatex
61
- @@which_pdflatex = 'pdflatex' if @@which_pdflatex == nil
62
- @@which_pdflatex
61
+ @@which_pdflatex = 'pdflatex' if @@which_pdflatex == nil
62
+ @@which_pdflatex
63
63
  end
64
64
 
65
65
  def FigureMaker.pdflatex=(s)
66
- @@which_pdflatex = s
66
+ @@which_pdflatex = s
67
67
  end
68
68
 
69
69
 
@@ -73,10 +73,26 @@ class FigureMaker
73
73
  return dict
74
74
  end
75
75
 
76
+
77
+
78
+ attr_accessor :title
79
+ attr_accessor :xlabel
80
+ attr_accessor :ylabel
81
+
82
+ attr_accessor :xaxis_locations_for_major_ticks
83
+ attr_accessor :xaxis_locations_for_minor_ticks
84
+ attr_accessor :xaxis_tick_labels
85
+
86
+ attr_accessor :yaxis_locations_for_major_ticks
87
+ attr_accessor :yaxis_locations_for_minor_ticks
88
+ attr_accessor :yaxis_tick_labels
89
+
76
90
  attr_accessor :style_filename
77
91
 
78
92
  attr_accessor :legend_info
79
93
 
94
+ attr_reader :line_type
95
+
80
96
  attr_reader :num_figures
81
97
 
82
98
  attr_reader :figure_names
@@ -120,9 +136,10 @@ class FigureMaker
120
136
 
121
137
  # Whether or not do do multithreading for parallel pdflatex calls
122
138
  attr_accessor :multithreads_okay_for_tioga
123
-
124
-
125
-
139
+
140
+ # An accessor for @measures_info:
141
+ attr_accessor :measures_info
142
+
126
143
  # old preview attributes -- to be removed later
127
144
 
128
145
  attr_accessor :model_number
@@ -144,7 +161,6 @@ class FigureMaker
144
161
  #attr_accessor :tex_preview_figure_height
145
162
  #attr_accessor :tex_preview_minwhitespace
146
163
  #attr_accessor :tex_preview_fullpage
147
-
148
164
 
149
165
  def reset_figures # set the state to default values
150
166
  @figure_commands = []
@@ -190,6 +206,8 @@ class FigureMaker
190
206
 
191
207
  @num_error_lines = 10
192
208
 
209
+ reset_plot_attrs
210
+
193
211
  @tex_xoffset = 0
194
212
  @tex_yoffset = 0
195
213
 
@@ -252,14 +270,59 @@ class FigureMaker
252
270
 
253
271
  # multithreads by default
254
272
  @multithreads_okay_for_tioga = true
255
-
273
+
274
+
275
+ # The values of the sizes measured during the pdflatex run
276
+ # we need to keep track of them so we can decide how many times
277
+ # we'll run pdflatex.
278
+ @measures = {}
279
+
280
+ # We *must* initialize the measures_info hash.
281
+ @measures_info = {}
256
282
  end
283
+
257
284
 
258
- def initialize
285
+ def reset_plot_attrs
286
+ @title = nil
287
+ @xlabel = nil
288
+ @ylabel = nil
289
+ @line_type = nil
290
+ @xaxis_locations_for_major_ticks = nil
291
+ @xaxis_locations_for_minor_ticks = nil
292
+ @xaxis_tick_labels = nil
293
+ @yaxis_locations_for_major_ticks = nil
294
+ @yaxis_locations_for_minor_ticks = nil
295
+ @yaxis_tick_labels = nil
296
+ private_init_fm_data
297
+ end
298
+
299
+
300
+ def initialize
301
+ @fm_data = Dvector.new(@@fm_data_size)
259
302
  reset_figures
260
303
  end
261
304
 
262
305
 
306
+ # Returns informations about the size of the named element.
307
+ # Returns a hash:
308
+ # * 'width' : the width of the box in figure coordinates
309
+ # * 'height': the height of the box in figure coordinates
310
+ # * 'just' : the justification used
311
+ # * 'align' : the vertical alignment used
312
+ # * 'angle' : the angle used
313
+ # * 'scale' : the *total* scale used.
314
+ #
315
+ # If the measurement did not take place yet, the width, height,
316
+ # and other attributes will be missing. Look for those.
317
+ def get_text_size(name, default = 1.0)
318
+ if self.measures_info.key? name
319
+ return self.measures_info[name]
320
+ else
321
+ return {} # Empty hash
322
+ end
323
+ end
324
+
325
+
263
326
  def reset_state
264
327
  reset_figures
265
328
  end
@@ -351,6 +414,10 @@ class FigureMaker
351
414
  self.stroke_color=(color)
352
415
  end
353
416
 
417
+ def line_type=(val)
418
+ self.line_type_set(val)
419
+ end
420
+
354
421
  def stroke_width
355
422
  self.line_width
356
423
  end
@@ -590,11 +657,12 @@ class FigureMaker
590
657
  'alignment' => self.legend_alignment)
591
658
  end
592
659
  line_width = dict['line_width']
593
- if line_width >= 0
660
+ line_type = dict['line_type']
661
+ unless (line_width < 0) || ((line_type.kind_of?String) && (line_type.casecmp('none') == 0))
594
662
  self.line_color = dict['line_color']
595
663
  self.line_width = dict['line_width']
596
664
  self.line_cap = dict['line_cap']
597
- self.line_type = dict['line_type']
665
+ self.line_type = line_type
598
666
  stroke_line(line_x0, y+line_dy, line_x1, y+line_dy)
599
667
  end
600
668
  # place any marker right in the middle of the line
@@ -874,8 +942,38 @@ class FigureMaker
874
942
 
875
943
 
876
944
  def context(&cmd)
877
- trace_cmd_no_arg(@enter_context_function, @exit_context_function) {
878
- private_context(cmd) }
945
+ trace_cmd_no_arg(@enter_context_function, @exit_context_function) {
946
+
947
+ save_title = self.title
948
+ save_xlabel = self.xlabel
949
+ save_ylabel = self.ylabel
950
+ save_line_type = self.line_type
951
+ save_xaxis_locations_for_major_ticks = self.xaxis_locations_for_major_ticks
952
+ save_xaxis_locations_for_minor_ticks = self.xaxis_locations_for_minor_ticks
953
+ save_xaxis_tick_labels = self.xaxis_tick_labels
954
+ save_yaxis_locations_for_major_ticks = self.yaxis_locations_for_major_ticks
955
+ save_yaxis_locations_for_minor_ticks = self.yaxis_locations_for_minor_ticks
956
+ save_yaxis_tick_labels = self.yaxis_tick_labels
957
+ save_fm_data = Dvector.new(@@fm_data_size).replace(@fm_data)
958
+ pdf_gsave
959
+ begin
960
+ cmd.call
961
+ ensure
962
+ pdf_grestore
963
+ self.title = save_title
964
+ self.xlabel = save_xlabel
965
+ self.ylabel = save_ylabel
966
+ self.line_type = save_line_type
967
+ self.xaxis_locations_for_major_ticks = save_xaxis_locations_for_major_ticks
968
+ self.xaxis_locations_for_minor_ticks = save_xaxis_locations_for_minor_ticks
969
+ self.xaxis_tick_labels = save_xaxis_tick_labels
970
+ self.yaxis_locations_for_major_ticks = save_yaxis_locations_for_major_ticks
971
+ self.yaxis_locations_for_minor_ticks = save_yaxis_locations_for_minor_ticks
972
+ self.yaxis_tick_labels = save_yaxis_tick_labels
973
+ @fm_data.replace(save_fm_data)
974
+ end
975
+
976
+ }
879
977
  end
880
978
 
881
979
 
@@ -1023,8 +1121,8 @@ class FigureMaker
1023
1121
  if z_level == nil
1024
1122
  z_level = complain_if_missing_numeric_arg(dict, 'z', 'level', 'make_contour')
1025
1123
  end
1026
- dest_xs = get_dvec(dict, 'dest_xs', 'make_contour')
1027
- dest_ys = get_dvec(dict, 'dest_ys', 'make_contour')
1124
+ dest_xs = dict['dest_xs']
1125
+ dest_ys = dict['dest_ys']
1028
1126
  xs = get_dvec(dict, 'xs', 'make_contour')
1029
1127
  ys = get_dvec(dict, 'ys', 'make_contour')
1030
1128
  gaps = dict['gaps']
@@ -1035,7 +1133,9 @@ class FigureMaker
1035
1133
  if (!(zs.kind_of? Dtable))
1036
1134
  raise "Sorry: 'zs' for 'make_contour' must be a Dtable"
1037
1135
  end
1038
- dest_xs.clear; dest_ys.clear; gaps.clear
1136
+ dest_xs.clear unless dest_xs == nil
1137
+ dest_ys.clear unless dest_ys == nil
1138
+ gaps.clear
1039
1139
 
1040
1140
  legit = dict['legit']
1041
1141
  if legit == nil
@@ -1046,8 +1146,18 @@ class FigureMaker
1046
1146
 
1047
1147
  method = dict['method']
1048
1148
  use_conrec = (method == 'conrec' or method == 'CONREC')? 1 : 0
1049
- private_make_contour(dest_xs, dest_ys, gaps, xs, ys, zs, z_level, legit, use_conrec)
1149
+ pts_array = private_make_contour(gaps, xs, ys, zs, z_level, legit, use_conrec)
1050
1150
 
1151
+ unless dest_xs == nil
1152
+ dest_xs.resize(pts_array[0].size)
1153
+ dest_xs.replace(pts_array[0])
1154
+ end
1155
+ unless dest_ys == nil
1156
+ dest_ys.resize(pts_array[1].size)
1157
+ dest_ys.replace(pts_array[1])
1158
+ end
1159
+ return pts_array
1160
+
1051
1161
  end
1052
1162
 
1053
1163
  @@keys_for_make_steps = FigureMaker.make_name_lookup_hash([
@@ -1059,11 +1169,20 @@ class FigureMaker
1059
1169
  yfirst = complain_if_missing_numeric_arg(dict, 'yfirst', 'y_first', 'make_steps')
1060
1170
  xlast = complain_if_missing_numeric_arg(dict, 'xlast', 'x_last', 'make_steps')
1061
1171
  ylast = complain_if_missing_numeric_arg(dict, 'ylast', 'y_last', 'make_steps')
1062
- dest_xs = get_dvec(dict, 'dest_xs', 'make_steps')
1063
- dest_ys = get_dvec(dict, 'dest_ys', 'make_steps')
1172
+ dest_xs = dict['dest_xs']
1173
+ dest_ys = dict['dest_ys']
1064
1174
  xs = get_dvec(dict, 'xs', 'make_steps')
1065
1175
  ys = get_dvec(dict, 'ys', 'make_steps')
1066
- private_make_steps(dest_xs, dest_ys, xs, ys, xfirst, yfirst, xlast, ylast)
1176
+ pts_array = private_make_steps(xs, ys, xfirst, yfirst, xlast, ylast)
1177
+ unless dest_xs == nil
1178
+ dest_xs.resize(pts_array[0].size)
1179
+ dest_xs.replace(pts_array[0])
1180
+ end
1181
+ unless dest_ys == nil
1182
+ dest_ys.resize(pts_array[1].size)
1183
+ dest_ys.replace(pts_array[1])
1184
+ end
1185
+ return pts_array
1067
1186
  end
1068
1187
 
1069
1188
  @@keys_for_make_curves = FigureMaker.make_name_lookup_hash([
@@ -1073,10 +1192,15 @@ class FigureMaker
1073
1192
  start_slope = dict['start_slope']
1074
1193
  end_slope = dict['end_slope']
1075
1194
  sample_xs = get_dvec(dict, 'sample_xs', 'make_spline_interpolated_points')
1076
- result_ys = get_dvec(dict, 'result_ys', 'make_spline_interpolated_points')
1077
1195
  xs = get_dvec(dict, 'xs', 'make_spline_interpolated_points')
1078
1196
  ys = get_dvec(dict, 'ys', 'make_spline_interpolated_points')
1079
- private_make_spline_interpolated_points(sample_xs, result_ys, xs, ys, start_slope, end_slope)
1197
+ yvec = private_make_spline_interpolated_points(sample_xs, xs, ys, start_slope, end_slope)
1198
+ result_ys = dict['result_ys']
1199
+ unless result_ys == nil
1200
+ result_ys.resize(yvec.size)
1201
+ result_ys.replace(yvec)
1202
+ end
1203
+ return yvec
1080
1204
  end
1081
1205
 
1082
1206
  @@keys_for_make_interpolant = FigureMaker.make_name_lookup_hash([
@@ -1114,11 +1238,15 @@ class FigureMaker
1114
1238
  dx = dict['dx']
1115
1239
  dx_plus = get_if_given_else_default(dict, 'dx_plus', dx)
1116
1240
  dx_minus = get_if_given_else_default(dict, 'dx_minus', dx)
1241
+ dx_plus = 0 if dx_plus == nil
1242
+ dx_minus = 0 if dx_minus == nil
1117
1243
  dy = dict['dy']
1118
1244
  dy_plus = get_if_given_else_default(dict, 'dy_plus', dy)
1119
1245
  dy_minus = get_if_given_else_default(dict, 'dy_minus', dy)
1120
- if (dx_plus == nil || dx_minus == nil || dy_plus == nil || dy_minus == nil)
1121
- raise "Sorry: Must give both 'dx' and 'dy' error ranges for show_error_bar."
1246
+ dy_plus = 0 if dy_plus == nil
1247
+ dy_minus = 0 if dy_minus == nil
1248
+ if (dx_plus == 0 && dy_minus == 0)
1249
+ raise "Sorry: Must give either or both 'dx' and 'dy' error ranges for show_error_bar."
1122
1250
  end
1123
1251
  end_cap = get_if_given_else_default(dict, 'end_cap', 0.15) # end_cap length in default text heights
1124
1252
  x_end_cap = end_cap * self.default_text_height_dy
@@ -1459,7 +1587,7 @@ class FigureMaker
1459
1587
  end
1460
1588
 
1461
1589
  @@keys_for_show_marker = FigureMaker.make_name_lookup_hash([
1462
- 'marker', 'x', 'y', 'at', 'point', 'Xs', 'Ys', 'xs', 'ys', 'mode', 'rendering_mode',
1590
+ 'marker', 'x', 'y', 'at', 'point', 'Xs', 'Ys', 'xs', 'ys', 'mode', 'rendering_mode', 'legend',
1463
1591
  'angle', 'scale', 'font', 'string', 'text', 'color', 'fill_color', 'stroke_color', 'stroke_width',
1464
1592
  'horizontal_scale', 'vertical_scale', 'italic_angle', 'ascent_angle', 'alignment', 'justification'])
1465
1593
  def show_marker(dict)
@@ -1527,10 +1655,30 @@ class FigureMaker
1527
1655
  it_angle = get_if_given_else_use_default_dict(dict, 'italic_angle', @marker_defaults)
1528
1656
  ascent_angle = get_if_given_else_use_default_dict(dict, 'ascent_angle', @marker_defaults)
1529
1657
  glyph = 0 if glyph == nil
1530
- int_args = glyph*100000 + font*1000 + mode*100 + align*10 + just
1531
- # Ruby limits us to 15 args, so pack some small integers together
1658
+ int_args = glyph*100000 + font*1000 + mode*100 + align*10 + (just+1) # min value for just is -1
1659
+ # Ruby limits us to 15 args, so pack some small integers together
1532
1660
  private_show_marker(int_args, stroke_width, string, x, y, xs, ys,
1533
- h_scale, v_scale, scale, it_angle, ascent_angle, angle, fill_color, stroke_color)
1661
+ h_scale, v_scale, scale, it_angle, ascent_angle, angle, fill_color, stroke_color)
1662
+ legend_arg = dict['legend']
1663
+ if legend_arg != nil
1664
+ if legend_arg.kind_of?Hash
1665
+ legend = legend_arg.dup
1666
+ legend["line_type"] = 'None' if legend["line_type"] == nil
1667
+ legend["marker"] = marker if legend["marker"] == nil
1668
+ legend["marker_scale"] = scale if legend["marker_scale"] == nil
1669
+ legend["marker_color"] = fill_color if legend["marker_color"] == nil
1670
+ save_legend_info(legend)
1671
+ elsif legend_arg.kind_of?String
1672
+ save_legend_info(
1673
+ 'line_type' => 'None',
1674
+ 'marker' => marker,
1675
+ 'marker_scale' => scale,
1676
+ 'marker_color' => fill_color,
1677
+ 'text' => legend_arg)
1678
+ else
1679
+ save_legend_info(legend_arg)
1680
+ end
1681
+ end
1534
1682
  end
1535
1683
 
1536
1684
  def show_label(dict)
@@ -1551,7 +1699,7 @@ class FigureMaker
1551
1699
 
1552
1700
  @@keys_for_show_text = FigureMaker.make_name_lookup_hash([
1553
1701
  'text', 'side', 'loc', 'position', 'pos', 'x', 'y',
1554
- 'shift', 'scale', 'color', 'angle', 'alignment', 'justification', 'at', 'point'])
1702
+ 'shift', 'scale', 'color', 'angle', 'alignment', 'justification', 'at', 'point', 'measure'])
1555
1703
  def show_text(dict)
1556
1704
  check_dict(dict, @@keys_for_show_text, 'show_text')
1557
1705
  text = dict['text']
@@ -1561,7 +1709,7 @@ class FigureMaker
1561
1709
  scale = get_if_given_else_default(dict, 'scale', 1)
1562
1710
  color = dict['color'] # color is [r,g,b] array. this adds \textcolor[rgb]{r,g,b}{...}
1563
1711
  if color != nil
1564
- if !color.kind_of?Array
1712
+ if !color.kind_of? Array
1565
1713
  raise "Sorry: 'color' must be array of [r,g,b] intensities for show_text (#{color})"
1566
1714
  end
1567
1715
  r = color[0]; g = color[1]; b = color[2];
@@ -1573,6 +1721,7 @@ class FigureMaker
1573
1721
  just = get_if_given_else_default(dict, 'justification', self.justification)
1574
1722
  align = get_if_given_else_default(dict, 'alignment', self.alignment)
1575
1723
  angle = get_if_given_else_default(dict, 'angle', 0)
1724
+
1576
1725
  loc = alt_names(dict, 'loc', 'side')
1577
1726
  if (loc == nil)
1578
1727
  at = alt_names(dict, 'at', 'point')
@@ -1586,7 +1735,8 @@ class FigureMaker
1586
1735
  if (xloc == nil || yloc == nil)
1587
1736
  raise "Sorry: Must supply a location for show_text"
1588
1737
  end
1589
- show_rotated_label(text, xloc, yloc, scale, angle, just, align)
1738
+ show_rotated_label(text, xloc, yloc, scale, angle, just, align,
1739
+ dict['measure'] || nil)
1590
1740
  return
1591
1741
  end
1592
1742
  position = alt_names(dict, 'position', 'pos')
@@ -1613,10 +1763,12 @@ class FigureMaker
1613
1763
  else
1614
1764
  raise "Sorry: 'loc' must be LEFT, RIGHT, TOP, BOTTOM, AT_X_ORIGIN, or AT_Y_ORIGIN for show_text"
1615
1765
  end
1616
- show_rotated_label(text, xloc, yloc, scale, angle, just, align)
1766
+ show_rotated_label(text, xloc, yloc, scale, angle, just, align,
1767
+ dict['measure'])
1617
1768
  return
1618
1769
  end
1619
- show_rotated_text(text, loc, shift, position, scale, angle, just, align)
1770
+ show_rotated_text(text, loc, shift, position, scale, angle, just,
1771
+ align, dict['measure'])
1620
1772
  end
1621
1773
 
1622
1774
 
@@ -1796,11 +1948,24 @@ class FigureMaker
1796
1948
  end
1797
1949
 
1798
1950
 
1951
+ # We wrap the call so that if the keys of @measures
1952
+ # did change during the call, we call it again.
1799
1953
  def make_pdf(num) # returns pdf name if successful, false if failed.
1954
+ old_measure_keys = @measures.keys
1800
1955
  num = get_num_for_pdf(num)
1801
1956
  result = start_making_pdf(num)
1802
1957
  return unless result
1803
- return @figure_pdfs[num] = finish_making_pdf(@figure_names[num])
1958
+ begin
1959
+ @figure_pdfs[num] = finish_making_pdf(@figure_names[num])
1960
+ # If the keys have changed, we run that again.
1961
+ rescue Exception => e
1962
+ p e, e.backtrace
1963
+ end
1964
+
1965
+ if @measures.keys != old_measure_keys
1966
+ make_pdf(num)
1967
+ end
1968
+ return @figure_pdfs[num]
1804
1969
  end
1805
1970
 
1806
1971
 
@@ -1862,9 +2027,10 @@ class FigureMaker
1862
2027
  cmd = @figure_commands[num]
1863
2028
  return false unless cmd.kind_of?(Proc)
1864
2029
  begin
2030
+ reset_plot_attrs
1865
2031
  reset_legend_info
1866
- result = private_make(name, cmd)
1867
- return result
2032
+ private_make(name, cmd)
2033
+ return true
1868
2034
  rescue Exception => er
1869
2035
  report_error(er, "ERROR while executing command: #{cmd}")
1870
2036
  end
@@ -1946,21 +2112,55 @@ class FigureMaker
1946
2112
 
1947
2113
 
1948
2114
  def finish_making_pdf(name) # returns pdfname if succeeds, false if fails.
1949
- pdflatex = FigureMaker.pdflatex
1950
- quiet = @quiet_mode
1951
- run_directory = @run_dir
1952
- if (@save_dir == nil)
1953
- syscmd = "#{pdflatex} -interaction nonstopmode #{name}.tex > pdflatex.log 2>&1"
1954
- else
1955
- syscmd = "cd #{@save_dir}; #{pdflatex} -interaction nonstopmode #{name}.tex > pdflatex.log 2>&1"
2115
+ pdflatex = FigureMaker.pdflatex
2116
+ quiet = @quiet_mode
2117
+ run_directory = @run_dir
2118
+
2119
+ if (@save_dir == nil)
2120
+ logname = "pdflatex.log"
2121
+ else
2122
+ logname = "#{@save_dir}/pdflatex.log"
2123
+ end
2124
+
2125
+ if (@save_dir == nil)
2126
+ syscmd = "#{pdflatex} -interaction nonstopmode #{name}.tex"
2127
+ else
2128
+ syscmd = "cd #{@save_dir}; #{pdflatex} -interaction nonstopmode #{name}.tex"
2129
+ end
2130
+ # Now fun begins:
2131
+ # We use IO::popen for three reasons:
2132
+ # * first, we want to be able to read back information from
2133
+ # pdflatex (see \tiogameasure)
2134
+ # * second, this way of doing should be portable to win, while
2135
+ # the > trick might not be that much...
2136
+ # * third, closing the standard input of pdflatex will remove
2137
+ # painful bugs, when pdflatex gets interrupted but waits
2138
+ # for an input for which it didn't prompt.
2139
+
2140
+ @measures = {}
2141
+ IO::popen(syscmd, "r+") do |f|
2142
+ f.close_write # We don't need that.
2143
+ log = File.open(logname, "w")
2144
+ for line in f
2145
+ log.print line
2146
+ if line =~ /^(.*)\[(\d)\]=(.+pt)/
2147
+ n = $1
2148
+ num = $2.to_i
2149
+ dim = Utils::tex_dimension_to_bp($3)
2150
+ @measures[n] ||= []
2151
+ @measures[n][num] = dim
2152
+ end
1956
2153
  end
1957
- result = system(syscmd)
2154
+ end
2155
+
2156
+ # Now passing the saved measures to the C code.
2157
+ for key, val in @measures
2158
+ # p @fm_data
2159
+ private_save_measure(key, *val)
2160
+ end
2161
+
2162
+ result = $?
1958
2163
  if !result
1959
- if (@save_dir == nil)
1960
- logname = "pdflatex.log"
1961
- else
1962
- logname = "#{@save_dir}/pdflatex.log"
1963
- end
1964
2164
  puts "ERROR: #{pdflatex} failed."
1965
2165
  file = File.open(logname)
1966
2166
  if file == nil
@@ -1968,9 +2168,7 @@ class FigureMaker
1968
2168
  else
1969
2169
  reporting = false; linecount = 0
1970
2170
  file.each_line do |line|
1971
- firstchar = line[0..0]
1972
- comparison = (firstchar <=> '!')
1973
- reporting = true if comparison == 0
2171
+ reporting = true if line =~ /^!/
1974
2172
  if reporting
1975
2173
  puts line
1976
2174
  linecount = linecount + 1