Coverage for /builds/ase/ase/ase/io/eps.py: 100.00%
44 statements
« prev ^ index » next coverage.py v7.5.3, created at 2025-08-02 00:12 +0000
« prev ^ index » next coverage.py v7.5.3, created at 2025-08-02 00:12 +0000
1# fmt: off
3import time
5from ase.io.utils import PlottingVariables, make_patch_list
6from ase.utils import writer
9class EPS(PlottingVariables):
10 def __init__(self, atoms,
11 rotation='', radii=None,
12 bbox=None, colors=None, scale=20, maxwidth=500,
13 **kwargs):
14 """Encapsulated PostScript writer.
16 show_unit_cell: int
17 0: Don't show unit cell (default). 1: Show unit cell.
18 2: Show unit cell and make sure all of it is visible.
19 """
20 PlottingVariables.__init__(
21 self, atoms, rotation=rotation,
22 radii=radii, bbox=bbox, colors=colors, scale=scale,
23 maxwidth=maxwidth,
24 **kwargs)
26 def write(self, fd):
27 renderer = self._renderer(fd)
28 self.write_header(fd)
29 self.write_body(fd, renderer)
30 self.write_trailer(fd, renderer)
32 def write_header(self, fd):
33 fd.write('%!PS-Adobe-3.0 EPSF-3.0\n')
34 fd.write('%%Creator: G2\n')
35 fd.write('%%CreationDate: %s\n' % time.ctime(time.time()))
36 fd.write('%%Orientation: portrait\n')
37 bbox = (0, 0, self.w, self.h)
38 fd.write('%%%%BoundingBox: %d %d %d %d\n' % bbox)
39 fd.write('%%EndComments\n')
41 Ndict = len(psDefs)
42 fd.write('%%BeginProlog\n')
43 fd.write('/mpldict %d dict def\n' % Ndict)
44 fd.write('mpldict begin\n')
45 for d in psDefs:
46 d = d.strip()
47 for line in d.split('\n'):
48 fd.write(line.strip() + '\n')
49 fd.write('%%EndProlog\n')
51 fd.write('mpldict begin\n')
52 fd.write('%d %d 0 0 clipbox\n' % (self.w, self.h))
54 def _renderer(self, fd):
55 # Subclass can override
56 from matplotlib.backends.backend_ps import RendererPS
57 return RendererPS(self.w, self.h, fd)
59 def write_body(self, fd, renderer):
60 patch_list = make_patch_list(self)
61 for patch in patch_list:
62 patch.draw(renderer)
64 def write_trailer(self, fd, renderer):
65 fd.write('end\n')
66 fd.write('showpage\n')
69@writer
70def write_eps(fd, atoms, **parameters):
71 EPS(atoms, **parameters).write(fd)
74# Adapted from Matplotlib 3.7.3
76# The following Python dictionary psDefs contains the entries for the
77# PostScript dictionary mpldict. This dictionary implements most of
78# the matplotlib primitives and some abbreviations.
79#
80# References:
81# https://www.adobe.com/content/dam/acom/en/devnet/actionscript/articles/PLRM.pdf
82# http://preserve.mactech.com/articles/mactech/Vol.09/09.04/PostscriptTutorial
83# http://www.math.ubc.ca/people/faculty/cass/graphics/text/www/
84#
86# The usage comments use the notation of the operator summary
87# in the PostScript Language reference manual.
88psDefs = [
89 # name proc *_d* -
90 # Note that this cannot be bound to /d, because when embedding a Type3 font
91 # we may want to define a "d" glyph using "/d{...} d" which would locally
92 # overwrite the definition.
93 "/_d { bind def } bind def",
94 # x y *m* -
95 "/m { moveto } _d",
96 # x y *l* -
97 "/l { lineto } _d",
98 # x y *r* -
99 "/r { rlineto } _d",
100 # x1 y1 x2 y2 x y *c* -
101 "/c { curveto } _d",
102 # *cl* -
103 "/cl { closepath } _d",
104 # *ce* -
105 "/ce { closepath eofill } _d",
106 # w h x y *box* -
107 """/box {
108 m
109 1 index 0 r
110 0 exch r
111 neg 0 r
112 cl
113 } _d""",
114 # w h x y *clipbox* -
115 """/clipbox {
116 box
117 clip
118 newpath
119 } _d""",
120 # wx wy llx lly urx ury *setcachedevice* -
121 "/sc { setcachedevice } _d",
122]