ctioga2 0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. data/COPYING +339 -0
  2. data/Changelog +6 -0
  3. data/bin/ctioga2 +26 -0
  4. data/lib/ctioga2/commands/arguments.rb +58 -0
  5. data/lib/ctioga2/commands/commands.rb +258 -0
  6. data/lib/ctioga2/commands/doc/doc.rb +118 -0
  7. data/lib/ctioga2/commands/doc/documentation-commands.rb +119 -0
  8. data/lib/ctioga2/commands/doc/help.rb +95 -0
  9. data/lib/ctioga2/commands/doc/html.rb +230 -0
  10. data/lib/ctioga2/commands/doc/introspection.rb +211 -0
  11. data/lib/ctioga2/commands/doc/man.rb +279 -0
  12. data/lib/ctioga2/commands/doc/markup.rb +359 -0
  13. data/lib/ctioga2/commands/general-commands.rb +119 -0
  14. data/lib/ctioga2/commands/general-types.rb +118 -0
  15. data/lib/ctioga2/commands/groups.rb +73 -0
  16. data/lib/ctioga2/commands/interpreter.rb +257 -0
  17. data/lib/ctioga2/commands/parsers/command-line.rb +187 -0
  18. data/lib/ctioga2/commands/parsers/file.rb +186 -0
  19. data/lib/ctioga2/commands/strings.rb +303 -0
  20. data/lib/ctioga2/commands/type.rb +100 -0
  21. data/lib/ctioga2/commands/variables.rb +101 -0
  22. data/lib/ctioga2/data/backends/backend.rb +260 -0
  23. data/lib/ctioga2/data/backends/backends.rb +39 -0
  24. data/lib/ctioga2/data/backends/backends/gnuplot.rb +140 -0
  25. data/lib/ctioga2/data/backends/backends/math.rb +121 -0
  26. data/lib/ctioga2/data/backends/backends/text.rb +335 -0
  27. data/lib/ctioga2/data/backends/description.rb +405 -0
  28. data/lib/ctioga2/data/backends/factory.rb +73 -0
  29. data/lib/ctioga2/data/backends/parameter.rb +109 -0
  30. data/lib/ctioga2/data/datacolumn.rb +245 -0
  31. data/lib/ctioga2/data/dataset.rb +233 -0
  32. data/lib/ctioga2/data/filters.rb +131 -0
  33. data/lib/ctioga2/data/merge.rb +43 -0
  34. data/lib/ctioga2/data/point.rb +72 -0
  35. data/lib/ctioga2/data/stack.rb +294 -0
  36. data/lib/ctioga2/graphics/coordinates.rb +73 -0
  37. data/lib/ctioga2/graphics/elements.rb +111 -0
  38. data/lib/ctioga2/graphics/elements/containers.rb +111 -0
  39. data/lib/ctioga2/graphics/elements/curve2d.rb +155 -0
  40. data/lib/ctioga2/graphics/elements/element.rb +90 -0
  41. data/lib/ctioga2/graphics/elements/primitive.rb +256 -0
  42. data/lib/ctioga2/graphics/elements/subplot.rb +140 -0
  43. data/lib/ctioga2/graphics/generator.rb +68 -0
  44. data/lib/ctioga2/graphics/legends.rb +108 -0
  45. data/lib/ctioga2/graphics/legends/area.rb +199 -0
  46. data/lib/ctioga2/graphics/legends/items.rb +183 -0
  47. data/lib/ctioga2/graphics/legends/provider.rb +58 -0
  48. data/lib/ctioga2/graphics/legends/storage.rb +65 -0
  49. data/lib/ctioga2/graphics/root.rb +209 -0
  50. data/lib/ctioga2/graphics/styles.rb +30 -0
  51. data/lib/ctioga2/graphics/styles/axes.rb +247 -0
  52. data/lib/ctioga2/graphics/styles/background.rb +122 -0
  53. data/lib/ctioga2/graphics/styles/base.rb +115 -0
  54. data/lib/ctioga2/graphics/styles/carrays.rb +53 -0
  55. data/lib/ctioga2/graphics/styles/curve.rb +101 -0
  56. data/lib/ctioga2/graphics/styles/drawable.rb +87 -0
  57. data/lib/ctioga2/graphics/styles/factory.rb +351 -0
  58. data/lib/ctioga2/graphics/styles/legend.rb +63 -0
  59. data/lib/ctioga2/graphics/styles/plot.rb +410 -0
  60. data/lib/ctioga2/graphics/styles/sets.rb +64 -0
  61. data/lib/ctioga2/graphics/styles/texts.rb +277 -0
  62. data/lib/ctioga2/graphics/subplot-commands.rb +141 -0
  63. data/lib/ctioga2/graphics/types.rb +188 -0
  64. data/lib/ctioga2/graphics/types/bijection.rb +79 -0
  65. data/lib/ctioga2/graphics/types/boundaries.rb +170 -0
  66. data/lib/ctioga2/graphics/types/boxes.rb +157 -0
  67. data/lib/ctioga2/graphics/types/dimensions.rb +157 -0
  68. data/lib/ctioga2/graphics/types/point.rb +247 -0
  69. data/lib/ctioga2/log.rb +97 -0
  70. data/lib/ctioga2/metabuilder/type.rb +316 -0
  71. data/lib/ctioga2/metabuilder/types.rb +39 -0
  72. data/lib/ctioga2/metabuilder/types/coordinates.rb +124 -0
  73. data/lib/ctioga2/metabuilder/types/dates.rb +43 -0
  74. data/lib/ctioga2/metabuilder/types/lists.rb +188 -0
  75. data/lib/ctioga2/metabuilder/types/numbers.rb +97 -0
  76. data/lib/ctioga2/metabuilder/types/strings.rb +93 -0
  77. data/lib/ctioga2/metabuilder/types/styles.rb +178 -0
  78. data/lib/ctioga2/plotmaker.rb +677 -0
  79. data/lib/ctioga2/postprocess.rb +115 -0
  80. data/lib/ctioga2/utils.rb +120 -0
  81. data/setup.rb +1586 -0
  82. metadata +144 -0
@@ -0,0 +1,188 @@
1
+ # types.rb: various useful types to interact with Tioga
2
+ # copyright (c) 2009 by Vincent Fourmond
3
+
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 2 of the License, or
7
+ # (at your option) any later version.
8
+
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details (in the COPYING file).
13
+
14
+ require 'ctioga2/graphics/types/dimensions'
15
+ require 'ctioga2/graphics/types/point'
16
+ require 'ctioga2/graphics/types/boundaries'
17
+ require 'ctioga2/graphics/types/boxes'
18
+ require 'ctioga2/graphics/types/bijection'
19
+
20
+ # In addition to the former, here are some useful constants
21
+ # This module contains all the classes used by ctioga
22
+ module CTioga2
23
+
24
+ Version::register_svn_info('$Revision: 96 $', '$Date: 2009-06-27 20:56:17 +0200 (Sat, 27 Jun 2009) $')
25
+
26
+ module Graphics
27
+
28
+ # A small convenience module for line styles
29
+ module LineStyles
30
+ include Tioga::FigureConstants
31
+
32
+ Line_Type_Dash_Dot_Dot = [[5,2,1,2,1,2],0]
33
+ Line_Type_Small_Dots = [[0.5,1],0]
34
+
35
+ # Shortcut for line styles:
36
+ Solid = Line_Type_Solid
37
+ Dots = Line_Type_Dots
38
+ Dashes = Line_Type_Dashes
39
+ Small_Dots = Line_Type_Small_Dots
40
+ Dot_Long_Dash = Line_Type_Dot_Long_Dash
41
+ Dash_Dot_Dot = Line_Type_Dash_Dot_Dot
42
+ end
43
+
44
+
45
+ ColorType = CmdType.new('color', {
46
+ :type => :tioga_color,
47
+ :namespace => Tioga::ColorConstants
48
+ }, <<EOD)
49
+ A color. It can take three forms:
50
+ * the name of a named color; see
51
+ http://tioga.rubyforge.org/doc/classes/Tioga/ColorConstants.html
52
+ for the list of colors.
53
+ * an HTML color: for instance, #f00 or #ff0000 is red;
54
+ * a list of three numbers between 0 and 1: 1,0,0 is red too.
55
+ EOD
56
+
57
+ ColorOrFalseType =
58
+ CmdType.new('color-or-false', {
59
+ :type => :tioga_color,
60
+ :namespace => Tioga::ColorConstants,
61
+ :shortcuts => {'none' => false }
62
+ }, <<EOD)
63
+ A {type: color}, or false to say that nothing should be drawn.
64
+ EOD
65
+
66
+ LineStyleType =
67
+ CmdType.new('line-style', {
68
+ :type => :tioga_line_style,
69
+ :namespace => LineStyles
70
+ }, <<EOD)
71
+ A line style.
72
+ EOD
73
+
74
+ MarkerType =
75
+ CmdType.new('marker', {
76
+ :type => :tioga_marker,
77
+ :namespace => Tioga::MarkerConstants,
78
+ :shortcuts => {
79
+ 'None' => 'None',
80
+ 'no' => 'None',
81
+ 'none' => 'None',
82
+ 'off' => 'None',
83
+ },}, <<EOD)
84
+ A Tioga Marker.
85
+ EOD
86
+
87
+ PointType =
88
+ CmdType.new('point', :point, <<EOD)
89
+ A given point on a figure.
90
+ EOD
91
+
92
+ JustificationType =
93
+ CmdType.new('justification', :tioga_justification, <<EOD)
94
+ Horizontal aligment for text.
95
+ EOD
96
+
97
+ AlignmentType =
98
+ CmdType.new('alignment', :tioga_align, <<EOD)
99
+ Vertical aligment for text.
100
+ EOD
101
+
102
+ PDFFont =
103
+ CmdType.new('pdf-font', :integer, <<EOD)
104
+ A number between 1 and 14 that designates one of the 14 standard
105
+ PDF fonts.
106
+ EOD
107
+
108
+ AlignedPointType =
109
+ CmdType.new('aligned-point', {:type => :aligned_point,
110
+ :default => :frame}, <<EOD)
111
+ A point together with alignment specifications.
112
+ EOD
113
+
114
+ FrameMarginsType =
115
+ CmdType.new('frame-margins', {:type =>
116
+ :frame_margins, :shortcuts =>
117
+ { /^\s*auto\s*$/i => nil}}, <<EOD)
118
+ Margins around a plot, ie the distance from the side of the plot to
119
+ the corresponding side of the container (most likely the whole
120
+ PDF). It can take three forms:
121
+
122
+ * dimension (applies to all sides)
123
+ * left_right, top_bottom
124
+ * left, right, top, bottom
125
+
126
+ Each of the elements is a valid {type: dimension}.
127
+
128
+ It can also be auto, in which case the position of the margins is
129
+ computed automatically to accomodate the various labels/ticks.
130
+ EOD
131
+
132
+ # Now, axes stuff:
133
+
134
+ AxisDecorationType =
135
+ CmdType.new('axis-decoration', :tioga_axis_type, <<EOD)
136
+ Kinds of decoration on a axis line, such as nothing, lines, ticks,
137
+ tick labels...
138
+ EOD
139
+
140
+ # Dimensions
141
+
142
+ DimensionType =
143
+ CmdType.new('dimension', { :type => :dimension,
144
+ :default => :dy }, <<EOD)
145
+
146
+ A dimension, in absolute units, or in units of text height, figure,
147
+ frame or page coordinates. It is in the form
148
+
149
+ @ value unit
150
+
151
+ Where value is a number and unit can be one of pt,bp,in,cm (absolute
152
+ units, same meaning as in TeX), dy (1.0 dy is the height of a text
153
+ line), figure (for figure coordinates, i.e. the coordinates of the
154
+ plot), frame (1.0 frame is the full size of the current subplot) and
155
+ page (1.0 page is the whole height/width of the output file).
156
+
157
+ figure can be abbreviated as f, frame as F and page as p.
158
+ EOD
159
+
160
+ # Boxes
161
+
162
+ BoxType =
163
+ CmdType.new('box', :box, <<EOD)
164
+ The specification for a box, such as an inset. Specifications vary for
165
+ now...
166
+
167
+ TODO: to be written later on.
168
+ EOD
169
+
170
+ # Coordinate transformations
171
+ BijectionType =
172
+ CmdType.new('bijection', :bijection, <<EOD)
173
+ A pair of functions of x specifying a bidirectional coordinate
174
+ transformation , separated by a double colon (::), in the order
175
+ from::to.
176
+
177
+ Each of the functions must be valid Ruby code - it is not exactly
178
+ mathematical functions, in particular Ruby does not like floats which
179
+ are missing digits on either side of the dot : for instance, .3 and
180
+ 1. are not valid. Sorry.
181
+
182
+ In most of the usual cases, the coordinate transform is an involution,
183
+ that is from and to is the same function (this is the case for
184
+ a/x). In this case, you can omit the second function.
185
+ EOD
186
+
187
+ end
188
+ end
@@ -0,0 +1,79 @@
1
+ # bijection.rb: a bijection representing a reversible coordinate transformation
2
+ # copyright (c) 2009 by Vincent Fourmond
3
+
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 2 of the License, or
7
+ # (at your option) any later version.
8
+
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details (in the COPYING file).
13
+
14
+ require 'ctioga2/utils'
15
+ require 'ctioga2/log'
16
+
17
+ module CTioga2
18
+
19
+ Version::register_svn_info('$Revision: 67 $', '$Date: 2009-05-30 23:38:00 +0200 (Sat, 30 May 2009) $')
20
+
21
+ module Graphics
22
+
23
+ module Types
24
+
25
+ # This class represents a *reversible* arbitrary coordinate
26
+ # transformation, such as the ones that could be desirable for
27
+ # alternative axes. Characterized by two Block objects, #from
28
+ # and #to, that converts respectively from and to the target
29
+ # coordinates.
30
+ class Bijection
31
+
32
+ # A Block converting from the target coordinates
33
+ attr_accessor :from
34
+
35
+ # A Block converting to the target coordinates
36
+ attr_accessor :to
37
+
38
+ # Creates a new Bijection with the given blocks.
39
+ def initialize(from, to = nil)
40
+ @from = from
41
+ @to = to || @from
42
+ end
43
+
44
+ # Converts a vector to the target coordinates
45
+ def convert_to(vect)
46
+ return vect.map do |x|
47
+ self.to.call(x)
48
+ end
49
+ end
50
+
51
+ # Converts a vector from the target coordinates
52
+ def convert_from(vect)
53
+ return vect.map do |x|
54
+ self.from.call(x)
55
+ end
56
+ end
57
+
58
+ # Creates a Bijection from a text representation.
59
+ #
60
+ # Takes functions of _x_. Takes two blocks _from_ _to_
61
+ # separated by :: -- or only one block in the case of an
62
+ # involution (very common, actually, all 1/x transforms).
63
+ #
64
+ # TODO: few things around here to change... in particular,
65
+ # I should try to find a way to include Math...
66
+ #
67
+ # TODO: add very common cases ?
68
+ def self.from_text(spec)
69
+ blocks = spec.split(/::/).map do |code|
70
+ eval("proc do |x|\n#{code}\nend")
71
+ end
72
+ return Bijection.new(*blocks)
73
+ end
74
+ end
75
+
76
+ end
77
+ end
78
+ end
79
+
@@ -0,0 +1,170 @@
1
+ # boundaries.rb: manipulation of Plot boundaries
2
+ # copyright (c) 2009 by Vincent Fourmond
3
+
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 2 of the License, or
7
+ # (at your option) any later version.
8
+
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details (in the COPYING file).
13
+
14
+ require 'ctioga2/utils'
15
+ require 'ctioga2/log'
16
+
17
+ module CTioga2
18
+
19
+ Version::register_svn_info('$Revision: 2 $', '$Date: 2009-04-25 14:03:30 +0200 (Sat, 25 Apr 2009) $')
20
+
21
+ # This module contains all graphical elements of CTioga2
22
+ module Graphics
23
+
24
+ # A module holding different data types useful for interacting
25
+ # with Tioga
26
+ module Types
27
+
28
+ # An object representing boundaries for a plot.
29
+ class Boundaries
30
+
31
+ # Boundaries
32
+ attr_accessor :left, :right, :top, :bottom
33
+
34
+ # Creates a new Boundaries object with the given boundaries. A
35
+ # _nil_, _false_ or NaN in one of those means *unspecified*.
36
+ def initialize(left, right, top, bottom)
37
+ @left = left
38
+ @right = right
39
+ @top = top
40
+ @bottom = bottom
41
+ end
42
+
43
+ # Converts to an array suitable for use with Tioga.
44
+ def to_a
45
+ return [@left, @right, @top, @bottom]
46
+ end
47
+
48
+ # Minimum x value
49
+ def xmin
50
+ @left < @right ? @left : @right
51
+ end
52
+
53
+ # Maximum x value
54
+ def xmax
55
+ @left > @right ? @left : @right
56
+ end
57
+
58
+ # Minimum y value
59
+ def ymin
60
+ @bottom < @top ? @bottom : @top
61
+ end
62
+
63
+ # Maxiumum y value
64
+ def ymax
65
+ @bottom > @top ? @bottom : @top
66
+ end
67
+
68
+
69
+ # Converts to an [xmin, xmax, ymin, ymax] array
70
+ def extrema
71
+ return [xmin, xmax, ymin, ymax]
72
+ end
73
+
74
+ # The algebraic width of the boundaries
75
+ def width
76
+ return @right - @left
77
+ end
78
+
79
+ # The algebraic height of the boundaries
80
+ def height
81
+ return @top - @bottom
82
+ end
83
+
84
+ # This function makes sures that the Boundaries object is big
85
+ # enough to encompass what it currently does and the _bounds_
86
+ # Boundaries object.
87
+ def extend(bounds)
88
+ # Left/right
89
+ if (! @left.is_a? Float) or @left.nan? or
90
+ (@left > bounds.left)
91
+ @left = bounds.left
92
+ end
93
+ if (! @right.is_a? Float) or @right.nan? or
94
+ (@right < bounds.right)
95
+ @right = bounds.right
96
+ end
97
+
98
+ # Top/bottom
99
+ if (! @top.is_a? Float) or @top.nan? or
100
+ (@top < bounds.top)
101
+ @top = bounds.top
102
+ end
103
+ if (! @bottom.is_a? Float) or @bottom.nan? or
104
+ (@bottom > bounds.bottom)
105
+ @bottom = bounds.bottom
106
+ end
107
+ return self
108
+ end
109
+
110
+
111
+ # Override the Boundaries with the contents of _override_. All
112
+ # elements which are not _nil_ or NaN from _override_
113
+ # precisely override those in _self_.
114
+ def override_boundaries(override)
115
+ for el in [ :left, :right, :top, :bottom]
116
+ val = override.send(el)
117
+ if val and (val == val) # Strip NaN on the property that NaN != NaN
118
+ self.send("#{el}=", val)
119
+ end
120
+ end
121
+ end
122
+
123
+ # Apply a fixed margin on the Boundaries.
124
+ def apply_margin!(margin)
125
+ w = self.width
126
+ @left = @left - margin * w
127
+ @right = @right + margin * w
128
+ h = self.height
129
+ @top = @top + margin * h
130
+ @bottom = @bottom - margin * h
131
+ end
132
+
133
+ # Sets the values of the Boundaries for the _which_ axis from
134
+ # the given _range_.
135
+ def set_from_range(range, which)
136
+ case which
137
+ when :x
138
+ @left, @right = range.first, range.last
139
+ when :y
140
+ @bottom, @top = range.first, range.last
141
+ else
142
+ raise "What is this #{which} axis ? "
143
+ end
144
+ end
145
+
146
+ # Returns a boundary object that exactly contains all _x_values_
147
+ # and _y_values_ (including error bars if applicable)
148
+ def self.bounds(x_values, y_values)
149
+ return Boundaries.new(x_values.min, x_values.max,
150
+ y_values.max, y_values.min)
151
+ end
152
+
153
+ # Takes an array of Boundaries and returns a Boundaries object
154
+ # that precisely encompasses them all. Invalid floats are simply
155
+ # ignored.
156
+ def self.overall_bounds(bounds)
157
+ retval = Boundaries.new(nil, nil, nil, nil)
158
+ for b in bounds
159
+ retval.extend(b)
160
+ end
161
+ return retval
162
+ end
163
+
164
+ end
165
+
166
+ end
167
+
168
+ end
169
+
170
+ end
@@ -0,0 +1,157 @@
1
+ # boxes.rb: various ways to represent a box in Tioga
2
+ # copyright (c) 2009 by Vincent Fourmond
3
+
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 2 of the License, or
7
+ # (at your option) any later version.
8
+
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details (in the COPYING file).
13
+
14
+ require 'ctioga2/utils'
15
+ require 'ctioga2/log'
16
+
17
+ module CTioga2
18
+
19
+ Version::register_svn_info('$Revision: 92 $', '$Date: 2009-06-24 01:17:46 +0200 (Wed, 24 Jun 2009) $')
20
+
21
+ # This module contains all graphical elements of CTioga2
22
+ module Graphics
23
+
24
+ # A module holding different data types useful for interacting
25
+ # with Tioga
26
+ module Types
27
+
28
+ # The base class for different kind of boxes
29
+ class Box
30
+
31
+ def initialize
32
+ raise "Use a derived class !"
33
+ end
34
+
35
+ # This function returns the frame coordinates of the box, in
36
+ # the form:
37
+ # [ xl, yt, xr, yb ]
38
+ # This function *must* be reimplemented in children.
39
+ def to_frame_coordinates(t)
40
+ raise "Reimplement this in children !"
41
+ end
42
+
43
+ # Converts this object into an array suitable for use with
44
+ # FigureMaker#set_sub_frame.
45
+ def to_frame_margins(t)
46
+ xl, yt, xr, yb = self.to_frame_coordinates(t)
47
+ return [xl, 1 - xr, 1 - yt, yb]
48
+ end
49
+
50
+ end
51
+
52
+ # A box defined by its margins
53
+ class MarginsBox < Box
54
+
55
+ # Margin specifications. These are Dimension objects.
56
+ attr_accessor :left, :right, :top, :bottom
57
+
58
+ # Creates a new MarginsBox object with the specified margins,
59
+ # as String (passed on to Dimension::to_text), float (defaults
60
+ # to frame coordinates) or directly as Dimension objects.
61
+ #
62
+ # The Dimension's orientation is automatically tweaked.
63
+ def initialize(left, right, top, bottom)
64
+ # First, convert any float into Dimension:
65
+ a = [left, right, top, bottom]
66
+ a.each_index do |i|
67
+ if ! a[i].is_a? Dimension
68
+ a[i] = Dimension::from_text(a[i].to_s, :x, :frame)
69
+ end
70
+ end
71
+ left, right, top, bottom = a
72
+
73
+ # Then assign to the appropriate stuff:
74
+ @left = left
75
+ @left.orientation = :x
76
+ @right = right
77
+ @right.orientation = :x
78
+ @top = top
79
+ @top.orientation = :y
80
+ @bottom = bottom
81
+ @bottom.orientation = :y
82
+ end
83
+
84
+ def to_frame_coordinates(t)
85
+ return [@left.to_frame(t), 1 - @top.to_frame(t),
86
+ 1 - @right.to_frame(t), @bottom.to_frame(t)]
87
+ end
88
+
89
+ # Returns the dimensions composing the MarginsBox, in the
90
+ # order _left_, _right_, _top_, _bottom_, suitable for feeding
91
+ # to MarginsBox.new.
92
+ def margins
93
+ return [@left, @right, @top, @bottom]
94
+ end
95
+
96
+ end
97
+
98
+ # A box defined by an AlignedPoint and two dimensions
99
+ class PointBasedBox < Box
100
+
101
+ # The aligned point of the box:
102
+ attr_accessor :point
103
+
104
+ # The width
105
+ attr_accessor :width
106
+
107
+ # The height
108
+ attr_accessor :height
109
+
110
+ # Creates a new PointBasedBox at the given _point_, with the
111
+ # given _width_ and _height_.
112
+ def initialize(point, width, height)
113
+ @point = point
114
+ @width = width
115
+ @height = height
116
+ end
117
+
118
+ # A well formed point-based box must match the following
119
+ # regular expression.
120
+ PointBasedBoxRE = /^\s*(.*):([^,]+)(?:,\s*(.*))?$/
121
+
122
+ # Returns a new PointBasedBox object based on the text
123
+ # specification, which reads:
124
+ #
125
+ # aligned_point:w(,h)
126
+ #
127
+ # The default holds for point and dimensions
128
+ def self.from_text(text, default = :frame)
129
+ if text =~ PointBasedBoxRE
130
+ po,w,h = $1,$2,$3
131
+ point = AlignedPoint.from_text(po, default)
132
+ width = Dimension.from_text(w, :x, default)
133
+ if h
134
+ height = Dimension.from_text(h, :y, default)
135
+ else
136
+ height = width.dup
137
+ end
138
+ return PointBasedBox.new(point, width, height)
139
+ else
140
+ raise "#{text} is not a point-based box."
141
+ end
142
+ end
143
+
144
+ # Returns the frame coordinates of the box.
145
+ def to_frame_coordinates(t)
146
+ dx = @width.to_figure(t, :x)
147
+ dy = @height.to_figure(t, :y)
148
+ a = @point.to_frame_coordinates(t, dx, dy)
149
+ return @point.to_frame_coordinates(t, dx, dy)
150
+ end
151
+
152
+ end
153
+
154
+ end
155
+ end
156
+ end
157
+