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
|