1 # -*- coding: ISO-8859-1 -*-
4 # Copyright (C) 2002-2006 Jörg Lehmann <joergl@users.sourceforge.net>
5 # Copyright (C) 2003-2004,2006 Michael Schindler <m-schindler@users.sourceforge.net>
6 # Copyright (C) 2002-2006 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
25 import attr
, unit
, canvas
28 # base classes for stroke and fill styles
31 class strokestyle(canvas
.canvasitem
): pass
33 class fillstyle(canvas
.canvasitem
): pass
36 # common stroke styles
40 class linecap(attr
.exclusiveattr
, strokestyle
):
42 """linecap of paths"""
44 def __init__(self
, value
=0):
45 attr
.exclusiveattr
.__init
__(self
, linecap
)
48 def processPS(self
, file, writer
, context
, registry
, bbox
):
49 file.write("%d setlinecap\n" % self
.value
)
51 def processPDF(self
, file, writer
, context
, registry
, bbox
):
52 file.write("%d J\n" % self
.value
)
54 linecap
.butt
= linecap(0)
55 linecap
.round = linecap(1)
56 linecap
.square
= linecap(2)
57 linecap
.clear
= attr
.clearclass(linecap
)
60 class linejoin(attr
.exclusiveattr
, strokestyle
):
62 """linejoin of paths"""
64 def __init__(self
, value
=0):
65 attr
.exclusiveattr
.__init
__(self
, linejoin
)
68 def processPS(self
, file, writer
, context
, registry
, bbox
):
69 file.write("%d setlinejoin\n" % self
.value
)
71 def processPDF(self
, file, writer
, context
, registry
, bbox
):
72 file.write("%d j\n" % self
.value
)
74 linejoin
.miter
= linejoin(0)
75 linejoin
.round = linejoin(1)
76 linejoin
.bevel
= linejoin(2)
77 linejoin
.clear
= attr
.clearclass(linejoin
)
80 class miterlimit(attr
.exclusiveattr
, strokestyle
):
82 """miterlimit of paths"""
84 def __init__(self
, value
=10.0):
85 attr
.exclusiveattr
.__init
__(self
, miterlimit
)
88 def processPS(self
, file, writer
, context
, registry
, bbox
):
89 file.write("%f setmiterlimit\n" % self
.value
)
91 def processPDF(self
, file, writer
, context
, registry
, bbox
):
92 file.write("%f M\n" % self
.value
)
94 miterlimit
.lessthan180deg
= miterlimit(1/math
.sin(math
.pi
*180/360))
95 miterlimit
.lessthan90deg
= miterlimit(1/math
.sin(math
.pi
*90/360))
96 miterlimit
.lessthan60deg
= miterlimit(1/math
.sin(math
.pi
*60/360))
97 miterlimit
.lessthan45deg
= miterlimit(1/math
.sin(math
.pi
*45/360))
98 miterlimit
.lessthan11deg
= miterlimit(10) # the default, approximately 11.4783 degress
99 miterlimit
.clear
= attr
.clearclass(miterlimit
)
102 _defaultlinewidth
= 0.02 * unit
.w_cm
103 _defaultlinewidth_pt
= unit
.topt(_defaultlinewidth
)
105 class dash(attr
.exclusiveattr
, strokestyle
):
109 def __init__(self
, pattern
=[], offset
=0, rellengths
=1):
110 """set pattern with offset.
112 If rellengths is True, interpret all dash lengths relative to current linewidth.
114 attr
.exclusiveattr
.__init
__(self
, dash
)
115 self
.pattern
= pattern
117 self
.rellengths
= rellengths
119 def processPS(self
, file, writer
, context
, registry
, bbox
):
121 patternstring
= " ".join(["%f" % (element
* context
.linewidth_pt
/_defaultlinewidth_pt
) for element
in self
.pattern
])
123 patternstring
= " ".join(["%f" % element
for element
in self
.pattern
])
124 file.write("[%s] %d setdash\n" % (patternstring
, self
.offset
))
126 def processPDF(self
, file, writer
, context
, registry
, bbox
):
128 patternstring
= " ".join(["%f" % (element
* context
.linewidth_pt
/_defaultlinewidth_pt
) for element
in self
.pattern
])
130 patternstring
= " ".join(["%f" % element
for element
in self
.pattern
])
131 file.write("[%s] %d d\n" % (patternstring
, self
.offset
))
133 dash
.clear
= attr
.clearclass(dash
)
136 class linestyle(attr
.exclusiveattr
, strokestyle
):
138 """linestyle (linecap together with dash) of paths"""
140 def __init__(self
, c
=linecap
.butt
, d
=dash([])):
141 # XXX better, but at the moment not supported by attr.exlusiveattr would be:
142 # XXX attr.exclusiveattr.__init__(self, [linestyle, linecap, dash])
143 attr
.exclusiveattr
.__init
__(self
, linestyle
)
147 def processPS(self
, file, writer
, context
, registry
, bbox
):
148 self
.c
.processPS(file, writer
, context
, registry
, bbox
)
149 self
.d
.processPS(file, writer
, context
, registry
, bbox
)
151 def processPDF(self
, file, writer
, context
, registry
, bbox
):
152 self
.c
.processPDF(file, writer
, context
, registry
, bbox
)
153 self
.d
.processPDF(file, writer
, context
, registry
, bbox
)
155 linestyle
.solid
= linestyle(linecap
.butt
, dash([]))
156 linestyle
.dashed
= linestyle(linecap
.butt
, dash([2]))
157 linestyle
.dotted
= linestyle(linecap
.round, dash([0, 2]))
158 linestyle
.dashdotted
= linestyle(linecap
.round, dash([0, 2, 2, 2]))
159 linestyle
.clear
= attr
.clearclass(linestyle
)
162 class linewidth(attr
.sortbeforeexclusiveattr
, strokestyle
):
164 """linewidth of paths"""
166 def __init__(self
, width
):
167 attr
.sortbeforeexclusiveattr
.__init
__(self
, linewidth
, [dash
, linestyle
])
170 def processPS(self
, file, writer
, context
, registry
, bbox
):
171 file.write("%f setlinewidth\n" % unit
.topt(self
.width
))
172 context
.linewidth_pt
= unit
.topt(self
.width
)
174 def processPDF(self
, file, writer
, context
, registry
, bbox
):
175 file.write("%f w\n" % unit
.topt(self
.width
))
176 context
.linewidth_pt
= unit
.topt(self
.width
)
178 linewidth
.THIN
= linewidth(_defaultlinewidth
/math
.sqrt(32))
179 linewidth
.THIn
= linewidth(_defaultlinewidth
/math
.sqrt(16))
180 linewidth
.THin
= linewidth(_defaultlinewidth
/math
.sqrt(8))
181 linewidth
.Thin
= linewidth(_defaultlinewidth
/math
.sqrt(4))
182 linewidth
.thin
= linewidth(_defaultlinewidth
/math
.sqrt(2))
183 linewidth
.normal
= linewidth(_defaultlinewidth
)
184 linewidth
.thick
= linewidth(_defaultlinewidth
*math
.sqrt(2))
185 linewidth
.Thick
= linewidth(_defaultlinewidth
*math
.sqrt(4))
186 linewidth
.THick
= linewidth(_defaultlinewidth
*math
.sqrt(8))
187 linewidth
.THIck
= linewidth(_defaultlinewidth
*math
.sqrt(16))
188 linewidth
.THICk
= linewidth(_defaultlinewidth
*math
.sqrt(32))
189 linewidth
.THICK
= linewidth(_defaultlinewidth
*math
.sqrt(64))
190 linewidth
.clear
= attr
.clearclass(linewidth
)