jeremias 2004/04/03 05:35:09
Modified: src/java/org/apache/fop/render/ps PSGraphics2D.java
PSGenerator.java PSRenderer.java
PSDocumentGraphics2D.java
EPSDocumentGraphics2D.java PSTextPainter.java
Added: src/java/org/apache/fop/render/ps PSImageUtils.java
Log:
Some improvements on the quality fallback for text (use stroking when in doubt).
PSGenerator returns the PS level to use.
Start bringing back bitmap support.
Revision Changes Path
1.8 +57 -66 xml-fop/src/java/org/apache/fop/render/ps/PSGraphics2D.java
Index: PSGraphics2D.java
===================================================================
RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/render/ps/PSGraphics2D.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- PSGraphics2D.java 27 Feb 2004 17:53:11 -0000 1.7
+++ PSGraphics2D.java 3 Apr 2004 13:35:09 -0000 1.8
@@ -38,6 +38,7 @@
import java.awt.Stroke;
import java.awt.TexturePaint;
import java.awt.color.ColorSpace;
+import java.awt.color.ICC_Profile;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
@@ -54,9 +55,12 @@
//Batik
import org.apache.batik.ext.awt.g2d.AbstractGraphics2D;
import org.apache.batik.ext.awt.g2d.GraphicContext;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
//FOP
import org.apache.fop.fonts.Font;
+import org.apache.fop.image.FopImage;
import org.apache.fop.apps.Document;
/**
@@ -73,6 +77,9 @@
*/
public class PSGraphics2D extends AbstractGraphics2D {
+ /** the logger for this class */
+ protected Log log = LogFactory.getLog(PSTextPainter.class);
+
/** the PostScript generator being created */
protected PSGenerator gen;
@@ -196,7 +203,7 @@
public boolean drawImage(Image img, int x, int y,
ImageObserver observer) {
preparePainting();
- System.out.println("drawImage: x, y " + img.getClass().getName());
+ log.debug("drawImage: " + x + ", " + y + " " + img.getClass().getName());
final int width = img.getWidth(observer);
final int height = img.getHeight(observer);
@@ -249,24 +256,21 @@
// error
break;
}
-/*
+
try {
- FopImage fopimg = new TempImage(width, height, result, mask);
+ FopImage fopimg = new TempImage(width, height, result, null);
AffineTransform at = getTransform();
- double[] matrix = new double[6];
- at.getMatrix(matrix);
gen.saveGraphicsState();
Shape imclip = getClip();
writeClip(imclip);
- // psRenderer.write("" + matrix[0] + " " + matrix[1] +
- // " " + matrix[2] + " " + matrix[3] + " " +
- // matrix[4] + " " + matrix[5] + " cm\n");
- //psRenderer.renderBitmap(fopimg, x, y, width, height);
+ gen.concatMatrix(at);
+ PSImageUtils.renderFopImage(fopimg,
+ 1000 * x, 1000 * y, 1000 * width, 1000 * height, gen);
gen.restoreGraphicsState();
} catch (IOException ioe) {
handleIOException(ioe);
}
-*/
+
return true;
}
@@ -280,40 +284,44 @@
BufferedImage.TYPE_INT_ARGB);
}
-/*
+
class TempImage implements FopImage {
- int height;
- int width;
- int bitsPerPixel;
- ColorSpace colorSpace;
- int bitmapSiye;
- byte[] bitmaps;
- byte[] mask;
- PDFColor transparent = new PDFColor(255, 255, 255);
+ private int height;
+ private int width;
+ private int bitsPerPixel;
+ private ColorSpace colorSpace;
+ private int bitmapSiye;
+ private byte[] bitmaps;
+ private byte[] mask;
+ private Color transparentColor;
- TempImage(int width, int height, byte[] result,
+ TempImage(int width, int height, byte[] bitmaps,
byte[] mask) {
this.height = height;
this.width = width;
this.bitsPerPixel = 8;
- this.colorSpace = ColorSpace.new
PDFColorSpace(PDFColorSpace.DEVICE_RGB);
- this.bitmaps = result;
+ this.colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+ this.bitmaps = bitmaps;
this.mask = mask;
}
- public boolean load(int type, FOUserAgent ua) {
- return true;
- }
-
public String getMimeType() {
- return "";
+ return "application/octet-stream";
}
- public String getURL() {
- return "" + this.bitmaps;
+ /**
+ * @see org.apache.fop.image.FopImage#load(int,
org.apache.commons.logging.Log)
+ */
+ public boolean load(int type, Log logger) {
+ switch (type) {
+ case FopImage.DIMENSIONS: break;
+ case FopImage.BITMAP: break;
+ case FopImage.ORIGINAL_DATA: break;
+ default: throw new RuntimeException("Unknown load type: " + type);
+ }
+ return true;
}
- // image size
public int getWidth() {
return this.width;
}
@@ -322,23 +330,25 @@
return this.height;
}
- // DeviceGray, DeviceRGB, or DeviceCMYK
public ColorSpace getColorSpace() {
return this.colorSpace;
}
- // bits per pixel
+ public ICC_Profile getICCProfile() {
+ return null;
+ }
+
public int getBitsPerPixel() {
return this.bitsPerPixel;
}
// For transparent images
public boolean isTransparent() {
- return this.transparent != null;
+ return getTransparentColor() != null;
}
- public PDFColor getTransparentColor() {
- return this.transparent;
+ public Color getTransparentColor() {
+ return this.transparentColor;
}
public boolean hasSoftMask() {
@@ -349,9 +359,6 @@
return this.mask;
}
- // get the image bytes, and bytes properties
-
- // get uncompressed image bytes
public byte[] getBitmaps() {
return this.bitmaps;
}
@@ -372,22 +379,8 @@
return 0;
}
- // return null if no corresponding PDFFilter
- public PDFFilter getPDFFilter() {
- return null;
- }
-
- // release memory
- public void close() {
- //nop
- }
-
- public ICC_Profile getICCProfile() {
- return null;
- }
-
}
-*/
+
/**
* Draws as much of the specified image as has already been scaled
@@ -426,7 +419,7 @@
public boolean drawImage(Image img, int x, int y, int width, int height,
ImageObserver observer) {
preparePainting();
- System.out.println("drawImage");
+ log.warn("NYI: drawImage");
return true;
}
@@ -458,7 +451,6 @@
* @see java.awt.Graphics#create
*/
public void dispose() {
- // System.out.println("dispose");
this.gen = null;
this.font = null;
this.currentColour = null;
@@ -529,7 +521,6 @@
public void draw(Shape s) {
preparePainting();
try {
- // System.out.println("draw(Shape)");
gen.saveGraphicsState();
Shape imclip = getClip();
writeClip(imclip);
@@ -578,9 +569,9 @@
protected void applyPaint(Paint paint, boolean fill) {
preparePainting();
if (paint instanceof GradientPaint) {
- //NYI
+ log.warn("NYI: Gradient paint");
} else if (paint instanceof TexturePaint) {
- //NYI
+ log.warn("NYI: texture paint");
}
}
@@ -618,6 +609,7 @@
case BasicStroke.CAP_SQUARE:
gen.writeln("2 setlinecap");
break;
+ default: log.warn("Unsupported line cap: " + ec);
}
int lj = bs.getLineJoin();
@@ -631,6 +623,7 @@
case BasicStroke.JOIN_BEVEL:
gen.writeln("2 setlinejoin");
break;
+ default: log.warn("Unsupported line join: " + lj);
}
float lw = bs.getLineWidth();
gen.writeln(gen.formatDouble(1000 * lw) + " setlinewidth");
@@ -665,7 +658,7 @@
*/
public void drawRenderedImage(RenderedImage img, AffineTransform xform) {
preparePainting();
- System.out.println("drawRenderedImage");
+ log.warn("NYI: drawRenderedImage");
}
/**
@@ -701,7 +694,7 @@
public void drawRenderableImage(RenderableImage img,
AffineTransform xform) {
preparePainting();
- System.out.println("drawRenderableImage");
+ log.warn("NYI: drawRenderableImage");
}
/**
@@ -807,7 +800,7 @@
*/
public void drawStringAsText(String s, float x, float y) {
preparePainting();
- //System.out.println("drawString('" + s + "', " + x + ", " + y + ")");
+ log.trace("drawString('" + s + "', " + x + ", " + y + ")");
try {
if (this.overrideFont == null) {
java.awt.Font awtFont = getFont();
@@ -926,7 +919,7 @@
public void drawString(AttributedCharacterIterator iterator, float x,
float y) {
preparePainting();
- System.err.println("drawString(AttributedCharacterIterator) NYI");
+ log.warn("NYI: drawString(AttributedCharacterIterator)");
/*
try {
gen.writeln("BT");
@@ -974,7 +967,6 @@
*/
public void fill(Shape s) {
preparePainting();
- // System.err.println("fill");
try {
gen.saveGraphicsState();
Shape imclip = getClip();
@@ -1030,7 +1022,6 @@
* @return the device configuration
*/
public GraphicsConfiguration getDeviceConfiguration() {
- // System.out.println("getDeviceConviguration");
return GraphicsEnvironment.getLocalGraphicsEnvironment().
getDefaultScreenDevice().getDefaultConfiguration();
}
@@ -1083,7 +1074,7 @@
* @param c1 the XOR alternation color
*/
public void setXORMode(Color c1) {
- System.out.println("setXORMode");
+ log.warn("NYI: setXORMode");
}
@@ -1108,7 +1099,7 @@
*/
public void copyArea(int x, int y, int width, int height, int dx,
int dy) {
- System.out.println("copyArea");
+ log.warn("NYI: copyArea");
}
/* --- for debugging
1.5 +9 -0 xml-fop/src/java/org/apache/fop/render/ps/PSGenerator.java
Index: PSGenerator.java
===================================================================
RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/render/ps/PSGenerator.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- PSGenerator.java 27 Feb 2004 17:53:11 -0000 1.4
+++ PSGenerator.java 3 Apr 2004 13:35:09 -0000 1.5
@@ -69,6 +69,15 @@
}
/**
+ * Returns the selected PostScript level.
+ * (Hardcoded to level 3 for the moment.)
+ * @return the PostScript level
+ */
+ public int getPSLevel() {
+ return 3;
+ }
+
+ /**
* Writes a newline character to the OutputStream.
*
* @throws IOException In case of an I/O problem
1.25 +1 -0 xml-fop/src/java/org/apache/fop/render/ps/PSRenderer.java
Index: PSRenderer.java
===================================================================
RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/render/ps/PSRenderer.java,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- PSRenderer.java 27 Feb 2004 17:53:11 -0000 1.24
+++ PSRenderer.java 3 Apr 2004 13:35:09 -0000 1.25
@@ -324,6 +324,7 @@
writeln(DSCConstants.PS_ADOBE_30);
gen.writeDSCComment(DSCConstants.CREATOR, new String[] {"FOP " +
this.producer});
gen.writeDSCComment(DSCConstants.CREATION_DATE, new Object[] {new
java.util.Date()});
+ gen.writeDSCComment(DSCConstants.LANGUAGE_LEVEL, new
Integer(gen.getPSLevel()));
gen.writeDSCComment(DSCConstants.PAGES, new Object[] {PSGenerator.ATEND});
gen.writeDSCComment(DSCConstants.END_COMMENTS);
1.11 +3 -1
xml-fop/src/java/org/apache/fop/render/ps/PSDocumentGraphics2D.java
Index: PSDocumentGraphics2D.java
===================================================================
RCS file:
/home/cvs/xml-fop/src/java/org/apache/fop/render/ps/PSDocumentGraphics2D.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- PSDocumentGraphics2D.java 27 Feb 2004 17:53:11 -0000 1.10
+++ PSDocumentGraphics2D.java 3 Apr 2004 13:35:09 -0000 1.11
@@ -25,6 +25,7 @@
//FOP
import org.apache.fop.apps.Document;
+import org.apache.fop.apps.Version;
import org.apache.fop.fonts.FontSetup;
/**
@@ -91,7 +92,8 @@
//PostScript Header
gen.writeln(DSCConstants.PS_ADOBE_30);
gen.writeDSCComment(DSCConstants.CREATOR,
- new String[] {"FOP PostScript Transcoder for SVG"});
+ new String[] {"Apache FOP " + Version.getVersion()
+ + ": PostScript Transcoder for SVG"});
gen.writeDSCComment(DSCConstants.CREATION_DATE,
new Object[] {new java.util.Date()});
gen.writeDSCComment(DSCConstants.PAGES, PSGenerator.ATEND);
1.3 +7 -4
xml-fop/src/java/org/apache/fop/render/ps/EPSDocumentGraphics2D.java
Index: EPSDocumentGraphics2D.java
===================================================================
RCS file:
/home/cvs/xml-fop/src/java/org/apache/fop/render/ps/EPSDocumentGraphics2D.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- EPSDocumentGraphics2D.java 27 Feb 2004 17:53:11 -0000 1.2
+++ EPSDocumentGraphics2D.java 3 Apr 2004 13:35:09 -0000 1.3
@@ -20,6 +20,8 @@
import java.io.IOException;
+import org.apache.fop.apps.Version;
+
/**
* This class is a wrapper for the <tt>AbstractPSDocumentGraphics2D</tt> that
* is used to create EPS (Encapsulated PostScript) files instead of PS file.
@@ -53,13 +55,14 @@
//PostScript Header
gen.writeln(DSCConstants.PS_ADOBE_30 + " " + DSCConstants.EPSF_30);
gen.writeDSCComment(DSCConstants.CREATOR,
- new String[] {"FOP EPS Transcoder for SVG"});
+ new String[] {"Apache FOP " + Version.getVersion()
+ + ": EPS Transcoder for SVG"});
gen.writeDSCComment(DSCConstants.CREATION_DATE,
new Object[] {new java.util.Date()});
gen.writeDSCComment(DSCConstants.PAGES, new Integer(0));
gen.writeDSCComment(DSCConstants.BBOX, new Object[]
{ZERO, ZERO, pagewidth, pageheight});
- gen.writeDSCComment(DSCConstants.LANGUAGE_LEVEL, new Integer(2));
+ gen.writeDSCComment(DSCConstants.LANGUAGE_LEVEL, new
Integer(gen.getPSLevel()));
gen.writeDSCComment(DSCConstants.END_COMMENTS);
//Prolog
1.12 +39 -0 xml-fop/src/java/org/apache/fop/render/ps/PSTextPainter.java
Index: PSTextPainter.java
===================================================================
RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/render/ps/PSTextPainter.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- PSTextPainter.java 27 Feb 2004 17:53:11 -0000 1.11
+++ PSTextPainter.java 3 Apr 2004 13:35:09 -0000 1.12
@@ -42,6 +42,8 @@
import org.apache.batik.gvt.text.TextPaintInfo;
import org.apache.batik.gvt.font.GVTFontFamily;
import org.apache.batik.gvt.renderer.StrokingTextPainter;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.fop.fonts.FontMetrics;
import org.apache.fop.fonts.Font;
@@ -64,6 +66,9 @@
*/
public class PSTextPainter implements TextPainter {
+ /** the logger for this class */
+ protected Log log = LogFactory.getLog(PSTextPainter.class);
+
private Document document;
/**
@@ -117,6 +122,13 @@
private boolean hasUnsupportedAttributes(AttributedCharacterIterator aci) {
boolean hasunsupported = false;
+ String text = getText(aci);
+ Font font = makeFont(aci);
+ if (hasUnsupportedGlyphs(text, font)) {
+ log.trace("-> Unsupported glyphs found");
+ hasunsupported = true;
+ }
+
TextPaintInfo tpi = (TextPaintInfo) aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.PAINT_INFO);
if ((tpi != null)
@@ -124,6 +136,7 @@
|| (tpi.strikethroughStroke != null)
|| (tpi.underlineStroke != null)
|| (tpi.overlineStroke != null))) {
+ log.trace("-> under/overlines etc. found");
hasunsupported = true;
}
@@ -132,6 +145,7 @@
if (foreground instanceof Color) {
Color col = (Color)foreground;
if (col.getAlpha() != 255) {
+ log.trace("-> transparency found");
hasunsupported = true;
}
}
@@ -139,18 +153,21 @@
Object letSpace = aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.LETTER_SPACING);
if (letSpace != null) {
+ log.trace("-> letter spacing found");
hasunsupported = true;
}
Object wordSpace = aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.WORD_SPACING);
if (wordSpace != null) {
+ log.trace("-> word spacing found");
hasunsupported = true;
}
Object lengthAdjust = aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.LENGTH_ADJUST);
if (lengthAdjust != null) {
+ log.trace("-> length adjustments found");
hasunsupported = true;
}
@@ -159,6 +176,7 @@
if (writeMod != null
&&
!GVTAttributedCharacterIterator.TextAttribute.WRITING_MODE_LTR.equals(
writeMod)) {
+ log.trace("-> Unsupported writing modes found");
hasunsupported = true;
}
@@ -166,15 +184,20 @@
GVTAttributedCharacterIterator.TextAttribute.VERTICAL_ORIENTATION);
if (GVTAttributedCharacterIterator.TextAttribute.ORIENTATION_ANGLE.equals(
vertOr)) {
+ log.trace("-> vertical orientation found");
hasunsupported = true;
}
Object rcDel = aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.TEXT_COMPOUND_DELIMITER);
if (!(rcDel instanceof SVGOMTextElement)) {
+ log.trace("-> spans found");
hasunsupported = true; //Filter spans
}
+ if (hasunsupported) {
+ log.trace("Unsupported attributes found in ACI, using
StrokingTextPainter");
+ }
return hasunsupported;
}
@@ -343,6 +366,9 @@
private Font makeFont(AttributedCharacterIterator aci) {
Float fontSize = (Float)aci.getAttribute(TextAttribute.SIZE);
+ if (fontSize == null) {
+ fontSize = new Float(10.0f);
+ }
String style = getStyle(aci);
int weight = getWeight(aci);
@@ -408,6 +434,19 @@
wordWidth += charWidth;
}
return wordWidth / 1000f;
+ }
+
+ private boolean hasUnsupportedGlyphs(String str, Font font) {
+ for (int i = 0; i < str.length(); i++) {
+ float charWidth;
+ char c = str.charAt(i);
+ if (!((c == ' ') || (c == '\n') || (c == '\r') || (c == '\t'))) {
+ if (!font.hasChar(c)) {
+ return true;
+ }
+ }
+ }
+ return false;
}
/**
1.1 xml-fop/src/java/org/apache/fop/render/ps/PSImageUtils.java
Index: PSImageUtils.java
===================================================================
/*
* Copyright 2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* $Id: PSImageUtils.java,v 1.1 2004/04/03 13:35:09 jeremias Exp $ */
package org.apache.fop.render.ps;
import java.awt.color.ColorSpace;
import java.io.IOException;
import java.io.OutputStream;
import org.apache.fop.image.FopImage;
import org.apache.fop.image.JpegImage;
import org.apache.fop.util.ASCII85OutputStream;
import org.apache.fop.util.Finalizable;
import org.apache.fop.util.FlateEncodeOutputStream;
import org.apache.fop.util.RunLengthEncodeOutputStream;
/**
* Utility code for rendering images in PostScript.
*/
public class PSImageUtils {
/**
* Renders an image to PostScript.
* @param img image to render
* @param x x position
* @param y y position
* @param w width
* @param h height
* @param gen PS generator
* @throws IOException In case of an I/O problem while rendering the image
*/
public static void renderFopImage(FopImage img, int x, int y, int w, int h,
PSGenerator gen) throws IOException {
boolean iscolor = img.getColorSpace().getType()
!= ColorSpace.CS_GRAY;
byte[] imgmap = img.getBitmaps();
gen.saveGraphicsState();
if (img.getColorSpace().getType() == ColorSpace.TYPE_CMYK) {
gen.writeln("/DeviceCMYK setcolorspace");
} else if (img.getColorSpace().getType() == ColorSpace.CS_GRAY) {
gen.writeln("/DeviceGray setcolorspace");
} else {
gen.writeln("/DeviceRGB setcolorspace");
}
gen.writeln(x + " " + y + " translate");
gen.writeln(w + " " + h + " scale");
gen.writeln("{{");
// Template: (RawData is used for the EOF signal only)
// gen.write("/RawData currentfile <first filter> filter def");
// gen.write("/Data RawData <second filter> <third filter> [...] def");
if (img instanceof JpegImage) {
gen.writeln("/RawData currentfile /ASCII85Decode filter def");
gen.writeln("/Data RawData << >> /DCTDecode filter def");
} else {
if (gen.getPSLevel() >= 3) {
gen.writeln("/RawData currentfile /ASCII85Decode filter def");
gen.writeln("/Data RawData /FlateDecode filter def");
} else {
gen.writeln("/RawData currentfile /ASCII85Decode filter def");
gen.writeln("/Data RawData /RunLengthDecode filter def");
}
}
gen.writeln("<<");
gen.writeln(" /ImageType 1");
gen.writeln(" /Width " + img.getWidth());
gen.writeln(" /Height " + img.getHeight());
gen.writeln(" /BitsPerComponent 8");
if (img.getColorSpace().getType() == ColorSpace.TYPE_CMYK) {
if (false /*TODO img.invertImage()*/) {
gen.writeln(" /Decode [1 0 1 0 1 0 1 0]");
} else {
gen.writeln(" /Decode [0 1 0 1 0 1 0 1]");
}
} else if (iscolor) {
gen.writeln(" /Decode [0 1 0 1 0 1]");
} else {
gen.writeln(" /Decode [0 1]");
}
// Setup scanning for left-to-right and top-to-bottom
gen.writeln(" /ImageMatrix [" + img.getWidth() + " 0 0 "
+ img.getHeight() + " 0 0]");
gen.writeln(" /DataSource Data");
gen.writeln(">>");
gen.writeln("image");
/* the following two lines could be enabled if something still goes wrong
* gen.write("Data closefile");
* gen.write("RawData flushfile");
*/
gen.writeln("} stopped {handleerror} if");
gen.writeln(" RawData flushfile");
gen.writeln("} exec");
/*
* for (int y=0; y<img.getHeight(); y++) {
* int indx = y * img.getWidth();
* if (iscolor) indx*= 3;
* for (int x=0; x<img.getWidth(); x++) {
* if (iscolor) {
* writeASCIIHex(imgmap[indx++] & 0xFF);
* writeASCIIHex(imgmap[indx++] & 0xFF);
* writeASCIIHex(imgmap[indx++] & 0xFF);
* } else {
* writeASCIIHex(imgmap[indx++] & 0xFF);
* }
* }
* }
*/
OutputStream out = gen.getOutputStream();
out = new ASCII85OutputStream(out);
if (img instanceof JpegImage) {
//nop
} else {
if (gen.getPSLevel() >= 3) {
out = new FlateEncodeOutputStream(out);
} else {
out = new RunLengthEncodeOutputStream(out);
}
}
out.write(imgmap);
if (out instanceof Finalizable) {
((Finalizable)out).finalizeStream();
} else {
out.flush();
}
gen.writeln("");
gen.restoreGraphicsState();
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]