~ubuntu-branches/ubuntu/oneiric/ctioga2/oneiric

« back to all changes in this revision

Viewing changes to lib/ctioga2/graphics/styles/texts.rb

  • Committer: Bazaar Package Importer
  • Author(s): Vincent Fourmond
  • Date: 2011-01-24 21:36:06 UTC
  • Revision ID: james.westby@ubuntu.com-20110124213606-9ettx0ugl83z0bzp
Tags: upstream-0.1
ImportĀ upstreamĀ versionĀ 0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# texts.rb: style for textual objects
 
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
# This module contains all the classes used by ctioga
 
18
module CTioga2
 
19
 
 
20
  Version::register_svn_info('$Revision: 197 $', '$Date: 2010-11-29 14:26:12 +0100 (Mon, 29 Nov 2010) $')
 
21
 
 
22
  module Graphics
 
23
 
 
24
    module Styles
 
25
 
 
26
      # The style of a text object. This class is suitable for
 
27
      # inclusion as a Hash to FigureMaker#show_axis, for the tick
 
28
      # labels.
 
29
      class BaseTextStyle < BasicStyle
 
30
        
 
31
        # The angle of the text
 
32
        attr_accessor :angle
 
33
 
 
34
        # The 'shift' of the text. Only meaningful for axes and tick
 
35
        # labels, where the position of the text is specified using a
 
36
        # side rather than a precise position
 
37
        attr_accessor :shift
 
38
 
 
39
        # The scale of the text
 
40
        attr_accessor :scale
 
41
 
 
42
        # The vertical alignment 
 
43
        attr_accessor :alignement
 
44
 
 
45
        # The horizontal alignment
 
46
        attr_accessor :justification
 
47
 
 
48
        # Draw the _text_ at the given location with the given style.
 
49
        # If _y_ is _nil_, then _x_or_loc_ is taken to be a location
 
50
        # (see FigureMaker#show_text).
 
51
        def draw_text(t, text, x_or_loc, y = nil, measure = nil)
 
52
          dict = prepare_show_text_dict(text, x_or_loc, y, measure)
 
53
          t.show_text(dict)
 
54
        end
 
55
 
 
56
        protected
 
57
        
 
58
        # Prepares the dictionnary for use with show_text
 
59
        def prepare_show_text_dict(text, x_or_loc, y = nil, measure = nil)
 
60
          dict = self.to_hash
 
61
          dict['text'] = text
 
62
          if y
 
63
            dict['at'] = [x_or_loc, y]
 
64
          else
 
65
            # Perform automatic conversion on the location
 
66
            case x_or_loc
 
67
            when Symbol, Types::PlotLocation
 
68
              ## @todo It won't be easy to implement shifts for this,
 
69
              ## though it may be useful eventually.
 
70
              x_or_loc = Types::PlotLocation.new(x_or_loc).tioga_location
 
71
            end
 
72
            dict['loc'] = x_or_loc
 
73
          end
 
74
          if measure
 
75
            dict['measure'] = measure
 
76
          end
 
77
          return dict
 
78
        end
 
79
      end
 
80
 
 
81
 
 
82
 
 
83
      # The style of a full text object.
 
84
      class FullTextStyle < BaseTextStyle
 
85
        # The color of the text
 
86
        attr_accessor :color
 
87
 
 
88
        # The (horizontal) position with respect to a location. You'll
 
89
        # seldom need that.
 
90
        attr_accessor :position
 
91
      end
 
92
 
 
93
      # A hash that can be used as a base for optional arguments to
 
94
      # things that take texts.
 
95
      FullTextStyleOptions = {
 
96
        'angle' => CmdArg.new('float'),
 
97
        'shift' => CmdArg.new('float'),
 
98
        'scale' => CmdArg.new('float'),
 
99
        'justification' => CmdArg.new('justification'),
 
100
        'color' => CmdArg.new('color'),
 
101
        'align' => CmdArg.new('alignment'),
 
102
      }
 
103
 
 
104
      # A label.
 
105
      class TextLabel < FullTextStyle
 
106
        # The text of the label. _nil_ or _false_ means there will be
 
107
        # no text displayed
 
108
        attr_accessor :text
 
109
        
 
110
        # The location of the label.
 
111
        #
 
112
        # @todo This will have to eventually use PlotLocation, as it
 
113
        # makes much more sense.
 
114
        attr_accessor :loc
 
115
 
 
116
        def initialize(text = nil)
 
117
          @text = text
 
118
        end
 
119
        
 
120
        # Draw the label, if #text is not _nil_ or _false_.
 
121
        # Attributes such as scale, shift and angle are taken from the
 
122
        # corresponding _default_ if _default_ isn't nil.
 
123
        def draw(t, default = nil, measure = nil)
 
124
          if @text
 
125
            dict = prepare_label_dict(t, default, measure) 
 
126
            t.show_text(dict)
 
127
          end
 
128
        end
 
129
 
 
130
        # Gets the extension of the label, in units of text height.
 
131
        # Default values for the various parameters are taken from the
 
132
        # _default_ parameter if they are not specified.
 
133
        def label_extension(t, default = nil, location = nil)
 
134
          if @text
 
135
            dict = prepare_label_dict(t, default, nil)
 
136
            extra = 0
 
137
            if location
 
138
              extra = location.label_extra_space(t)
 
139
            end
 
140
            return (dict['shift'] + extra) * dict['scale']
 
141
          else
 
142
            return 0
 
143
          end
 
144
        end
 
145
 
 
146
        protected 
 
147
        
 
148
        def prepare_label_dict(t, default = nil, measure = nil)
 
149
          dict = prepare_show_text_dict(@text, @loc, nil, measure)
 
150
          if default
 
151
            for attribute in %w(scale angle shift)
 
152
              if ! dict.key?(attribute)
 
153
                dict[attribute] = t.send("#{default}_#{attribute}")
 
154
              end
 
155
            end
 
156
          end
 
157
          return dict
 
158
        end
 
159
 
 
160
      end
 
161
 
 
162
      # Same thing as FullTextStyleOptions, but also permits to
 
163
      # override the #text part of the whole stuff..
 
164
      FullTextLabelOptions = FullTextStyleOptions.dup
 
165
      FullTextLabelOptions['text'] = CmdArg.new('text')
 
166
 
 
167
 
 
168
 
 
169
      # The style for a string marker. Hmmm, this is somewhat
 
170
      # redundant with TiogaPrimitiveCall::MarkerOptions and I don't
 
171
      # like that.
 
172
      class MarkerStringStyle < BasicStyle
 
173
        
 
174
        MarkerOptions = {
 
175
          'color' => 'color',
 
176
          'stroke_color' => 'color',
 
177
          'fill_color' => 'color',
 
178
          'scale' => 'float',
 
179
          'horizontal_scale' => 'float',
 
180
          'vertical_scale' => 'float',
 
181
          'angle' => 'float',
 
182
          'justification' => 'justification',
 
183
          'alignment' => 'alignment',
 
184
        }
 
185
 
 
186
 
 
187
        # The angle of the text
 
188
        attr_accessor :angle
 
189
 
 
190
        # The scale of the text
 
191
        attr_accessor :scale
 
192
 
 
193
        # The horizontal scale of the text
 
194
        attr_accessor :horizontal_scale
 
195
 
 
196
        # The vertical scale of the text
 
197
        attr_accessor :vertical_scale
 
198
 
 
199
        # The vertical alignment 
 
200
        attr_accessor :alignement
 
201
 
 
202
        # The horizontal alignment
 
203
        attr_accessor :justification
 
204
 
 
205
        # Colors
 
206
        attr_accessor :color
 
207
        attr_accessor :stroke_color
 
208
        attr_accessor :fill_color
 
209
 
 
210
        # A number between 1 to 14 -- a PDF font
 
211
        attr_accessor :font
 
212
 
 
213
        # The rendering mode.
 
214
        attr_accessor :mode
 
215
        
 
216
        def initialize
 
217
          # It make sense to use both by default, as it would be
 
218
          # confusing to provide both fill_ and stroke_color that
 
219
          # don't have effects by default...
 
220
          @mode = Tioga::FigureConstants::FILL_AND_STROKE
 
221
        end
 
222
 
 
223
 
 
224
        # Draws the string marker at the given location
 
225
        def draw_string_marker(t, text, x, y)
 
226
          dict = self.to_hash
 
227
          dict['text'] = text
 
228
          dict['at'] = [x, y]
 
229
          # TODO !
 
230
          dict['mode'] = 
 
231
          t.show_marker(dict)
 
232
        end
 
233
 
 
234
        # Returns the true vertical scale of the marker
 
235
        def real_vertical_scale
 
236
          return (@vertical_scale || 1.0) * (@scale || 1.0)
 
237
        end
 
238
      end
 
239
      
 
240
      StringMarkerOptions = {
 
241
        'color' => CmdArg.new('color'),
 
242
        'stroke_color' => CmdArg.new('color'),
 
243
        'fill_color' => CmdArg.new('color'),
 
244
        'scale' => CmdArg.new('float'),
 
245
        'horizontal_scale' => CmdArg.new('float'),
 
246
        'vertical_scale' => CmdArg.new('float'),
 
247
        'angle' => CmdArg.new('float'),
 
248
        'justification' => CmdArg.new('justification'),
 
249
        'alignment' => CmdArg.new('alignment'),
 
250
        'font' => CmdArg.new('pdf-font')
 
251
      }
 
252
 
 
253
      # A LaTeX font. It should be applied to text using the function
 
254
      # #fontify.
 
255
      #
 
256
      # \todo add real font attributes (family, and so on...)
 
257
      class LaTeXFont
 
258
        # The font command (bf, sf...). Naive but effective !
 
259
        attr_accessor :font_command
 
260
 
 
261
        def initialize
 
262
          # Nothing to be done
 
263
        end
 
264
 
 
265
        def self.from_text(txt)
 
266
          # For now, only the naive way of things:
 
267
          font = self.new
 
268
          font.font_command = txt
 
269
          return font
 
270
        end
 
271
 
 
272
        # Returns text wrapping _txt_ with the appropriate functions
 
273
        # to get the appropriate font in LaTeX.
 
274
        def fontify(txt)
 
275
          if @font_command
 
276
            return "{\\#{@font_command} #{txt}}"
 
277
          end
 
278
          return txt
 
279
        end
 
280
        
 
281
      end
 
282
      
 
283
 
 
284
    end
 
285
  end
 
286
end
 
287