update to PyX 0.5
[PyX/mjg.git] / pyx / style.py
blobf751b6602ab79d7484dec2a5bfedcf89be10c72a
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) 2003-2004 Michael Schindler <m-schindler@users.sourceforge.net>
7 # Copyright (C) 2002-2004 André Wobst <wobsta@users.sourceforge.net>
9 # This file is part of PyX (http://pyx.sourceforge.net/).
11 # PyX is free software; you can redistribute it and/or modify
12 # it under the terms of the GNU General Public License as published by
13 # the Free Software Foundation; either version 2 of the License, or
14 # (at your option) any later version.
16 # PyX is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 # GNU General Public License for more details.
21 # You should have received a copy of the GNU General Public License
22 # along with PyX; if not, write to the Free Software
23 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 import math
26 import attr, unit, base
29 # base classes for stroke and fill styles
32 class strokestyle(base.PSOp): pass
34 class fillstyle(base.PSOp): pass
37 # common stroke styles
41 class linecap(attr.exclusiveattr, strokestyle):
43 """linecap of paths"""
45 def __init__(self, value=0):
46 attr.exclusiveattr.__init__(self, linecap)
47 self.value = value
49 def write(self, file):
50 file.write("%d setlinecap\n" % self.value)
52 linecap.butt = linecap(0)
53 linecap.round = linecap(1)
54 linecap.square = linecap(2)
55 linecap.clear = attr.clearclass(linecap)
58 class linejoin(attr.exclusiveattr, strokestyle):
60 """linejoin of paths"""
62 def __init__(self, value=0):
63 attr.exclusiveattr.__init__(self, linejoin)
64 self.value = value
66 def write(self, file):
67 file.write("%d setlinejoin\n" % self.value)
69 linejoin.miter = linejoin(0)
70 linejoin.round = linejoin(1)
71 linejoin.bevel = linejoin(2)
72 linejoin.clear = attr.clearclass(linejoin)
75 class miterlimit(attr.exclusiveattr, strokestyle):
77 """miterlimit of paths"""
79 def __init__(self, value=10.0):
80 attr.exclusiveattr.__init__(self, miterlimit)
81 self.value = value
83 def write(self, file):
84 file.write("%f setmiterlimit\n" % self.value)
86 miterlimit.lessthan180deg = miterlimit(1/math.sin(math.pi*180/360))
87 miterlimit.lessthan90deg = miterlimit(1/math.sin(math.pi*90/360))
88 miterlimit.lessthan60deg = miterlimit(1/math.sin(math.pi*60/360))
89 miterlimit.lessthan45deg = miterlimit(1/math.sin(math.pi*45/360))
90 miterlimit.lessthan11deg = miterlimit(10) # the default, approximately 11.4783 degress
91 miterlimit.clear = attr.clearclass(miterlimit)
94 class dash(attr.exclusiveattr, strokestyle):
96 """dash of paths"""
98 def __init__(self, pattern=[], offset=0, rellengths=0):
99 """set pattern with offset.
101 If rellengths is True, interpret all dash lengths relative to current linewidth.
103 attr.exclusiveattr.__init__(self, dash)
104 self.pattern = pattern
105 self.offset = offset
106 self.rellengths = rellengths
108 def write(self, file):
109 if self.rellengths:
110 sep = " currentlinewidth mul "
111 else:
112 sep = " "
113 patternstring = sep.join(["%g" % element for element in self.pattern])
114 file.write("[%s] %d setdash\n" % (patternstring, self.offset))
116 dash.clear = attr.clearclass(dash)
119 class linestyle(attr.exclusiveattr, strokestyle):
121 """linestyle (linecap together with dash) of paths"""
123 def __init__(self, c=linecap.butt, d=dash([])):
124 # XXX better, but at the moment not supported by attr.exlusiveattr would be:
125 # XXX attr.exclusiveattr.__init__(self, [linestyle, linecap, dash])
126 attr.exclusiveattr.__init__(self, linestyle)
127 self.c = c
128 self.d = d
130 def write(self, file):
131 self.c.write(file)
132 self.d.write(file)
134 linestyle.solid = linestyle(linecap.butt, dash([]))
135 linestyle.dashed = linestyle(linecap.butt, dash([2]))
136 linestyle.dotted = linestyle(linecap.round, dash([0, 3]))
137 linestyle.dashdotted = linestyle(linecap.round, dash([0, 3, 3, 3]))
138 linestyle.clear = attr.clearclass(linestyle)
141 class linewidth(unit.length, attr.sortbeforeexclusiveattr, strokestyle):
143 """linewidth of paths"""
145 def __init__(self, l="0 cm"):
146 unit.length.__init__(self, l=l, default_type="w")
147 attr.sortbeforeexclusiveattr.__init__(self, linewidth, [dash, linestyle])
149 def write(self, file):
150 file.write("%f setlinewidth\n" % unit.topt(self))
152 _base = 0.02
154 linewidth.THIN = linewidth("%f cm" % (_base/math.sqrt(32)))
155 linewidth.THIn = linewidth("%f cm" % (_base/math.sqrt(16)))
156 linewidth.THin = linewidth("%f cm" % (_base/math.sqrt(8)))
157 linewidth.Thin = linewidth("%f cm" % (_base/math.sqrt(4)))
158 linewidth.thin = linewidth("%f cm" % (_base/math.sqrt(2)))
159 linewidth.normal = linewidth("%f cm" % _base)
160 linewidth.thick = linewidth("%f cm" % (_base*math.sqrt(2)))
161 linewidth.Thick = linewidth("%f cm" % (_base*math.sqrt(4)))
162 linewidth.THick = linewidth("%f cm" % (_base*math.sqrt(8)))
163 linewidth.THIck = linewidth("%f cm" % (_base*math.sqrt(16)))
164 linewidth.THICk = linewidth("%f cm" % (_base*math.sqrt(32)))
165 linewidth.THICK = linewidth("%f cm" % (_base*math.sqrt(64)))
166 linewidth.clear = attr.clearclass(linewidth)