more restructuring of the unit system
[PyX/mjg.git] / pyx / unit.py
blob07b1b18da2b8c589b3d32702e92852aacbfe1f45
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 import copy
25 import types
26 import helper
28 scale = { 't':1, 'u':1, 'v':1, 'w':1, 'x':1 }
30 _default_unit = "cm"
32 _m = {
33 'm' : 1,
34 'cm': 0.01,
35 'mm': 0.001,
36 'inch': 0.01*2.54,
37 'pt': 0.01*2.54/72,
40 def set(uscale=None, vscale=None, wscale=None, xscale=None, defaultunit=None):
41 if uscale is not None:
42 scale['u'] = uscale
43 if vscale is not None:
44 scale['v'] = vscale
45 if wscale is not None:
46 scale['w'] = wscale
47 if xscale is not None:
48 scale['x'] = xscale
49 if defaultunit is not None:
50 global _default_unit
51 _default_unit = defaultunit
54 def _convert_to(l, dest_unit="m"):
55 if type(l) in (types.IntType, types.LongType, types.FloatType):
56 return l * _m[_default_unit] * scale['u'] / _m[dest_unit]
57 elif not isinstance(l, length):
58 l = length(l) # convert to length instance if necessary
60 return (l.t + l.u*scale['u'] + l.v*scale['v'] + l.w*scale['w'] + l.x*scale['x']) / _m[dest_unit]
62 def tom(l):
63 return _convert_to(l, "m")
65 def tocm(l):
66 return _convert_to(l, "cm")
68 def tomm(l):
69 return _convert_to(l, "mm")
71 def toinch(l):
72 return _convert_to(l, "inch")
74 def topt(l):
75 return _convert_to(l, "pt")
77 ################################################################################
78 # class for generic length
79 ################################################################################
81 class length:
82 """ general lengths
84 XXX write me
86 """
88 def __init__(self, f, type="u", unit=None):
89 self.t = self.u = self.v = self.w = self.x = 0
90 l = f * _m[unit or _default_unit]
91 if type == "t":
92 self.t = l
93 elif type == "u":
94 self.u = l
95 elif type == "v":
96 self.v = l
97 elif type == "w":
98 self.w = l
99 elif type == "x":
100 self.x = l
102 def __cmp__(self, other):
103 return cmp(tom(self), tom(other))
105 def __mul__(self, factor):
106 result = copy.copy(self)
107 result.t *= factor
108 result.u *= factor
109 result.v *= factor
110 result.w *= factor
111 result.x *= factor
112 return result
114 __rmul__=__mul__
116 def __div__(self, factor):
117 result = copy.copy(self)
118 result.t /= factor
119 result.u /= factor
120 result.v /= factor
121 result.w /= factor
122 result.x /= factor
123 return result
125 def __add__(self, other):
126 # convert to length if necessary
127 if not isinstance(other, length):
128 other = length(other)
129 result = copy.copy(self)
130 result.t += other.t
131 result.u += other.u
132 result.v += other.v
133 result.w += other.w
134 result.x += other.x
135 return result
137 __radd__=__add__
139 def __sub__(self, other):
140 # convert to length if necessary
141 if not isinstance(other, length):
142 other = length(other)
143 result = copy.copy(self)
144 result.t -= other.t
145 result.u -= other.u
146 result.v -= other.v
147 result.w -= other.w
148 result.x -= other.x
149 return result
151 def __rsub__(self, other):
152 # convert to length if necessary
153 if not isinstance(other, length):
154 other = length(other)
155 result = copy.copy(self)
156 result.t = other.t - self.t
157 result.u = other.u - self.u
158 result.v = other.v - self.v
159 result.w = other.w - self.w
160 result.x = other.x - self.x
161 return result
163 def __neg__(self):
164 result = copy.copy(self)
165 result.t *= -1
166 result.u *= -1
167 result.v *= -1
168 result.w *= -1
169 result.x *= -1
170 return result
172 def __str__(self):
173 return "(%(t)f t + %(u)f u + %(v)f v + %(w)f w + %(x)f x) m" % self.length.__dict__
176 ################################################################################
177 # predefined instances which can be used as length units
178 ################################################################################
180 # user lengths and unqualified length which are also user length
181 u_pt = pt = length(1, type="u", unit="pt")
182 u_m = m = length(1, type="u", unit="m")
183 u_mm = mm = length(1, type="u", unit="mm")
184 u_cm = cm = length(1, type="u", unit="cm")
185 u_inch = inch = length(1, type="u", unit="inch")
187 # true lengths
188 t_pt = length(1, type="t", unit="pt")
189 t_m = length(1, type="t", unit="m")
190 t_mm = length(1, type="t", unit="mm")
191 t_cm = length(1, type="t", unit="cm")
192 t_inch = length(1, type="t", unit="inch")
194 # visual lengths
195 v_pt = length(1, type="v", unit="pt")
196 v_m = length(1, type="v", unit="m")
197 v_mm = length(1, type="v", unit="mm")
198 v_cm = length(1, type="v", unit="cm")
199 v_inch = length(1, type="v", unit="inch")
201 # width lengths
202 w_pt = length(1, type="w", unit="pt")
203 w_m = length(1, type="w", unit="m")
204 w_mm = length(1, type="w", unit="mm")
205 w_cm = length(1, type="w", unit="cm")
206 w_inch = length(1, type="w", unit="inch")
208 # TeX lengths
209 x_pt = length(1, type="x", unit="pt")
210 x_m = length(1, type="x", unit="m")
211 x_mm = length(1, type="x", unit="mm")
212 x_cm = length(1, type="x", unit="cm")
213 x_inch = length(1, type="x", unit="inch")