ctioga2 0.0

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 (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
+