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

« back to all changes in this revision

Viewing changes to lib/ctioga2/graphics/types/dimensions.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
# dimensions.rb: various ways to represent a dimension 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: 198 $', '$Date: 2010-11-30 00:48:23 +0100 (Tue, 30 Nov 2010) $')
 
20
 
 
21
  module Graphics
 
22
 
 
23
    module Types
 
24
 
 
25
      # A Dimension is an object that represents a dimension in the
 
26
      # different ways understood by Tioga:
 
27
      # * an "absolute" dimension, ie, in real units (postscript points)
 
28
      # * a "text" dimension, in units of the height of the current
 
29
      #   text object
 
30
      # * a frame/page/figure dimension, in units of the *current*
 
31
      #   frame/page/figure coordinates
 
32
      class Dimension
 
33
 
 
34
        include Tioga::Utils
 
35
 
 
36
        # What is the underlying representation of the dimension ?
 
37
        # * :bp in postscript points
 
38
        # * :dy in text height units
 
39
        # * :frame in frame coordinates
 
40
        # * :page in page coordinates
 
41
        # * :figure in figure coordinates
 
42
        attr_accessor :type
 
43
 
 
44
        # The orientation of the dimension: vertical (:y) or
 
45
        # horizontal (:x) ?
 
46
        attr_accessor :orientation
 
47
 
 
48
        # The actual dimension. The interpretation depends on the
 
49
        # value of #type.
 
50
        attr_accessor :value
 
51
 
 
52
        # Creates a Dimension object of the given _type_, the given
 
53
        # _value_ oriented along the given _orientation_
 
54
        def initialize(type, value, orientation = :x)
 
55
          @type = type
 
56
          @value = value
 
57
          @orientation = orientation
 
58
        end
 
59
 
 
60
        # Converts the Dimension to the *figure* coordinates of the
 
61
        # *current* figure in _t_.
 
62
        def to_figure(t, orientation = nil)
 
63
          orientation ||= @orientation
 
64
          case @type
 
65
          when :bp
 
66
            return t.send("convert_output_to_figure_d#{orientation}", @value) * 10
 
67
          when :dy
 
68
            return t.send("default_text_height_d#{orientation}") * @value
 
69
          when :frame
 
70
            return t.send("convert_frame_to_figure_d#{orientation}", @value)
 
71
          when :page
 
72
            return t.send("convert_page_to_figure_d#{orientation}", @value)
 
73
          when :figure
 
74
            return @value
 
75
          else
 
76
            raise "Invalid type for Dimension: #{@type}"
 
77
          end
 
78
        end
 
79
 
 
80
        # Converts the Dimension to the *frame* coordinates of the
 
81
        # *current* frame in _t_.
 
82
        def to_frame(t, orientation = nil)
 
83
          orientation ||= @orientation
 
84
          return t.send("convert_figure_to_frame_d#{orientation}", 
 
85
                        to_figure(t, orientation))
 
86
        end
 
87
 
 
88
        # Express the Dimension in units of text height (dy)
 
89
        def to_text_height(t, orientation = nil)
 
90
          orientation ||= @orientation
 
91
          return self.to_figure(t, orientation)/
 
92
            t.send("default_text_height_d#{orientation}")
 
93
        end
 
94
 
 
95
        # Replace this Dimension by _dimension_ if the latter is
 
96
        # bigger. Conserves the current orientation.
 
97
        def replace_if_bigger(t, dimension)
 
98
          if self.to_figure(t) < dimension.to_figure(t, @orientation)
 
99
            @type = dimension.type
 
100
            @value = dimension.value
 
101
          end
 
102
        end
 
103
 
 
104
        # Dimension conversion constants taken straight from the
 
105
        # TeXbook
 
106
        DimensionConversion = {
 
107
          "pt" => (72.0/72.27),
 
108
          "bp" => 1.0,
 
109
          "in" => 72.0,
 
110
          "cm" => (72.0/2.54),
 
111
          "mm" => (72.0/25.4),
 
112
        }
 
113
        
 
114
        # A regular expression that matches all dimensions.
 
115
        DimensionRegexp = /^\s*([+-]?\s*[\d.eE+-]+)\s*([a-zA-Z]+)?\s*$/
 
116
 
 
117
 
 
118
        # Creates a Dimension object from a _text_ specification. The
 
119
        # text should be in the forms
 
120
        # 
 
121
        #  value unit
 
122
        #  
 
123
        # where unit is one of bp, pt, in, mm, cm, dy (the latter
 
124
        # being one unit of height) f|figure, F|Frame|frame,
 
125
        # p|page. It can be ommitted, in which case it defaults to the
 
126
        # _default_ parameter.
 
127
        def self.from_text(text, orientation, default = :figure)
 
128
          # Absolute or :dy dimension
 
129
          if text =~ DimensionRegexp
 
130
            value = Float($1)
 
131
            unit = $2
 
132
            if ! unit
 
133
              unit = default
 
134
            elsif DimensionConversion.key?(unit.downcase)
 
135
              value *= DimensionConversion[unit.downcase]
 
136
              unit = :bp
 
137
            else
 
138
              case unit
 
139
              when /^dy$/i
 
140
                unit = :dy
 
141
              when /^F|(?i:frame)$/
 
142
                unit = :frame
 
143
              when /^f|(?i:figure)$/
 
144
                unit = :figure
 
145
              when /^p|(?i:page)$/
 
146
                unit = :page
 
147
              else
 
148
                raise "Unkown dimension unit: #{unit}"
 
149
              end
 
150
            end
 
151
            return Dimension.new(unit, value, orientation)
 
152
          else
 
153
            raise "Unkown Dimension specification: '#{text}'"
 
154
          end
 
155
        end
 
156
        
 
157
      end
 
158
 
 
159
    end
 
160
    
 
161
  end
 
162
 
 
163
end
 
164