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

1# fmt: off 

2 

3import time 

4 

5from ase.io.utils import PlottingVariables, make_patch_list 

6from ase.utils import writer 

7 

8 

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. 

15 

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) 

25 

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) 

31 

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') 

40 

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') 

50 

51 fd.write('mpldict begin\n') 

52 fd.write('%d %d 0 0 clipbox\n' % (self.w, self.h)) 

53 

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) 

58 

59 def write_body(self, fd, renderer): 

60 patch_list = make_patch_list(self) 

61 for patch in patch_list: 

62 patch.draw(renderer) 

63 

64 def write_trailer(self, fd, renderer): 

65 fd.write('end\n') 

66 fd.write('showpage\n') 

67 

68 

69@writer 

70def write_eps(fd, atoms, **parameters): 

71 EPS(atoms, **parameters).write(fd) 

72 

73 

74# Adapted from Matplotlib 3.7.3 

75 

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# 

85 

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]