16
16
require 'ctioga2/log'
18
18
require 'ctioga2/graphics/types'
19
require 'ctioga2/graphics/styles'
19
20
require 'shellwords'
21
22
# This module contains all the classes used by ctioga
24
Version::register_svn_info('$Revision: 151 $', '$Date: 2010-06-19 23:45:20 +0200 (Sat, 19 Jun 2010) $')
25
Version::register_svn_info('$Revision: 370 $', '$Date: 2012-12-28 17:40:18 +0100 (Fri, 28 Dec 2012) $')
30
31
# A TiogaElement that represents a graphics primitive.
33
# @todo Most of the objects here should rely on getting a
34
# BasicStyle object from the options hash and use it to
35
# draw. There is no need to make cumbersome and hard to extend
31
37
class TiogaPrimitiveCall < TiogaElement
33
39
# Some kind of reimplementation of Command for graphics
88
94
# Creates a new primitive with the given parameters, and makes
89
95
# it immediately available as a command.
90
def self.primitive(name, long_name, comp, opts = {}, &code)
96
def self.primitive(name, long_name, comp, opts = {},
91
98
primitive = TiogaPrimitive.new(name, comp, opts, &code)
92
99
@known_primitives[name] = primitive
111
122
plotmaker.root_object.current_plot.
112
123
add_element(call)
126
desc = "Directly draws #{long_name} on the current plot"
114
128
cmd.describe("Draws #{long_name}",
115
"Directly draws #{long_name} on the current plot", PrimitiveGroup)
117
132
PrimitiveCommands[name] = cmd
135
# This creates a primitive base on a style object, given a
136
# _style_class_, the base _style_name_ for the underlying
137
# styling system, options to remove and options to add.
139
# The underlying code receives:
140
# * the FigureMaker object
141
# * the compulsory arguments
144
def self.styled_primitive(name, long_name, comp, style_class,
145
style_name, without = [],
146
additional_options = {},
147
set_style_command = nil, # This
151
options = style_class.options_hash.without(without)
152
options.merge!(additional_options)
153
options['base-style'] = 'text' # the base style name
155
set_style_command ||= style_name
157
Draws #{long_name} on the current plot, using the given style.
158
For more information on the available options, see the
159
{command: define-#{set_style_command}-style} command.
162
self.primitive(name, long_name, comp, options, desc) do |*all|
164
st_name = opts['base-style'] || "base"
165
style = Styles::StyleSheet.style_for(style_class,st_name)
166
style.set_from_hash(opts)
121
173
# Returns a pair primitive/primitive command for the named
122
174
# primitive, or [ _nil_, _nil_ ]
127
179
# Now, a list of primitives, along with their code.
129
primitive("text", "text", [ 'point', 'text' ],
134
'justification' => 'justification',
135
'alignment' => 'alignment',
136
'font' => 'latex-font',
138
) do |t, point, string, options|
181
styled_primitive("text", "text",
183
Styles::FullTextStyle,
186
{'font' => 'latex-font'}
187
) do |t, point, string, style, options|
139
188
# @todo add a way to specify fonts ???
141
190
if options['font']
142
191
string = options['font'].fontify(string)
143
options.delete('font')
145
options['text'] = string
146
options['at'] = point.to_figure_xy(t)
150
# @todo add rendering mode !!
153
'stroke_color' => 'color',
154
'fill_color' => 'color',
156
'horizontal_scale' => 'float',
157
'vertical_scale' => 'float',
159
'justification' => 'justification',
160
'alignment' => 'alignment',
163
primitive("marker", "marker", [ 'point', 'marker' ],
164
MarkerOptions) do |t, point, marker, options|
165
## \todo add a way to specify fonts ???
167
options['marker'] = marker
168
options['at'] = point.to_figure_xy(t)
169
t.show_marker(options)
172
primitive("string-marker", "marker", [ 'point', 'text' ],
173
{'font' => 'pdf-font' }.update(MarkerOptions)
174
) do |t, point, string, options|
175
## \todo add a way to specify fonts ???
177
options['text'] = string
178
options['at'] = point.to_figure_xy(t)
179
t.show_marker(options)
193
style.draw_text(t, string, *(point.to_figure_xy(t)))
196
styled_primitive("marker", "marker",
197
[ 'point', 'marker' ],
198
Styles::MarkerStringStyle,
200
['font'] # font doesn't make any sense with a
202
) do |t, point, marker, style, options|
203
style.draw_marker(t, marker, *point.to_figure_xy(t))
206
styled_primitive("string-marker", "marker",
208
Styles::MarkerStringStyle,
212
) do |t, point, string, style, options|
213
style.draw_string_marker(t, string, *point.to_figure_xy(t))
182
217
# options for arrows (and therefore tangents)
192
227
'line_style' => 'line-style',
195
primitive("arrow", "arrow", [ 'point', 'point' ],
196
ArrowOptions) do |t, tail,head, options|
197
## \todo a scale or marker_scale option that sets the scale
198
## of both head and tail
200
options['head'] = head.to_figure_xy(t)
201
options['tail'] = tail.to_figure_xy(t)
202
t.show_arrow(options)
205
primitive("line", "line", [ 'point', 'point' ],
208
'line_width' => 'float',
209
'line_style' => 'line-style',
211
) do |t, tail,head, options|
213
for a in ['head', 'tail']
214
options["#{a}_marker"] = "None"
216
options['head'] = head.to_figure_xy(t)
217
options['tail'] = tail.to_figure_xy(t)
218
t.show_arrow(options)
230
styled_primitive("arrow", "arrow",
231
[ 'point', 'point' ],
233
'arrow') do |t, tail, head, style, options|
234
style.draw_arrow(t, *tail.to_figure_xy(t),
235
*head.to_figure_xy(t))
238
styled_primitive("line", "line",
239
[ 'point', 'point' ],
242
) do |t, tail, head, style, options|
243
style.draw_line(t, *(tail.to_figure_xy(t)),
244
*(head.to_figure_xy(t)))
247
# Here, we need to add deprecated options for backward
250
for cmd in ['draw-line', 'draw-arrow']
251
Commands::make_alias_for_option cmd, 'width', 'line_width', true
252
Commands::make_alias_for_option cmd, 'style', 'line_style', true
255
styled_primitive("box", "box",
256
[ 'point', 'point' ],
258
'box') do |t, tl, br, style, options|
259
x1,y1 = tl.to_figure_xy(t)
260
x2,y2 = br.to_figure_xy(t)
261
style.draw_box(t, x1, y1, x2, y2)
265
Commands::make_alias_for_option 'draw-box', 'fill_color', 'fill-color'
266
Commands::make_alias_for_option 'draw-box', 'fill_transparency', 'fill-transparency'