Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
EpsDocument | 39 | 86 | 30 |
1 | /* | |
2 | * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) | |
3 | * Copyright (C) $$Year-Rel$$ The Jalview Authors | |
4 | * | |
5 | * This file is part of Jalview. | |
6 | * | |
7 | * Jalview is free software: you can redistribute it and/or | |
8 | * modify it under the terms of the GNU General Public License | |
9 | * as published by the Free Software Foundation, either version 3 | |
10 | * of the License, or (at your option) any later version. | |
11 | * | |
12 | * Jalview is distributed in the hope that it will be useful, but | |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty | |
14 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR | |
15 | * PURPOSE. See the GNU General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License | |
18 | * along with Jalview. If not, see <http://www.gnu.org/licenses/>. | |
19 | * The Jalview Authors are detailed in the 'AUTHORS' file. | |
20 | */ | |
21 | package org.jibble.epsgraphics; | |
22 | ||
23 | import java.io.BufferedWriter; | |
24 | import java.io.IOException; | |
25 | import java.io.OutputStream; | |
26 | import java.io.OutputStreamWriter; | |
27 | import java.io.StringWriter; | |
28 | import java.io.Writer; | |
29 | import java.util.Date; | |
30 | ||
31 | /** | |
32 | * This represents an EPS document. Several EpsGraphics2D objects may point to | |
33 | * the same EpsDocument. | |
34 | * <p> | |
35 | * Copyright Paul Mutton, | |
36 | * <a href="http://www.jibble.org/">http://www.jibble.org/</a> | |
37 | * | |
38 | */ | |
39 | public class EpsDocument | |
40 | { | |
41 | ||
42 | /** | |
43 | * Constructs an empty EpsDevice. | |
44 | */ | |
45 | 10 | public EpsDocument(String title) |
46 | { | |
47 | 10 | _title = title; |
48 | 10 | minX = Float.POSITIVE_INFINITY; |
49 | 10 | minY = Float.POSITIVE_INFINITY; |
50 | 10 | maxX = Float.NEGATIVE_INFINITY; |
51 | 10 | maxY = Float.NEGATIVE_INFINITY; |
52 | 10 | _stringWriter = new StringWriter(); |
53 | 10 | _bufferedWriter = new BufferedWriter(_stringWriter); |
54 | } | |
55 | ||
56 | /** | |
57 | * Constructs an empty EpsDevice that writes directly to a file. Bounds must | |
58 | * be set before use. | |
59 | */ | |
60 | 10 | public EpsDocument(String title, OutputStream outputStream, int minX, |
61 | int minY, int maxX, int maxY) throws IOException | |
62 | { | |
63 | 10 | _title = title; |
64 | 10 | this.minX = minX; |
65 | 10 | this.minY = minY; |
66 | 10 | this.maxX = maxX; |
67 | 10 | this.maxY = maxY; |
68 | 10 | _bufferedWriter = new BufferedWriter( |
69 | new OutputStreamWriter(outputStream)); | |
70 | 10 | write(_bufferedWriter); |
71 | } | |
72 | ||
73 | /** | |
74 | * Returns the title of the EPS document. | |
75 | */ | |
76 | 0 | public synchronized String getTitle() |
77 | { | |
78 | 0 | return _title; |
79 | } | |
80 | ||
81 | /** | |
82 | * Updates the bounds of the current EPS document. | |
83 | */ | |
84 | 14020 | public synchronized void updateBounds(double x, double y) |
85 | { | |
86 | 14020 | if (x > maxX) |
87 | { | |
88 | 10 | maxX = (float) x; |
89 | } | |
90 | 14020 | if (x < minX) |
91 | { | |
92 | 10 | minX = (float) x; |
93 | } | |
94 | 14020 | if (y > maxY) |
95 | { | |
96 | 0 | maxY = (float) y; |
97 | } | |
98 | 14020 | if (y < minY) |
99 | { | |
100 | 20 | minY = (float) y; |
101 | } | |
102 | } | |
103 | ||
104 | /** | |
105 | * Appends a line to the EpsDocument. A new line character is added to the end | |
106 | * of the line when it is added. | |
107 | */ | |
108 | 264080 | public synchronized void append(EpsGraphics2D g, String line) |
109 | { | |
110 | 264080 | if (_lastG == null) |
111 | { | |
112 | 20 | _lastG = g; |
113 | } | |
114 | 264060 | else if (g != _lastG) |
115 | { | |
116 | 20 | EpsGraphics2D lastG = _lastG; |
117 | 20 | _lastG = g; |
118 | // We are being drawn on with a different EpsGraphics2D context. | |
119 | // We may need to update the clip, etc from this new context. | |
120 | 20 | if (g.getClip() != lastG.getClip()) |
121 | { | |
122 | 0 | g.setClip(g.getClip()); |
123 | } | |
124 | 20 | if (!g.getColor().equals(lastG.getColor())) |
125 | { | |
126 | 0 | g.setColor(g.getColor()); |
127 | } | |
128 | 20 | if (!g.getBackground().equals(lastG.getBackground())) |
129 | { | |
130 | 0 | g.setBackground(g.getBackground()); |
131 | } | |
132 | // We don't need this, as this only affects the stroke and font, | |
133 | // which are dealt with separately later on. | |
134 | // if (!g.getTransform().equals(lastG.getTransform())) { | |
135 | // g.setTransform(g.getTransform()); | |
136 | // } | |
137 | 20 | if (!g.getPaint().equals(lastG.getPaint())) |
138 | { | |
139 | 0 | g.setPaint(g.getPaint()); |
140 | } | |
141 | 20 | if (!g.getComposite().equals(lastG.getComposite())) |
142 | { | |
143 | 0 | g.setComposite(g.getComposite()); |
144 | } | |
145 | 20 | if (!g.getComposite().equals(lastG.getComposite())) |
146 | { | |
147 | 0 | g.setComposite(g.getComposite()); |
148 | } | |
149 | 20 | if (!g.getFont().equals(lastG.getFont())) |
150 | { | |
151 | 0 | g.setFont(g.getFont()); |
152 | } | |
153 | 20 | if (!g.getStroke().equals(lastG.getStroke())) |
154 | { | |
155 | 0 | g.setStroke(g.getStroke()); |
156 | } | |
157 | } | |
158 | 264080 | _lastG = g; |
159 | ||
160 | 264080 | try |
161 | { | |
162 | 264080 | _bufferedWriter.write(line + "\n"); |
163 | } catch (IOException e) | |
164 | { | |
165 | 0 | throw new EpsException("Could not write to the output file: " + e); |
166 | } | |
167 | } | |
168 | ||
169 | /** | |
170 | * Outputs the contents of the EPS document to the specified Writer, complete | |
171 | * with headers and bounding box. | |
172 | */ | |
173 | 10 | public synchronized void write(Writer writer) throws IOException |
174 | { | |
175 | 10 | float offsetX = -minX; |
176 | 10 | float offsetY = -minY; |
177 | ||
178 | 10 | writer.write("%!PS-Adobe-3.0 EPSF-3.0\n"); |
179 | 10 | writer.write("%%Creator: Jalview " |
180 | + jalview.bin.Cache.getProperty("VERSION") + " \n"); | |
181 | 10 | writer.write("%%Title: " + _title + "\n"); |
182 | 10 | writer.write("%%CreationDate: " + new Date() + "\n"); |
183 | 10 | writer.write("%%BoundingBox: 0 0 " + ((int) Math.ceil(maxX + offsetX)) |
184 | + " " + ((int) Math.ceil(maxY + offsetY)) + "\n"); | |
185 | 10 | writer.write("%%DocumentData: Clean7Bit\n"); |
186 | 10 | writer.write("%%DocumentProcessColors: Black\n"); |
187 | 10 | writer.write("%%ColorUsage: Color\n"); |
188 | 10 | writer.write("%%Origin: 0 0\n"); |
189 | 10 | writer.write("%%Pages: 1\n"); |
190 | 10 | writer.write("%%Page: 1 1\n"); |
191 | 10 | writer.write("%%EndComments\n\n"); |
192 | ||
193 | 10 | writer.write("gsave\n"); |
194 | ||
195 | 10 | if (_stringWriter != null) |
196 | { | |
197 | 0 | writer.write(offsetX + " " + (offsetY) + " translate\n"); |
198 | ||
199 | 0 | _bufferedWriter.flush(); |
200 | 0 | StringBuffer buffer = _stringWriter.getBuffer(); |
201 | 0 | for (int i = 0; i < buffer.length(); i++) |
202 | { | |
203 | 0 | writer.write(buffer.charAt(i)); |
204 | } | |
205 | ||
206 | 0 | writeFooter(writer); |
207 | } | |
208 | else | |
209 | { | |
210 | 10 | writer.write( |
211 | offsetX + " " + ((maxY - minY) - offsetY) + " translate\n"); | |
212 | } | |
213 | ||
214 | 10 | writer.flush(); |
215 | } | |
216 | ||
217 | 10 | private void writeFooter(Writer writer) throws IOException |
218 | { | |
219 | 10 | writer.write("grestore\n"); |
220 | 10 | if (isClipSet()) |
221 | { | |
222 | 0 | writer.write("grestore\n"); |
223 | } | |
224 | 10 | writer.write("showpage\n"); |
225 | 10 | writer.write("\n"); |
226 | 10 | writer.write("%%EOF"); |
227 | 10 | writer.flush(); |
228 | } | |
229 | ||
230 | 20 | public synchronized void flush() throws IOException |
231 | { | |
232 | 20 | _bufferedWriter.flush(); |
233 | } | |
234 | ||
235 | 10 | public synchronized void close() throws IOException |
236 | { | |
237 | 10 | if (_stringWriter == null) |
238 | { | |
239 | 10 | writeFooter(_bufferedWriter); |
240 | 10 | _bufferedWriter.flush(); |
241 | 10 | _bufferedWriter.close(); |
242 | } | |
243 | } | |
244 | ||
245 | 10 | public boolean isClipSet() |
246 | { | |
247 | 10 | return _isClipSet; |
248 | } | |
249 | ||
250 | 0 | public void setClipSet(boolean isClipSet) |
251 | { | |
252 | 0 | _isClipSet = isClipSet; |
253 | } | |
254 | ||
255 | private float minX; | |
256 | ||
257 | private float minY; | |
258 | ||
259 | private float maxX; | |
260 | ||
261 | private float maxY; | |
262 | ||
263 | private boolean _isClipSet = false; | |
264 | ||
265 | private String _title; | |
266 | ||
267 | private StringWriter _stringWriter; | |
268 | ||
269 | private BufferedWriter _bufferedWriter = null; | |
270 | ||
271 | // We need to remember which was the last EpsGraphics2D object to use | |
272 | // us, as we need to replace the clipping region if another EpsGraphics2D | |
273 | // object tries to use us. | |
274 | private EpsGraphics2D _lastG = null; | |
275 | ||
276 | } |