File: dimension.rb

package info (click to toggle)
ctioga 1.10-1
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 1,052 kB
  • ctags: 953
  • sloc: ruby: 9,306; sh: 504; makefile: 6
file content (133 lines) | stat: -rw-r--r-- 4,416 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# dimension.rb: a class handling relative/absolute dimensions
# copyright (c) 2007,2008 by Vincent Fourmond: 
  
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
  
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details (in the COPYING file).

require 'CTioga/log'

module CTioga

  Version::register_svn_info('$Revision: 831 $', '$Date: 2008-08-19 14:23:54 +0200 (Tue, 19 Aug 2008) $')

  # A class which represents a dimension, either absolute or
  # relative.
  class Dimension

    # TODO: we should extend this class to provide a comprehensive
    # way to specify the position of a point and provide coordinate
    # conversions to frame (including in postscript points) and
    # figure coordinates.

    include Tioga::Utils

    # The type of the dimension :
    # * :abs means absolute
    # * :rel is relative
    attr_accessor :type

    # The actual dimension. Its meaning depends on the
    # value of type:
    # * :abs : the value is in bp points
    # * :rel : the value is a fraction of the corresponding size
    #   in the given plot.
    attr_accessor :value

    # Creates a dimension. If the dimension contains a letter,
    # it will be interpreted in terms of a TeX size.
    # If it contains a percent - or nothing, it will be interpreted as
    # a relative measure. If it is a float, it will be interpreted
    # as a relative measure unless _type_ is not nil.
    def initialize(spec, type = nil)
      case spec
      when /^\s*[\d.]+[a-zA-Z]+\s*$/
        @type = :abs
        @value = tex_dimension_to_bp(spec)
      when /^\s*([\d.]+)\s*%\s*$/
        @type = :rel
        @value = $1.to_f * 0.01 # Value in percents
      when Float
        @value = spec
        @type = type || :rel
      when /^\s*([\d.]+)/
        @value = spec.to_f
        @type = type || :rel
      end
    end

    # Converts self to a relative dimension. _frames_ is the frames
    # of the current object (outer_frames) expressed in big points.
    def to_relative(frames, side = :horizontal)
      # The easy thing first:
      return @value if @type == :rel
      if side == :horizontal
        return @value/((frames[1] - frames[0]).abs)
      else
        return @value/((frames[3] - frames[2]).abs)
      end
    end

    # Converts self to an absolute dimension. _frames_ is the frames
    # of the current object (outer_frames) expressed in big points.
    def to_absolute(frames, side = :horizontal)
      # The easy thing first:
      return @value if @type == :abs
      if side == :horizontal
        return @value * ((frames[1] - frames[0]).abs)
      else
        return @value * ((frames[3] - frames[2]).abs)
      end
    end

    # Scales the dimension by the given factor
    def scale!(fact)
      @value *= fact
      return self
    end


    # Converts an absolute dimension in terms of a relative
    # one, using the given frames.
    def Dimension.absolute_to_relative(dimensions, frames)
      ret_val = []
      ret_val[0] = dimensions[0]/((frames[1] - frames[0]).abs)
      ret_val[1] = dimensions[1]/((frames[1] - frames[0]).abs)
      ret_val[2] = dimensions[2]/((frames[3] - frames[2]).abs)
      ret_val[3] = dimensions[3]/((frames[3] - frames[2]).abs)
      return ret_val
    end

    def self.update_extensions(extensions, new_ext)
      4.times do |i|
        extensions[i] = new_ext[i] unless  new_ext[i] < extensions[i]
      end
      return extensions
    end
  end

  # A dimension that represents text sizes. Absolute has the same meaning,
  # but relative values are relative to default_text_height_x/y
  class TextDimension < Dimension
    
    # These two functions don't make any sense here
    undef :to_relative, :to_absolute

    # Converts the dimension to figure coordinates in the given direction
    def to_figure(t, direction)
      if @type == :rel
        return @value * t.send("default_text_height_d#{direction.to_s}")
      else
        return t.send("convert_output_to_figure_d#{direction.to_s}", 
                      @value * 10)
      end
    end
  end

end