aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremias Maerki <jeremias@apache.org>2004-04-03 13:35:09 +0000
committerJeremias Maerki <jeremias@apache.org>2004-04-03 13:35:09 +0000
commit78e4c46bdf3e66a29a605c924d1969bb2211c5b8 (patch)
tree27a70b2447a2bfb998d5654350645286ec94f739
parent1715c728ad273c9d581828798234d6e657a00570 (diff)
downloadxmlgraphics-fop-78e4c46bdf3e66a29a605c924d1969bb2211c5b8.tar.gz
xmlgraphics-fop-78e4c46bdf3e66a29a605c924d1969bb2211c5b8.zip
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. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@197487 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--src/java/org/apache/fop/render/ps/EPSDocumentGraphics2D.java7
-rw-r--r--src/java/org/apache/fop/render/ps/PSDocumentGraphics2D.java4
-rw-r--r--src/java/org/apache/fop/render/ps/PSGenerator.java9
-rw-r--r--src/java/org/apache/fop/render/ps/PSGraphics2D.java125
-rw-r--r--src/java/org/apache/fop/render/ps/PSImageUtils.java150
-rw-r--r--src/java/org/apache/fop/render/ps/PSRenderer.java1
-rw-r--r--src/java/org/apache/fop/render/ps/PSTextPainter.java39
7 files changed, 265 insertions, 70 deletions
diff --git a/src/java/org/apache/fop/render/ps/EPSDocumentGraphics2D.java b/src/java/org/apache/fop/render/ps/EPSDocumentGraphics2D.java
index 5d46ad533..340ac85de 100644
--- a/src/java/org/apache/fop/render/ps/EPSDocumentGraphics2D.java
+++ b/src/java/org/apache/fop/render/ps/EPSDocumentGraphics2D.java
@@ -20,6 +20,8 @@ package org.apache.fop.render.ps;
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 @@ public class EPSDocumentGraphics2D extends AbstractPSDocumentGraphics2D {
//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
diff --git a/src/java/org/apache/fop/render/ps/PSDocumentGraphics2D.java b/src/java/org/apache/fop/render/ps/PSDocumentGraphics2D.java
index 93a66fe8e..ce419f722 100644
--- a/src/java/org/apache/fop/render/ps/PSDocumentGraphics2D.java
+++ b/src/java/org/apache/fop/render/ps/PSDocumentGraphics2D.java
@@ -25,6 +25,7 @@ import java.io.IOException;
//FOP
import org.apache.fop.apps.Document;
+import org.apache.fop.apps.Version;
import org.apache.fop.fonts.FontSetup;
/**
@@ -91,7 +92,8 @@ public class PSDocumentGraphics2D extends AbstractPSDocumentGraphics2D {
//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);
diff --git a/src/java/org/apache/fop/render/ps/PSGenerator.java b/src/java/org/apache/fop/render/ps/PSGenerator.java
index 3f739eac9..4a64f626c 100644
--- a/src/java/org/apache/fop/render/ps/PSGenerator.java
+++ b/src/java/org/apache/fop/render/ps/PSGenerator.java
@@ -69,6 +69,15 @@ public class PSGenerator {
}
/**
+ * 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
diff --git a/src/java/org/apache/fop/render/ps/PSGraphics2D.java b/src/java/org/apache/fop/render/ps/PSGraphics2D.java
index 97ab34417..e527450d7 100644
--- a/src/java/org/apache/fop/render/ps/PSGraphics2D.java
+++ b/src/java/org/apache/fop/render/ps/PSGraphics2D.java
@@ -38,6 +38,7 @@ import java.awt.Shape;
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 @@ import java.io.IOException;
//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 @@ import org.apache.fop.apps.Document;
*/
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 class PSGraphics2D extends AbstractGraphics2D {
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 @@ public class PSGraphics2D extends AbstractGraphics2D {
// 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 @@ public class PSGraphics2D extends AbstractGraphics2D {
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);
-
- TempImage(int width, int height, byte[] result,
+ 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[] 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 @@ public class PSGraphics2D extends AbstractGraphics2D {
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 @@ public class PSGraphics2D extends AbstractGraphics2D {
return this.mask;
}
- // get the image bytes, and bytes properties
-
- // get uncompressed image bytes
public byte[] getBitmaps() {
return this.bitmaps;
}
@@ -372,22 +379,8 @@ public class PSGraphics2D extends AbstractGraphics2D {
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 class PSGraphics2D extends AbstractGraphics2D {
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 @@ public class PSGraphics2D extends AbstractGraphics2D {
* @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 class PSGraphics2D extends AbstractGraphics2D {
public void draw(Shape s) {
preparePainting();
try {
- // System.out.println("draw(Shape)");
gen.saveGraphicsState();
Shape imclip = getClip();
writeClip(imclip);
@@ -578,9 +569,9 @@ public class PSGraphics2D extends AbstractGraphics2D {
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 @@ public class PSGraphics2D extends AbstractGraphics2D {
case BasicStroke.CAP_SQUARE:
gen.writeln("2 setlinecap");
break;
+ default: log.warn("Unsupported line cap: " + ec);
}
int lj = bs.getLineJoin();
@@ -631,6 +623,7 @@ public class PSGraphics2D extends AbstractGraphics2D {
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 class PSGraphics2D extends AbstractGraphics2D {
*/
public void drawRenderedImage(RenderedImage img, AffineTransform xform) {
preparePainting();
- System.out.println("drawRenderedImage");
+ log.warn("NYI: drawRenderedImage");
}
/**
@@ -701,7 +694,7 @@ public class PSGraphics2D extends AbstractGraphics2D {
public void drawRenderableImage(RenderableImage img,
AffineTransform xform) {
preparePainting();
- System.out.println("drawRenderableImage");
+ log.warn("NYI: drawRenderableImage");
}
/**
@@ -807,7 +800,7 @@ public class PSGraphics2D extends AbstractGraphics2D {
*/
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 class PSGraphics2D extends AbstractGraphics2D {
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 class PSGraphics2D extends AbstractGraphics2D {
*/
public void fill(Shape s) {
preparePainting();
- // System.err.println("fill");
try {
gen.saveGraphicsState();
Shape imclip = getClip();
@@ -1030,7 +1022,6 @@ public class PSGraphics2D extends AbstractGraphics2D {
* @return the device configuration
*/
public GraphicsConfiguration getDeviceConfiguration() {
- // System.out.println("getDeviceConviguration");
return GraphicsEnvironment.getLocalGraphicsEnvironment().
getDefaultScreenDevice().getDefaultConfiguration();
}
@@ -1083,7 +1074,7 @@ public class PSGraphics2D extends AbstractGraphics2D {
* @param c1 the XOR alternation color
*/
public void setXORMode(Color c1) {
- System.out.println("setXORMode");
+ log.warn("NYI: setXORMode");
}
@@ -1108,7 +1099,7 @@ public class PSGraphics2D extends AbstractGraphics2D {
*/
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
diff --git a/src/java/org/apache/fop/render/ps/PSImageUtils.java b/src/java/org/apache/fop/render/ps/PSImageUtils.java
new file mode 100644
index 000000000..7edc340ad
--- /dev/null
+++ b/src/java/org/apache/fop/render/ps/PSImageUtils.java
@@ -0,0 +1,150 @@
+/*
+ * 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$ */
+
+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();
+ }
+
+
+}
diff --git a/src/java/org/apache/fop/render/ps/PSRenderer.java b/src/java/org/apache/fop/render/ps/PSRenderer.java
index 614e9922a..ef39dcc5f 100644
--- a/src/java/org/apache/fop/render/ps/PSRenderer.java
+++ b/src/java/org/apache/fop/render/ps/PSRenderer.java
@@ -324,6 +324,7 @@ public class PSRenderer extends AbstractRenderer {
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);
diff --git a/src/java/org/apache/fop/render/ps/PSTextPainter.java b/src/java/org/apache/fop/render/ps/PSTextPainter.java
index 4112ac295..2c58813cc 100644
--- a/src/java/org/apache/fop/render/ps/PSTextPainter.java
+++ b/src/java/org/apache/fop/render/ps/PSTextPainter.java
@@ -42,6 +42,8 @@ import org.apache.batik.gvt.text.GVTAttributedCharacterIterator;
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 @@ import org.apache.fop.apps.Document;
*/
public class PSTextPainter implements TextPainter {
+ /** the logger for this class */
+ protected Log log = LogFactory.getLog(PSTextPainter.class);
+
private Document document;
/**
@@ -117,6 +122,13 @@ public class PSTextPainter implements TextPainter {
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 @@ public class PSTextPainter implements TextPainter {
|| (tpi.strikethroughStroke != null)
|| (tpi.underlineStroke != null)
|| (tpi.overlineStroke != null))) {
+ log.trace("-> under/overlines etc. found");
hasunsupported = true;
}
@@ -132,6 +145,7 @@ public class PSTextPainter implements TextPainter {
if (foreground instanceof Color) {
Color col = (Color)foreground;
if (col.getAlpha() != 255) {
+ log.trace("-> transparency found");
hasunsupported = true;
}
}
@@ -139,18 +153,21 @@ public class PSTextPainter implements TextPainter {
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 @@ public class PSTextPainter implements TextPainter {
if (writeMod != null
&& !GVTAttributedCharacterIterator.TextAttribute.WRITING_MODE_LTR.equals(
writeMod)) {
+ log.trace("-> Unsupported writing modes found");
hasunsupported = true;
}
@@ -166,15 +184,20 @@ public class PSTextPainter implements TextPainter {
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 @@ public class PSTextPainter implements TextPainter {
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);
@@ -410,6 +436,19 @@ public class PSTextPainter implements TextPainter {
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;
+ }
+
/**
* Get the outline shape of the text characters.
* This uses the StrokingTextPainter to get the outline