// Copyright 2001, FreeHEP. package org.freehep.graphicsio.cgm; import java.awt.Color; import java.awt.geom.Point2D; import java.io.FilterWriter; import java.io.IOException; import java.io.Writer; import org.freehep.util.io.IndentPrintWriter; import org.freehep.util.io.Tag; import org.freehep.util.io.TaggedOutput; /** * CGM Clear Text Writer. Tags written with this Writer will produce a clear * text CGM file. The class also holds the state for the various precisions, * defaults, etc... * * @author Mark Donszelmann * @author Charles Loomis * @version $Id: CGMWriter.java 8584 2006-08-10 23:06:37Z duns $ */ public class CGMWriter extends FilterWriter implements TaggedOutput { private int version; private boolean direct = true; private int colorIndexPrecision = 8; private int directColorPrecision = 8; private int integerPrecision = 16; private boolean fixedPrecision = true; private boolean doublePrecision = false; private boolean vdcReal = false; private boolean vdcFixedPrecision = true; private boolean vdcDoublePrecision = false; private int vdcIntegerPrecision = 16; private int namePrecision = 16; private int lineWidthSpecificationMode = LineWidthSpecificationMode.ABSOLUTE; private int markerSizeSpecificationMode = MarkerSizeSpecificationMode.ABSOLUTE; private int edgeWidthSpecificationMode = EdgeWidthSpecificationMode.ABSOLUTE; private int interiorStyleSpecificationMode = InteriorStyleSpecificationMode.ABSOLUTE; /** * Constructs a Clear Text CGM writer of a specified version. * * @param writer the underlying writer * @param version the requested cgm version */ public CGMWriter(Writer writer, int version) throws IOException { super(new IndentPrintWriter(writer)); this.version = version; } /** * Constructs a Clear Text CGM Writer of version 1. * * @param writer the underlying writer. */ public CGMWriter(Writer writer) throws IOException { this(writer, 1); } void setColorMode(boolean direct) { this.direct = direct; } void setColorIndexPrecision(int precision) { colorIndexPrecision = precision; } void setDirectColorPrecision(int precision) { directColorPrecision = precision; } void setIntegerPrecision(int precision) { integerPrecision = precision; } void setRealPrecision(boolean fixedPrecision, boolean doublePrecision) { this.fixedPrecision = fixedPrecision; this.doublePrecision = doublePrecision; } void setVDCReal(boolean real) { vdcReal = real; } void setVDCIntegerPrecision(int precision) { vdcIntegerPrecision = precision; } void setVDCRealPrecision(boolean fixedPrecision, boolean doublePrecision) { this.vdcFixedPrecision = fixedPrecision; this.vdcDoublePrecision = doublePrecision; } void setNamePrecision(int precision) { namePrecision = precision; } void setLineWidthSpecificationMode(int mode) { lineWidthSpecificationMode = mode; } int getLineWidthSpecificationMode() { return lineWidthSpecificationMode; } void setMarkerSizeSpecificationMode(int mode) { markerSizeSpecificationMode = mode; } int getMarkerSizeSpecificationMode() { return markerSizeSpecificationMode; } void setEdgeWidthSpecificationMode(int mode) { edgeWidthSpecificationMode = mode; } int getEdgeWidthSpecificationMode() { return edgeWidthSpecificationMode; } void setInteriorStyleSpecificationMode(int mode) { interiorStyleSpecificationMode = mode; } int getInteriorStyleSpecificationMode() { return interiorStyleSpecificationMode; } /** * Write a Fixed Point value (FX) * * @param d value to the written */ public void writeFixedPoint(double d) throws IOException { boolean negative = d < 0; d = Math.abs(d); int whole = (int) Math.floor(d); int frac = (int) Math.floor((d - whole) * 10000); if (negative) print("-"); print(whole); print("."); print(frac); } /** * Writes a Floating Point value (FP) * * @param d value to be written */ public void writeFloatingPoint(double d) throws IOException { if (doublePrecision) { // FIXME: ignored number of digits print(d); } else { // FIXME: ignored number of digits print((float) d); } } /** * Writes a Color Index (CI) * * @param i index to be written */ public void writeColorIndex(int i) throws IOException { switch (colorIndexPrecision) { case 8: print(Math.max(0, Math.min(255, i))); break; case 16: print(Math.max(0, Math.min(65535, i))); break; default: case 24: // FIXME case 32: print(i); break; } } /** * Writes a Color Component (CCO) * * @param c color component to be written */ public void writeColorComponent(int c) throws IOException { switch (directColorPrecision) { default: case 8: print(Math.max(0, Math.min(255, c))); break; case 16: print(Math.max(0, Math.min(65535, c))); break; case 24: // FIXME case 32: print(c); break; } } /** * Writes a Color Direct (CD) * * @param c color to be written */ public void writeColorDirect(Color c) throws IOException { writeColorComponent(c.getRed()); print(", "); writeColorComponent(c.getGreen()); print(", "); writeColorComponent(c.getBlue()); } /** * Writes an Integer (I) * * @param i integer to be written */ public void writeInteger(int i) throws IOException { switch (integerPrecision) { case 8: print((byte) i); break; default: case 16: print((short) i); break; case 24: // FIXME case 32: print(i); break; } } /** * Writes a Real (R) * * @param r value to be written */ public void writeReal(double r) throws IOException { if (fixedPrecision) { writeFixedPoint(r); } else { writeFloatingPoint(r); } } /** * Writes a String or String Fixed (S, SF) * * @param s string to be written */ public void writeString(String s) throws IOException { StringBuffer b = new StringBuffer(); b.append('"'); for (int i = 0; i < s.length(); i++) { b.append(s.charAt(i)); if (s.charAt(i) == '"') { b.append('"'); } } b.append('"'); print(b.toString()); } /** * Writes a chunk of Data (D) * * @param data data to be written */ public void writeData(byte[] data) throws IOException { // FIXME: good unless strings will do encoding writeString(new String(data)); } /** * Writes a Virtual Display Coordinate (VDC) * * @param d VDC to be written */ public void writeVDC(double d) throws IOException { if (vdcReal) { if (vdcFixedPrecision) { writeFixedPoint(d); } else { if (vdcDoublePrecision) { print(d); } else { print((float) d); } } } else { switch (vdcIntegerPrecision) { default: case 16: print((short) d); break; case 24: // FIXME case 32: print(d); break; } } } /** * Writes a Point (P) * * @param p value to be written */ public void writePoint(Point2D p) throws IOException { print("("); writeVDC(p.getX()); print(", "); writeVDC(p.getY()); print(")"); } /** * Writes a Color (CO) * * @param c color to be written */ public void writeColor(Color c) throws IOException { if (direct) { writeColorDirect(c); } else { // FIXME: we should look up the color writeColorIndex((c.getRed() << 16) + (c.getGreen() << 8) + c.getBlue()); } } /** * Writes a Name (N) * * @param name name to be written */ public void writeName(int name) throws IOException { switch (namePrecision) { case 8: print(Math.max(0, Math.min(255, name))); break; default: case 16: print(Math.max(0, Math.min(65535, name))); break; case 24: // FIXME case 32: print(name); break; } } /** * Writes a Tag and a Terminator (;) * * @param tag tag to be written */ public void writeTag(Tag tag) throws IOException { CGMTag cgm = (CGMTag) tag; cgm.write(cgm.getTag(), this); println(";"); } /** * @return the version of this CGM Writer */ public int getVersion() { return version; } // Delegations to IndentPrintWriter to avoid "strange" compilation error in jdk 1.5 public void indent() { ((IndentPrintWriter)out).indent(); } public void outdent() { ((IndentPrintWriter)out).outdent(); } public void print(byte b) { ((IndentPrintWriter)out).print(b); } public void print(double d) { ((IndentPrintWriter)out).print(d); } public void print(String s) { ((IndentPrintWriter)out).print(s); } public void println(String s) { ((IndentPrintWriter)out).println(s); } public void println() { ((IndentPrintWriter)out).println(); } }