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
26 import attr
, unit
, canvas
29 # base classes for stroke and fill styles
32 class strokestyle(canvas
.canvasitem
): pass
34 class fillstyle(canvas
.canvasitem
): 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
)
49 def outputPS(self
, file, writer
, context
):
50 file.write("%d setlinecap\n" % self
.value
)
52 def outputPDF(self
, file, writer
, context
):
53 file.write("%d J\n" % self
.value
)
55 linecap
.butt
= linecap(0)
56 linecap
.round = linecap(1)
57 linecap
.square
= linecap(2)
58 linecap
.clear
= attr
.clearclass(linecap
)
61 class linejoin(attr
.exclusiveattr
, strokestyle
):
63 """linejoin of paths"""
65 def __init__(self
, value
=0):
66 attr
.exclusiveattr
.__init
__(self
, linejoin
)
69 def outputPS(self
, file, writer
, context
):
70 file.write("%d setlinejoin\n" % self
.value
)
72 def outputPDF(self
, file, writer
, context
):
73 file.write("%d j\n" % self
.value
)
75 linejoin
.miter
= linejoin(0)
76 linejoin
.round = linejoin(1)
77 linejoin
.bevel
= linejoin(2)
78 linejoin
.clear
= attr
.clearclass(linejoin
)
81 class miterlimit(attr
.exclusiveattr
, strokestyle
):
83 """miterlimit of paths"""
85 def __init__(self
, value
=10.0):
86 attr
.exclusiveattr
.__init
__(self
, miterlimit
)
89 def outputPS(self
, file, writer
, context
):
90 file.write("%f setmiterlimit\n" % self
.value
)
92 def outoutPDF(self
, file):
93 file.write("%f M\n" % self
.value
)
95 miterlimit
.lessthan180deg
= miterlimit(1/math
.sin(math
.pi
*180/360))
96 miterlimit
.lessthan90deg
= miterlimit(1/math
.sin(math
.pi
*90/360))
97 miterlimit
.lessthan60deg
= miterlimit(1/math
.sin(math
.pi
*60/360))
98 miterlimit
.lessthan45deg
= miterlimit(1/math
.sin(math
.pi
*45/360))
99 miterlimit
.lessthan11deg
= miterlimit(10) # the default, approximately 11.4783 degress
100 miterlimit
.clear
= attr
.clearclass(miterlimit
)
103 class dash(attr
.exclusiveattr
, strokestyle
):
107 def __init__(self
, pattern
=[], offset
=0, rellengths
=0):
108 """set pattern with offset.
110 If rellengths is True, interpret all dash lengths relative to current linewidth.
112 attr
.exclusiveattr
.__init
__(self
, dash
)
113 self
.pattern
= pattern
115 self
.rellengths
= rellengths
117 def outputPS(self
, file, writer
, context
):
119 sep
= " currentlinewidth mul "
122 patternstring
= sep
.join(["%f" % element
for element
in self
.pattern
])
123 file.write("[%s] %d setdash\n" % (patternstring
, self
.offset
))
125 def outputPDF(self
, file, writer
, context
):
127 raise RuntimeError("rellengths currently not supported in pdf output")
128 file.write("[%s] %d d\n" % (" ".join(["%f" % element
for element
in self
.pattern
]), self
.offset
))
130 dash
.clear
= attr
.clearclass(dash
)
133 class linestyle(attr
.exclusiveattr
, strokestyle
):
135 """linestyle (linecap together with dash) of paths"""
137 def __init__(self
, c
=linecap
.butt
, d
=dash([])):
138 # XXX better, but at the moment not supported by attr.exlusiveattr would be:
139 # XXX attr.exclusiveattr.__init__(self, [linestyle, linecap, dash])
140 attr
.exclusiveattr
.__init
__(self
, linestyle
)
144 def outputPS(self
, file, writer
, context
):
145 self
.c
.outputPS(file, writer
, context
)
146 self
.d
.outputPS(file, writer
, context
)
148 def outputPDF(self
, file, writer
, context
):
149 self
.c
.outputPDF(file, writer
, context
)
150 self
.d
.outputPDF(file, writer
, context
)
152 linestyle
.solid
= linestyle(linecap
.butt
, dash([]))
153 linestyle
.dashed
= linestyle(linecap
.butt
, dash([2]))
154 linestyle
.dotted
= linestyle(linecap
.round, dash([0, 2]))
155 linestyle
.dashdotted
= linestyle(linecap
.round, dash([0, 2, 2, 2]))
156 linestyle
.clear
= attr
.clearclass(linestyle
)
159 class linewidth(unit
.length
, attr
.sortbeforeexclusiveattr
, strokestyle
):
161 """linewidth of paths"""
163 def __init__(self
, *args
, **kwargs
):
164 unit
.length
.__init
__(self
, *args
, **kwargs
)
165 attr
.sortbeforeexclusiveattr
.__init
__(self
, linewidth
, [dash
, linestyle
])
167 def outputPS(self
, file, writer
, context
):
168 file.write("%f setlinewidth\n" % unit
.topt(self
))
169 context
.linewidth_pt
= unit
.topt(self
)
171 def outputPDF(self
, file, writer
, context
):
172 file.write("%f w\n" % unit
.topt(self
))
173 context
.linewidth_pt
= unit
.topt(self
)
177 linewidth
.THIN
= linewidth(_base
/math
.sqrt(32), type="w", unit
="cm")
178 linewidth
.THIn
= linewidth(_base
/math
.sqrt(16), type="w", unit
="cm")
179 linewidth
.THin
= linewidth(_base
/math
.sqrt(8), type="w", unit
="cm")
180 linewidth
.Thin
= linewidth(_base
/math
.sqrt(4), type="w", unit
="cm")
181 linewidth
.thin
= linewidth(_base
/math
.sqrt(2), type="w", unit
="cm")
182 linewidth
.normal
= linewidth(_base
, type="w", unit
="cm")
183 linewidth
.thick
= linewidth(_base
*math
.sqrt(2), type="w", unit
="cm")
184 linewidth
.Thick
= linewidth(_base
*math
.sqrt(4), type="w", unit
="cm")
185 linewidth
.THick
= linewidth(_base
*math
.sqrt(8), type="w", unit
="cm")
186 linewidth
.THIck
= linewidth(_base
*math
.sqrt(16), type="w", unit
="cm")
187 linewidth
.THICk
= linewidth(_base
*math
.sqrt(32), type="w", unit
="cm")
188 linewidth
.THICK
= linewidth(_base
*math
.sqrt(64), type="w", unit
="cm")
189 linewidth
.clear
= attr
.clearclass(linewidth
)