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.
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