I'm sorry, I've just seen that I missed to checkin the new pyx/graph/style.py ...
[PyX.git] / pyx / unit.py
blobdeebca063007e9bca07434bc79e0aac5760d19d3
1 #!/usr/bin/env python
2 # -*- coding: ISO-8859-1 -*-
5 # Copyright (C) 2002-2004 Jörg Lehmann <joergl@users.sourceforge.net>
6 # Copyright (C) 2002-2004 André Wobst <wobsta@users.sourceforge.net>
8 # This file is part of PyX (http://pyx.sourceforge.net/).
10 # PyX is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 2 of the License, or
13 # (at your option) any later version.
15 # PyX is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
20 # You should have received a copy of the GNU General Public License
21 # along with PyX; if not, write to the Free Software
22 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 import types
26 scale = { 't':1, 'u':1, 'v':1, 'w':1, 'x':1 }
28 _default_unit = "cm"
30 _m = {
31 'm' : 1,
32 'cm': 0.01,
33 'mm': 0.001,
34 'inch': 0.01*2.54,
35 'pt': 0.01*2.54/72,
38 def set(uscale=None, vscale=None, wscale=None, xscale=None, defaultunit=None):
39 if uscale is not None:
40 scale['u'] = uscale
41 if vscale is not None:
42 scale['v'] = vscale
43 if wscale is not None:
44 scale['w'] = wscale
45 if xscale is not None:
46 scale['x'] = xscale
47 if defaultunit is not None:
48 global _default_unit
49 _default_unit = defaultunit
52 def _convert_to(l, dest_unit="m"):
53 if type(l) in (types.IntType, types.LongType, types.FloatType):
54 return l * _m[_default_unit] * scale['u'] / _m[dest_unit]
55 elif not isinstance(l, length):
56 l = length(l) # convert to length instance if necessary
58 return (l.t + l.u*scale['u'] + l.v*scale['v'] + l.w*scale['w'] + l.x*scale['x']) / _m[dest_unit]
60 def tom(l):
61 return _convert_to(l, "m")
63 def tocm(l):
64 return _convert_to(l, "cm")
66 def tomm(l):
67 return _convert_to(l, "mm")
69 def toinch(l):
70 return _convert_to(l, "inch")
72 def topt(l):
73 return _convert_to(l, "pt")
75 ################################################################################
76 # class for generic length
77 ################################################################################
79 class length:
80 """ PyX lengths
82 PyX lengths are composed of five components (t=true, u=user, v=visual,
83 w=width, and x=TeX) which can be scaled separately (except for the true
84 component, which is always unscaled). Lengths can be constructed in units
85 of "pt", "mm", "cm", "m" and "inch". When no unit is given, a module
86 default is used, which can be changed with the help of the module level function
87 set().
88 """
90 def __init__(self, f=0, type="u", unit=None):
91 """ create a length instance of the given type with a length f
92 in the given unit. If unit is not set, the currently set default unit is used.
93 """
94 self.t = self.u = self.v = self.w = self.x = 0
95 l = float(f) * _m[unit or _default_unit]
96 if type == "t":
97 self.t = l
98 elif type == "u":
99 self.u = l
100 elif type == "v":
101 self.v = l
102 elif type == "w":
103 self.w = l
104 elif type == "x":
105 self.x = l
107 def __cmp__(self, other):
108 # we try to convert self and other into meters and
109 # if this fails, we give other a chance to do the comparison
110 try:
111 return cmp(tom(self), tom(other))
112 except:
113 # why does -cmp(other, self) not work?
114 return -other.__cmp__(self)
116 def __mul__(self, factor):
117 result = length()
118 result.t = factor * self.t
119 result.u = factor * self.u
120 result.v = factor * self.v
121 result.w = factor * self.w
122 result.x = factor * self.x
123 return result
125 __rmul__=__mul__
127 def __div__(self, divisor):
128 if isinstance(divisor, length):
129 return tom(self) / tom(divisor)
130 result = length()
131 result.t = self.t / divisor
132 result.u = self.u / divisor
133 result.v = self.v / divisor
134 result.w = self.w / divisor
135 result.x = self.x / divisor
136 return result
138 def __add__(self, other):
139 # convert to length if necessary
140 if not isinstance(other, length):
141 # if other is not a length, we try to convert it into a length and
142 # if this fails, we give other a chance to do the addition
143 try:
144 other = length(other)
145 except:
146 return other + self
147 result = length()
148 result.t = self.t + other.t
149 result.u = self.u + other.u
150 result.v = self.v + other.v
151 result.w = self.w + other.w
152 result.x = self.x + other.x
153 return result
155 __radd__ = __add__
157 def __sub__(self, other):
158 # convert to length if necessary
159 if not isinstance(other, length):
160 # if other is not a length, we try to convert it into a length and
161 # if this fails, we give other a chance to do the subtraction
162 try:
163 other = length(other)
164 except:
165 return -other + self
166 result = length()
167 result.t = self.t - other.t
168 result.u = self.u - other.u
169 result.v = self.v - other.v
170 result.w = self.w - other.w
171 result.x = self.x - other.x
172 return result
174 def __rsub__(self, other):
175 # convert to length if necessary
176 if not isinstance(other, length):
177 other = length(other)
178 result = length()
179 result.t = other.t - self.t
180 result.u = other.u - self.u
181 result.v = other.v - self.v
182 result.w = other.w - self.w
183 result.x = other.x - self.x
184 return result
186 def __neg__(self):
187 result = length()
188 result.t = -self.t
189 result.u = -self.u
190 result.v = -self.v
191 result.w = -self.w
192 result.x = -self.x
193 return result
195 def __str__(self):
196 return "(%(t)f t + %(u)f u + %(v)f v + %(w)f w + %(x)f x) m" % self.__dict__
199 ################################################################################
200 # predefined instances which can be used as length units
201 ################################################################################
203 # user lengths and unqualified length which are also user length
204 u_pt = pt = length(1, type="u", unit="pt")
205 u_m = m = length(1, type="u", unit="m")
206 u_mm = mm = length(1, type="u", unit="mm")
207 u_cm = cm = length(1, type="u", unit="cm")
208 u_inch = inch = length(1, type="u", unit="inch")
210 # true lengths
211 t_pt = length(1, type="t", unit="pt")
212 t_m = length(1, type="t", unit="m")
213 t_mm = length(1, type="t", unit="mm")
214 t_cm = length(1, type="t", unit="cm")
215 t_inch = length(1, type="t", unit="inch")
217 # visual lengths
218 v_pt = length(1, type="v", unit="pt")
219 v_m = length(1, type="v", unit="m")
220 v_mm = length(1, type="v", unit="mm")
221 v_cm = length(1, type="v", unit="cm")
222 v_inch = length(1, type="v", unit="inch")
224 # width lengths
225 w_pt = length(1, type="w", unit="pt")
226 w_m = length(1, type="w", unit="m")
227 w_mm = length(1, type="w", unit="mm")
228 w_cm = length(1, type="w", unit="cm")
229 w_inch = length(1, type="w", unit="inch")
231 # TeX lengths
232 x_pt = length(1, type="x", unit="pt")
233 x_m = length(1, type="x", unit="m")
234 x_mm = length(1, type="x", unit="mm")
235 x_cm = length(1, type="x", unit="cm")
236 x_inch = length(1, type="x", unit="inch")