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
26 scale
= { 't':1, 'u':1, 'v':1, 'w':1, 'x':1 }
38 def set(uscale
=None, vscale
=None, wscale
=None, xscale
=None, defaultunit
=None):
39 if uscale
is not None:
41 if vscale
is not None:
43 if wscale
is not None:
45 if xscale
is not None:
47 if defaultunit
is not None:
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
]
61 return _convert_to(l
, "m")
64 return _convert_to(l
, "cm")
67 return _convert_to(l
, "mm")
70 return _convert_to(l
, "inch")
73 return _convert_to(l
, "pt")
75 ################################################################################
76 # class for generic length
77 ################################################################################
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
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.
94 self
.t
= self
.u
= self
.v
= self
.w
= self
.x
= 0
95 l
= float(f
) * _m
[unit
or _default_unit
]
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
111 return cmp(tom(self
), tom(other
))
113 # why does -cmp(other, self) not work?
114 return -other
.__cmp
__(self
)
116 def __mul__(self
, factor
):
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
127 def __div__(self
, divisor
):
128 if isinstance(divisor
, length
):
129 return tom(self
) / tom(divisor
)
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
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
144 other
= length(other
)
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
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
163 other
= length(other
)
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
174 def __rsub__(self
, other
):
175 # convert to length if necessary
176 if not isinstance(other
, length
):
177 other
= length(other
)
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
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")
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")
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")
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")
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")