1 |
|
2 |
package org.freehep.graphicsio.emf; |
3 |
|
4 |
import java.awt.BasicStroke; |
5 |
import java.awt.Color; |
6 |
import java.awt.Component; |
7 |
import java.awt.Dimension; |
8 |
import java.awt.Font; |
9 |
import java.awt.GradientPaint; |
10 |
import java.awt.Graphics; |
11 |
import java.awt.GraphicsConfiguration; |
12 |
import java.awt.Paint; |
13 |
import java.awt.Rectangle; |
14 |
import java.awt.Shape; |
15 |
import java.awt.Stroke; |
16 |
import java.awt.TexturePaint; |
17 |
import java.awt.Toolkit; |
18 |
import java.awt.font.FontRenderContext; |
19 |
import java.awt.geom.AffineTransform; |
20 |
import java.awt.geom.Area; |
21 |
import java.awt.image.RenderedImage; |
22 |
import java.io.BufferedOutputStream; |
23 |
import java.io.File; |
24 |
import java.io.FileNotFoundException; |
25 |
import java.io.FileOutputStream; |
26 |
import java.io.IOException; |
27 |
import java.io.OutputStream; |
28 |
import java.util.Properties; |
29 |
|
30 |
import org.freehep.graphics2d.VectorGraphics; |
31 |
import org.freehep.graphicsio.AbstractVectorGraphicsIO; |
32 |
import org.freehep.graphicsio.PageConstants; |
33 |
import org.freehep.graphicsio.emf.gdi.EOF; |
34 |
import org.freehep.graphicsio.emf.gdiplus.Clear; |
35 |
import org.freehep.graphicsio.emf.gdiplus.DrawImage; |
36 |
import org.freehep.graphicsio.emf.gdiplus.DrawPath; |
37 |
import org.freehep.graphicsio.emf.gdiplus.EndOfFile; |
38 |
import org.freehep.graphicsio.emf.gdiplus.FillPath; |
39 |
import org.freehep.graphicsio.emf.gdiplus.GDIPlusObject; |
40 |
import org.freehep.graphicsio.emf.gdiplus.Header; |
41 |
import org.freehep.graphicsio.emf.gdiplus.MultiplyWorldTransform; |
42 |
import org.freehep.graphicsio.emf.gdiplus.ResetClip; |
43 |
import org.freehep.graphicsio.emf.gdiplus.Restore; |
44 |
import org.freehep.graphicsio.emf.gdiplus.Save; |
45 |
import org.freehep.graphicsio.emf.gdiplus.SetAntiAliasMode; |
46 |
import org.freehep.graphicsio.emf.gdiplus.SetClipPath; |
47 |
import org.freehep.graphicsio.emf.gdiplus.SetWorldTransform; |
48 |
import org.freehep.util.UserProperties; |
49 |
import org.freehep.util.Value; |
50 |
|
51 |
|
52 |
|
53 |
|
54 |
@author |
55 |
@version |
56 |
|
57 |
public class EMFPlusGraphics2D extends AbstractVectorGraphicsIO { |
58 |
public static final String version = "$Revision: 10140 $"; |
59 |
|
60 |
private OutputStream ros; |
61 |
private EMFOutputStream os; |
62 |
private Rectangle imageBounds; |
63 |
|
64 |
private EMFHandleManager handleManager; |
65 |
private Value containerIndex; |
66 |
private Paint restorePaint; |
67 |
|
68 |
private static final String rootKey = EMFPlusGraphics2D.class.getName(); |
69 |
|
70 |
public static final String TRANSPARENT = rootKey + "." |
71 |
+ PageConstants.TRANSPARENT; |
72 |
|
73 |
public static final String BACKGROUND = rootKey + "." |
74 |
+ PageConstants.BACKGROUND; |
75 |
|
76 |
public static final String BACKGROUND_COLOR = rootKey + "." |
77 |
+ PageConstants.BACKGROUND_COLOR; |
78 |
|
79 |
private static final UserProperties defaultProperties = new UserProperties(); |
80 |
static { |
81 |
defaultProperties.setProperty(TRANSPARENT, true); |
82 |
defaultProperties.setProperty(BACKGROUND, false); |
83 |
defaultProperties.setProperty(BACKGROUND_COLOR, Color.GRAY); |
84 |
defaultProperties.setProperty(CLIP, true); |
85 |
defaultProperties.setProperty(TEXT_AS_SHAPES, true); |
86 |
} |
87 |
|
88 |
public static Properties getDefaultProperties() { |
89 |
return defaultProperties; |
90 |
} |
91 |
|
92 |
|
93 |
public FontRenderContext getFontRenderContext() { |
94 |
|
95 |
return new FontRenderContext(new AffineTransform(-1, 0, 0, 1, 0, 0), |
96 |
true, true); |
97 |
} |
98 |
|
99 |
|
100 |
public static void setDefaultProperties(Properties newProperties) { |
101 |
defaultProperties.setProperties(newProperties); |
102 |
} |
103 |
|
104 |
public EMFPlusGraphics2D(File file, Dimension size) |
105 |
throws FileNotFoundException { |
106 |
this(new FileOutputStream(file), size); |
107 |
} |
108 |
|
109 |
public EMFPlusGraphics2D(File file, Component component) |
110 |
throws FileNotFoundException { |
111 |
this(new FileOutputStream(file), component); |
112 |
} |
113 |
|
114 |
public EMFPlusGraphics2D(OutputStream os, Dimension size) { |
115 |
super(size, false); |
116 |
this.imageBounds = new Rectangle(0, 0, size.width, size.height); |
117 |
init(os); |
118 |
} |
119 |
|
120 |
public EMFPlusGraphics2D(OutputStream os, Component component) { |
121 |
super(component, false); |
122 |
this.imageBounds = new Rectangle(0, 0, getSize().width, getSize().height); |
123 |
init(os); |
124 |
} |
125 |
|
126 |
private void init(OutputStream os) { |
127 |
handleManager = new EMFHandleManager(); |
128 |
ros = os; |
129 |
containerIndex = new Value(); |
130 |
containerIndex.set(0); |
131 |
initProperties(defaultProperties); |
132 |
} |
133 |
|
134 |
protected EMFPlusGraphics2D(EMFPlusGraphics2D graphics, |
135 |
boolean doRestoreOnDispose) { |
136 |
super(graphics, doRestoreOnDispose); |
137 |
|
138 |
|
139 |
|
140 |
|
141 |
|
142 |
os = graphics.os; |
143 |
imageBounds = graphics.imageBounds; |
144 |
handleManager = graphics.handleManager; |
145 |
containerIndex = graphics.containerIndex; |
146 |
restorePaint = graphics.getPaint(); |
147 |
} |
148 |
|
149 |
public void writeHeader() throws IOException { |
150 |
ros = new BufferedOutputStream(ros); |
151 |
Dimension device = isDeviceIndependent() ? new Dimension(1024, 768) |
152 |
: Toolkit.getDefaultToolkit().getScreenSize(); |
153 |
String producer = getClass().getName(); |
154 |
if (!isDeviceIndependent()) { |
155 |
producer += " " + version.substring(1, version.length() - 1); |
156 |
} |
157 |
os = new EMFOutputStream(ros, imageBounds, handleManager, getCreator(), |
158 |
producer, device, 0x4001); |
159 |
|
160 |
os.writeTag(new Header()); |
161 |
|
162 |
|
163 |
os.writeTag(new SetAntiAliasMode(true)); |
164 |
|
165 |
|
166 |
|
167 |
|
168 |
|
169 |
|
170 |
|
171 |
|
172 |
|
173 |
|
174 |
|
175 |
|
176 |
|
177 |
} |
178 |
|
179 |
public void writeBackground() throws IOException { |
180 |
if (isProperty(TRANSPARENT)) { |
181 |
setBackground(null); |
182 |
|
183 |
|
184 |
} else if (isProperty(BACKGROUND)) { |
185 |
setBackground(getPropertyColor(BACKGROUND_COLOR)); |
186 |
os.writeTag(new Clear(getBackground())); |
187 |
} else { |
188 |
setBackground(getComponent() != null ? getComponent() |
189 |
.getBackground() : Color.WHITE); |
190 |
os.writeTag(new Clear(getBackground())); |
191 |
} |
192 |
} |
193 |
|
194 |
public void writeTrailer() throws IOException { |
195 |
|
196 |
for (;;) { |
197 |
int handle = handleManager.highestHandleInUse(); |
198 |
if (handle < 0) |
199 |
break; |
200 |
|
201 |
handleManager.freeHandle(handle); |
202 |
} |
203 |
os.writeTag(new EndOfFile()); |
204 |
os.writeTag(new EOF()); |
205 |
} |
206 |
|
207 |
public void closeStream() throws IOException { |
208 |
os.close(); |
209 |
} |
210 |
|
211 |
public Graphics create() { |
212 |
|
213 |
try { |
214 |
|
215 |
writeGraphicsSave(); |
216 |
} catch (IOException e) { |
217 |
handleException(e); |
218 |
} |
219 |
|
220 |
return new EMFPlusGraphics2D(this, true); |
221 |
} |
222 |
|
223 |
public Graphics create(double x, double y, double width, double height) { |
224 |
|
225 |
try { |
226 |
|
227 |
writeGraphicsSave(); |
228 |
} catch (IOException e) { |
229 |
handleException(e); |
230 |
} |
231 |
|
232 |
VectorGraphics graphics = new EMFPlusGraphics2D(this, true); |
233 |
graphics.translate(x, y); |
234 |
graphics.clipRect(0, 0, width, height); |
235 |
return graphics; |
236 |
} |
237 |
|
238 |
protected void writeGraphicsSave() throws IOException { |
239 |
os.writeTag(new Save(containerIndex.getInt())); |
240 |
containerIndex.set(containerIndex.getInt()+1); |
241 |
} |
242 |
|
243 |
protected void writeGraphicsRestore() throws IOException { |
244 |
containerIndex.set(containerIndex.getInt()-1); |
245 |
os.writeTag(new Restore(containerIndex.getInt())); |
246 |
if (restorePaint != null) writePaint(restorePaint); |
247 |
} |
248 |
|
249 |
public void draw(Shape shape) { |
250 |
try { |
251 |
Stroke stroke = getStroke(); |
252 |
if ((stroke instanceof BasicStroke) && (((BasicStroke)stroke).getLineWidth() == 0)) { |
253 |
os.writeTag(new GDIPlusObject(1, shape, false)); |
254 |
os.writeTag(new GDIPlusObject(2, new BasicStroke(0), getPaint())); |
255 |
os.writeTag(new DrawPath(1, 2)); |
256 |
} else { |
257 |
Shape strokedShape = getStroke().createStrokedShape(shape); |
258 |
fill(new Area(strokedShape)); |
259 |
} |
260 |
} catch (IOException e) { |
261 |
handleException(e); |
262 |
} |
263 |
} |
264 |
|
265 |
public void fill(Shape shape) { |
266 |
try { |
267 |
os.writeTag(new GDIPlusObject(1, shape, false)); |
268 |
os.writeTag(new FillPath(1, 0)); |
269 |
} catch (IOException e) { |
270 |
handleException(e); |
271 |
} |
272 |
} |
273 |
|
274 |
public void copyArea(int x, int y, int width, int height, int dx, int dy) { |
275 |
writeWarning(getClass() |
276 |
+ ": copyArea(int, int, int, int, int, int) not implemented."); |
277 |
|
278 |
} |
279 |
|
280 |
protected void writeImage(RenderedImage image, AffineTransform xform, |
281 |
Color bkg) throws IOException { |
282 |
|
283 |
writeGraphicsSave(); |
284 |
os.writeTag(new GDIPlusObject(5, image)); |
285 |
os.writeTag(new MultiplyWorldTransform(xform, true)); |
286 |
os.writeTag(new DrawImage(5, image)); |
287 |
writeGraphicsRestore(); |
288 |
} |
289 |
|
290 |
protected void writeString(String string, double x, double y) |
291 |
throws IOException { |
292 |
|
293 |
} |
294 |
|
295 |
protected void writeTransform(AffineTransform t) throws IOException { |
296 |
os.writeTag(new MultiplyWorldTransform(t, true)); |
297 |
} |
298 |
|
299 |
protected void writeSetTransform(AffineTransform t) throws IOException { |
300 |
os.writeTag(new SetWorldTransform(t)); |
301 |
} |
302 |
|
303 |
protected void writeClip(Shape s) throws IOException { |
304 |
os.writeTag(new GDIPlusObject(4, s, false)); |
305 |
os.writeTag(new SetClipPath(4, SetClipPath.INTERSECT)); |
306 |
} |
307 |
|
308 |
protected void writeSetClip(Shape s) throws IOException { |
309 |
if (s != null) { |
310 |
os.writeTag(new GDIPlusObject(4, s, false)); |
311 |
os.writeTag(new SetClipPath(4, SetClipPath.REPLACE)); |
312 |
} else { |
313 |
os.writeTag(new ResetClip()); |
314 |
} |
315 |
} |
316 |
|
317 |
protected void writeWidth(float width) throws IOException { |
318 |
|
319 |
} |
320 |
|
321 |
protected void writeCap(int cap) throws IOException { |
322 |
|
323 |
} |
324 |
|
325 |
protected void writeJoin(int join) throws IOException { |
326 |
|
327 |
} |
328 |
|
329 |
protected void writeMiterLimit(float limit) throws IOException { |
330 |
|
331 |
} |
332 |
|
333 |
protected void writeDash(float[] dash, float phase) throws IOException { |
334 |
|
335 |
} |
336 |
|
337 |
public void setPaintMode() { |
338 |
writeWarning(getClass() + ": setPaintMode() not implemented."); |
339 |
|
340 |
} |
341 |
|
342 |
public void setXORMode(Color c1) { |
343 |
writeWarning(getClass() + ": setXORMode(Color) not implemented."); |
344 |
|
345 |
} |
346 |
|
347 |
protected void writePaint(Color p) throws IOException { |
348 |
os.writeTag(new GDIPlusObject(0, p)); |
349 |
} |
350 |
|
351 |
protected void writePaint(GradientPaint p) throws IOException { |
352 |
os.writeTag(new GDIPlusObject(0, p)); |
353 |
} |
354 |
|
355 |
protected void writePaint(TexturePaint p) throws IOException { |
356 |
os.writeTag(new GDIPlusObject(0, p)); |
357 |
} |
358 |
|
359 |
protected void writePaint(Paint p) throws IOException { |
360 |
os.writeTag(new GDIPlusObject(0, p)); |
361 |
} |
362 |
|
363 |
protected void writeFont(Font font) throws IOException { |
364 |
|
365 |
} |
366 |
|
367 |
public GraphicsConfiguration getDeviceConfiguration() { |
368 |
writeWarning(getClass() + ": getDeviceConfiguration() not implemented."); |
369 |
|
370 |
return null; |
371 |
} |
372 |
|
373 |
public boolean hit(Rectangle rect, Shape s, boolean onStroke) { |
374 |
writeWarning(getClass() |
375 |
+ ": hit(Rectangle, Shape, boolean) not implemented."); |
376 |
|
377 |
return false; |
378 |
} |
379 |
|
380 |
public void writeComment(String comment) throws IOException { |
381 |
writeWarning(getClass() + ": writeComment(String) not implemented."); |
382 |
|
383 |
} |
384 |
|
385 |
protected void writeWarning(String string) { |
386 |
System.err.println(string); |
387 |
} |
388 |
|
389 |
public String toString() { |
390 |
return "EMFPlusGraphics2D"; |
391 |
} |
392 |
} |