~ubuntu-branches/ubuntu/wily/ctioga2/wily

« back to all changes in this revision

Viewing changes to lib/ctioga2/graphics/elements/primitive.rb

  • Committer: Package Import Robot
  • Author(s): Vincent Fourmond
  • Date: 2013-07-08 20:58:17 UTC
  • mfrom: (6.1.1 experimental)
  • Revision ID: package-import@ubuntu.com-20130708205817-cephnc6etndyxrrp
Tags: 0.4-2
* Upload to unstable
* Already conforms to newer standards

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
require 'ctioga2/log'
17
17
 
18
18
require 'ctioga2/graphics/types'
 
19
require 'ctioga2/graphics/styles'
19
20
require 'shellwords'
20
21
 
21
22
# This module contains all the classes used by ctioga
22
23
module CTioga2
23
24
 
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) $')
25
26
 
26
27
  module Graphics
27
28
 
28
29
    module Elements
29
30
      
30
31
      # A TiogaElement that represents a graphics primitive.
 
32
      #
 
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
 
36
      # hashes.
31
37
      class TiogaPrimitiveCall < TiogaElement
32
38
        
33
39
        # Some kind of reimplementation of Command for graphics
87
93
 
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 = {}, 
 
97
                           desc = nil, &code)
91
98
          primitive = TiogaPrimitive.new(name, comp, opts, &code)
92
99
          @known_primitives[name] = primitive
93
100
          
98
105
 
99
106
          cmd_opts = {}
100
107
          for k,v in opts
101
 
            cmd_opts[k] = CmdArg.new(v)
 
108
            cmd_opts[k] = if v.respond_to?(:type)
 
109
                            v
 
110
                          else
 
111
                            CmdArg.new(v)
 
112
                          end
102
113
          end
103
114
          
104
115
          cmd = Cmd.new("draw-#{name}",nil,"--draw-#{name}", 
111
122
            plotmaker.root_object.current_plot.
112
123
              add_element(call)
113
124
          end
 
125
          if ! desc
 
126
            desc = "Directly draws #{long_name} on the current plot"
 
127
          end
114
128
          cmd.describe("Draws #{long_name}",
115
 
                       "Directly draws #{long_name} on the current plot", PrimitiveGroup)
 
129
                       desc, 
 
130
                       PrimitiveGroup)
116
131
 
117
132
          PrimitiveCommands[name] = cmd
118
133
        end
119
134
 
 
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.
 
138
        #
 
139
        # The underlying code receives:
 
140
        # * the FigureMaker object
 
141
        # * the compulsory arguments
 
142
        # * the style
 
143
        # * the raw options
 
144
        def self.styled_primitive(name, long_name, comp, style_class, 
 
145
                                  style_name, without = [],
 
146
                                  additional_options = {},
 
147
                                  set_style_command = nil, # This
 
148
                                                           # could be
 
149
                                                           # removed
 
150
                                  &code)
 
151
          options = style_class.options_hash.without(without)
 
152
          options.merge!(additional_options)
 
153
          options['base-style'] = 'text' # the base style name
 
154
 
 
155
          set_style_command ||= style_name
 
156
          desc = <<"EOD"
 
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.
 
160
EOD
 
161
 
 
162
          self.primitive(name, long_name, comp, options, desc) do |*all|
 
163
            opts = all.pop
 
164
            st_name = opts['base-style'] || "base"
 
165
            style = Styles::StyleSheet.style_for(style_class,st_name) 
 
166
            style.set_from_hash(opts)
 
167
            all << style << opts
 
168
            code.call(*all)
 
169
          end
 
170
        end
 
171
 
120
172
 
121
173
        # Returns a pair primitive/primitive command for the named
122
174
        # primitive, or [ _nil_, _nil_ ]
126
178
 
127
179
        # Now, a list of primitives, along with their code.
128
180
 
129
 
        primitive("text", "text", [ 'point', 'text' ],
130
 
                  {
131
 
                    'color' => 'color',
132
 
                    'scale' => 'float',
133
 
                    'angle' => 'float',
134
 
                    'justification' => 'justification',
135
 
                    'alignment' => 'alignment',
136
 
                    'font' => 'latex-font',
137
 
                  }
138
 
                  ) do |t, point, string, options|
 
181
        styled_primitive("text", "text", 
 
182
                         [ 'point', 'text' ],
 
183
                         Styles::FullTextStyle,
 
184
                         'text',
 
185
                         ['text'],
 
186
                         {'font' => 'latex-font'}
 
187
                  ) do |t, point, string, style, options|
139
188
          # @todo add a way to specify fonts ???
140
189
          options ||= {}
141
190
          if options['font']
142
191
            string = options['font'].fontify(string)
143
 
            options.delete('font')
144
192
          end
145
 
          options['text'] = string
146
 
          options['at'] = point.to_figure_xy(t)
147
 
          t.show_text(options)
148
 
        end
149
 
 
150
 
        # @todo add rendering mode !!
151
 
        MarkerOptions = {
152
 
          'color' => 'color',
153
 
          'stroke_color' => 'color',
154
 
          'fill_color' => 'color',
155
 
          'scale' => 'float',
156
 
          'horizontal_scale' => 'float',
157
 
          'vertical_scale' => 'float',
158
 
          'angle' => 'float',
159
 
          'justification' => 'justification',
160
 
          'alignment' => 'alignment',
161
 
        }
162
 
 
163
 
        primitive("marker", "marker", [ 'point', 'marker' ],
164
 
                  MarkerOptions) do |t, point, marker, options|
165
 
          ## \todo add a way to specify fonts ???
166
 
          options ||= {}
167
 
          options['marker'] = marker
168
 
          options['at'] = point.to_figure_xy(t)
169
 
          t.show_marker(options)
170
 
        end
171
 
 
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 ???
176
 
          options ||= {}
177
 
          options['text'] = string
178
 
          options['at'] = point.to_figure_xy(t)
179
 
          t.show_marker(options)
180
 
        end
 
193
          style.draw_text(t, string, *(point.to_figure_xy(t)))
 
194
        end
 
195
 
 
196
        styled_primitive("marker", "marker", 
 
197
                         [ 'point', 'marker' ],
 
198
                         Styles::MarkerStringStyle,
 
199
                         'marker',
 
200
                         ['font'] # font doesn't make any sense with a
 
201
                         # marker spec
 
202
                         ) do |t, point, marker, style, options|
 
203
          style.draw_marker(t, marker, *point.to_figure_xy(t))
 
204
        end
 
205
 
 
206
        styled_primitive("string-marker", "marker", 
 
207
                         [ 'point', 'text' ],
 
208
                         Styles::MarkerStringStyle,
 
209
                         'marker-string', [],
 
210
                         {},
 
211
                         'marker'
 
212
                         ) do |t, point, string, style, options|
 
213
          style.draw_string_marker(t, string, *point.to_figure_xy(t))
 
214
        end
 
215
 
181
216
 
182
217
        # options for arrows (and therefore tangents)
183
218
        ArrowOptions = {
192
227
          'line_style' => 'line-style',
193
228
        }
194
229
 
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
199
 
          options ||= {}
200
 
          options['head'] = head.to_figure_xy(t)
201
 
          options['tail'] = tail.to_figure_xy(t)
202
 
          t.show_arrow(options)
203
 
        end
204
 
 
205
 
        primitive("line", "line", [ 'point', 'point' ],
206
 
                  {
207
 
                    'color' => 'color',
208
 
                    'line_width' => 'float',
209
 
                    'line_style' => 'line-style',
210
 
                  }
211
 
                  ) do |t, tail,head, options|
212
 
          options ||= {}
213
 
          for a in ['head', 'tail'] 
214
 
            options["#{a}_marker"] = "None"
215
 
          end
216
 
          options['head'] = head.to_figure_xy(t)
217
 
          options['tail'] = tail.to_figure_xy(t)
218
 
          t.show_arrow(options)
219
 
        end
220
 
 
 
230
        styled_primitive("arrow", "arrow", 
 
231
                         [ 'point', 'point' ], 
 
232
                         Styles::ArrowStyle,
 
233
                         'arrow') do |t, tail, head, style, options|
 
234
          style.draw_arrow(t, *tail.to_figure_xy(t),
 
235
                           *head.to_figure_xy(t))
 
236
        end
 
237
 
 
238
        styled_primitive("line", "line", 
 
239
                         [ 'point', 'point' ],
 
240
                         Styles::StrokeStyle,
 
241
                         'line'
 
242
                  ) do |t, tail, head, style, options|
 
243
          style.draw_line(t, *(tail.to_figure_xy(t)),
 
244
                          *(head.to_figure_xy(t)))
 
245
        end
 
246
 
 
247
        # Here, we need to add deprecated options for backward
 
248
        # compatibility
 
249
 
 
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
 
253
        end
 
254
 
 
255
        styled_primitive("box", "box", 
 
256
                         [ 'point', 'point' ], 
 
257
                         Styles::BoxStyle,
 
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)
 
262
        end
 
263
 
 
264
 
 
265
        Commands::make_alias_for_option 'draw-box', 'fill_color', 'fill-color'
 
266
        Commands::make_alias_for_option 'draw-box', 'fill_transparency', 'fill-transparency'
221
267
 
222
268
        protected
223
269