aboutsummaryrefslogtreecommitdiffstats
path: root/src/org/apache/fop/render
diff options
context:
space:
mode:
authorKeiron Liddle <keiron@apache.org>2001-05-17 07:48:06 +0000
committerKeiron Liddle <keiron@apache.org>2001-05-17 07:48:06 +0000
commitc824ede99cb449252823876b6224f6ed75e799cd (patch)
tree771770e0d8604c5511de0249b4072817fc483736 /src/org/apache/fop/render
parentf89f05c27124377ec9497b30d4d75874a2bec67b (diff)
downloadxmlgraphics-fop-c824ede99cb449252823876b6224f6ed75e799cd.tar.gz
xmlgraphics-fop-c824ede99cb449252823876b6224f6ed75e799cd.zip
FOP now uses Batik to render svg
This is handled for awt - using batik to render to a graphic and pdf. Pdf still requires better image support. The elements and properties are generated from the svgelements.xml document. The version of batik is 17/05/2001 cvs. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194250 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/org/apache/fop/render')
-rw-r--r--src/org/apache/fop/render/PrintRenderer.java2
-rw-r--r--src/org/apache/fop/render/Renderer.java2
-rw-r--r--src/org/apache/fop/render/awt/AWTRenderer.java679
-rw-r--r--src/org/apache/fop/render/mif/MIFRenderer.java8
-rwxr-xr-xsrc/org/apache/fop/render/pcl/PCLRenderer.java5
-rwxr-xr-xsrc/org/apache/fop/render/pcl/PCLSVGRenderer.java1400
-rw-r--r--src/org/apache/fop/render/pdf/PDFRenderer.java197
-rw-r--r--src/org/apache/fop/render/pdf/SVGRenderer.java2759
-rwxr-xr-xsrc/org/apache/fop/render/txt/TXTRenderer.java3
-rw-r--r--src/org/apache/fop/render/xml/XMLRenderer.java2
10 files changed, 349 insertions, 4708 deletions
diff --git a/src/org/apache/fop/render/PrintRenderer.java b/src/org/apache/fop/render/PrintRenderer.java
index efc9b8d56..21094a881 100644
--- a/src/org/apache/fop/render/PrintRenderer.java
+++ b/src/org/apache/fop/render/PrintRenderer.java
@@ -26,7 +26,7 @@ import org.apache.fop.datatypes.*;
//import org.apache.fop.datatypes.IDReferences;
import org.apache.fop.render.pdf.FontSetup;
-import org.apache.fop.dom.svg.*;
+import org.apache.fop.svg.SVGArea;
// Java
import java.io.IOException;
diff --git a/src/org/apache/fop/render/Renderer.java b/src/org/apache/fop/render/Renderer.java
index 5fcf18d16..adc268a9a 100644
--- a/src/org/apache/fop/render/Renderer.java
+++ b/src/org/apache/fop/render/Renderer.java
@@ -51,7 +51,7 @@
package org.apache.fop.render;
// FOP
-import org.apache.fop.dom.svg.SVGArea;
+import org.apache.fop.svg.SVGArea;
import org.apache.fop.image.ImageArea;
import org.apache.fop.apps.FOPException;
import org.apache.fop.layout.*;
diff --git a/src/org/apache/fop/render/awt/AWTRenderer.java b/src/org/apache/fop/render/awt/AWTRenderer.java
index 2d0790baa..79dabb579 100644
--- a/src/org/apache/fop/render/awt/AWTRenderer.java
+++ b/src/org/apache/fop/render/awt/AWTRenderer.java
@@ -15,14 +15,20 @@ import org.apache.fop.messaging.MessageHandler;
import org.apache.fop.datatypes.*;
import org.apache.fop.image.*;
import org.apache.fop.svg.*;
-import org.apache.fop.dom.svg.*;
-import org.apache.fop.dom.svg.SVGArea;
import org.apache.fop.render.pdf.*;
import org.apache.fop.viewer.*;
import org.apache.fop.apps.*;
import org.w3c.dom.svg.*;
+import org.apache.batik.bridge.*;
+import org.apache.batik.swing.svg.*;
+import org.apache.batik.swing.gvt.*;
+import org.apache.batik.gvt.*;
+import org.apache.batik.gvt.renderer.*;
+import org.apache.batik.gvt.filter.*;
+import org.apache.batik.gvt.event.*;
+
import java.awt.*;
import java.awt.Image;
import java.awt.image.*;
@@ -629,8 +635,13 @@ public class AWTRenderer implements Renderer, Printable, Pageable {
Enumeration e = area.getChildren().elements();
while (e.hasMoreElements()) {
- org.apache.fop.layout.Box b =
- (org.apache.fop.layout.Box) e.nextElement();
+ org.apache.fop.layout.Box b = (org.apache.fop.layout.Box) e.nextElement();
+ if(b instanceof InlineArea) {
+ InlineArea ia = (InlineArea)b;
+ this.currentYPosition = ry - ia.getYOffset();
+ } else {
+ this.currentYPosition = ry - area.getPlacementOffset();
+ }
b.render(this);
}
@@ -662,26 +673,65 @@ public class AWTRenderer implements Renderer, Printable, Pageable {
this.currentXPosition += area.getContentWidth();
}
-
public void renderSVGArea(SVGArea area) {
- int x = this.currentAreaContainerXPosition;
+ int x = this.currentXPosition;
int y = this.currentYPosition;
int w = area.getContentWidth();
int h = area.getHeight();
- Enumeration e = area.getChildren().elements();
- while (e.hasMoreElements()) {
- Object o = e.nextElement();
- if (o instanceof GraphicImpl) {
- renderElement(area, (GraphicImpl) o, x, y, null);
- }
- }
+// this.currentYPosition -= h;
- this.currentYPosition -= h;
+ SVGDocument doc = area.getSVGDocument();
+
+ UserAgent userAgent = new MUserAgent(new AffineTransform());
+
+ GVTBuilder builder = new GVTBuilder();
+ GraphicsNodeRenderContext rc = getRenderContext();
+ BridgeContext ctx = new BridgeContext(userAgent, rc);
+ GraphicsNode root;
+ graphics.translate(x / 1000f, pageHeight - y / 1000f);
+ graphics.setRenderingHints(rc.getRenderingHints());
+ try {
+ root = builder.build(ctx, doc);
+ root.paint(graphics, rc);
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+ graphics.translate(-x / 1000f, y / 1000f - pageHeight);
+ this.currentXPosition += area.getContentWidth();
}
+ public GraphicsNodeRenderContext getRenderContext() {
+ GraphicsNodeRenderContext nodeRenderContext = null;
+ if (nodeRenderContext == null) {
+ RenderingHints hints = new RenderingHints(null);
+ hints.put(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+
+ hints.put(RenderingHints.KEY_INTERPOLATION,
+ RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+
+ FontRenderContext fontRenderContext =
+ new FontRenderContext(new AffineTransform(), true, true);
+
+ TextPainter textPainter = new StrokingTextPainter();
+
+ GraphicsNodeRableFactory gnrFactory =
+ new ConcreteGraphicsNodeRableFactory();
+
+ nodeRenderContext =
+ new GraphicsNodeRenderContext(new AffineTransform(),
+ null,
+ hints,
+ fontRenderContext,
+ textPainter,
+ gnrFactory);
+ }
+
+ return nodeRenderContext;
+ }
public void setProducer(String producer) {
@@ -782,540 +832,121 @@ public class AWTRenderer implements Renderer, Printable, Pageable {
}
}
+ public void renderForeignObjectArea(ForeignObjectArea area) {
+ area.getObject().render(this);
+ }
-
- public void renderElement(SVGArea svgarea, GraphicImpl area,
- int posx, int posy, Vector parentTransforms) {
- int x = posx;
- int y = posy;
- Hashtable style = area.oldgetStyle();
- DrawingInstruction di = createInstruction(area, style);
-
- Object o = null;
- Vector v = area.oldgetTransform();
- v = (v == null) ? new Vector() : v;
- Vector trans = new Vector(v);
- parentTransforms = (parentTransforms == null) ? new Vector() :
- parentTransforms;
-
- if (parentTransforms != null) {
- trans.addAll(0, parentTransforms);
+ protected class MUserAgent implements UserAgent {
+ AffineTransform currentTransform = null;
+ /**
+ * Creates a new SVGUserAgent.
+ */
+ protected MUserAgent(AffineTransform at) {
+ currentTransform = at;
}
- float red = (float) graphics.getColor().getRed();
- float green = (float) graphics.getColor().getGreen();
- float blue = (float) graphics.getColor().getBlue();
- Color c = null;
-
- ColorType ct = null;
- try {
- o = style.get("fill");
- if (o != null && o instanceof ColorType) {
- ct = (ColorType) o;
- c = new Color((int)(ct.red() * 255f),
- (int)(ct.green() * 255f), (int)(ct.blue() * 255f));
- }
- o = style.get("stroke");
- if (c == null && o != null && o instanceof ColorType) {
- ct = (ColorType) o;
- c = new Color((int)(ct.red() * 255f),
- (int)(ct.green() * 255f), (int)(ct.blue() * 255f));
- }
- } catch (Exception ex) {
- MessageHandler.errorln("Can't set color: R G B : " +
- (int)(ct.red() * 255f) + " " +
- (int)(ct.green() * 255f) + " " +
- (int)(ct.blue() * 255f));
- c = Color.pink;
+ /**
+ * Displays an error message.
+ */
+ public void displayError(String message) {
+ System.err.println(message);
}
-
- if (c == null) {
- c = new Color((int) red, (int) green, (int) blue);
+
+ /**
+ * Displays an error resulting from the specified Exception.
+ */
+ public void displayError(Exception ex) {
+ ex.printStackTrace(System.err);
}
- Color oldColor = graphics.getColor();
- if (area instanceof SVGLineElement) {
- graphics.setColor(c);
- SVGLineElementImpl lg = (SVGLineElementImpl) area;
-
- float x1 = lg.getX1().getBaseVal().getValue() * 1000 + posx;
- float y1 = posy - lg.getY1().getBaseVal().getValue() * 1000 ;
- float x2 = lg.getX2().getBaseVal().getValue() * 1000 + posx;
- float y2 = posy - lg.getY2().getBaseVal().getValue() * 1000;
- // TODO:
- // The thickness of contour protect.
- int th = 1;
- o = style.get("stroke-width");
- if (o != null)
- th = (int)((SVGLengthImpl) o).getValue();
- Line2D.Double aLine = new Line2D.Double(x1 / 1000f,
- pageHeight - y1 / 1000f, x2 / 1000f,
- pageHeight - y2 / 1000f);
- drawShape(transformShape(trans, aLine), di);
- graphics.setColor(oldColor);
- } else if (area instanceof SVGRectElement) {
- graphics.setColor(c);
- SVGRectElement rg = (SVGRectElement) area;
- float rectx = rg.getX().getBaseVal().getValue() * 1000 + posx;
- float recty = posy - rg.getY().getBaseVal().getValue() * 1000;
- float rx = rg.getRx().getBaseVal().getValue() * 1000;
- float ry = rg.getRy().getBaseVal().getValue() * 1000;
- float rw = rg.getWidth().getBaseVal().getValue() * 1000;
- float rh = rg.getHeight().getBaseVal().getValue() * 1000;
-
- // TODO:
- // rx and ry are roundings.
- // RoundRectangle2D.Double
- Rectangle aRectangle = new Rectangle();
- aRectangle.setRect(rectx / 1000d,
- pageHeight - recty / 1000d, rw / 1000d, rh / 1000d);
- drawShape(transformShape(trans, aRectangle), di);
- graphics.setColor(oldColor);
- } else if (area instanceof SVGCircleElement) {
- graphics.setColor(c);
- SVGCircleElement cg = (SVGCircleElement) area;
- float cx = cg.getCx().getBaseVal().getValue() * 1000 + posx;
- float cy = posy - cg.getCy().getBaseVal().getValue() * 1000;
- float r = cg.getR().getBaseVal().getValue();
- Ellipse2D.Double anEllipse =
- new Ellipse2D.Double(cx / 1000d - r,
- pageHeight - cy / 1000d - r, r * 2d, r * 2d);
- drawShape(transformShape(trans, anEllipse), di);
- graphics.setColor(oldColor);
- } else if (area instanceof SVGEllipseElement) {
- graphics.setColor(c);
- SVGEllipseElement cg = (SVGEllipseElement) area;
- float cx = cg.getCx().getBaseVal().getValue() * 1000 + posx;
- float cy = posy - cg.getCy().getBaseVal().getValue() * 1000;
- float rx = cg.getRx().getBaseVal().getValue();
- float ry = cg.getRy().getBaseVal().getValue();
- Ellipse2D.Double anEllipse =
- new Ellipse2D.Double(cx / 1000d - rx,
- pageHeight - cy / 1000d - ry, rx * 2d, ry * 2d);
- drawShape(transformShape(trans, anEllipse), di);
- graphics.setColor(oldColor);
- } else if (area instanceof SVGImageElementImpl) {
- SVGImageElementImpl ig = (SVGImageElementImpl) area;
- renderImage(ig.link, ig.x + posx / 1000f,
- pageHeight - (posy / 1000f - ig.y), ig.width,
- ig.height, trans);
- } else if (area instanceof SVGUseElementImpl) {
- SVGUseElementImpl ug = (SVGUseElementImpl) area;
- String ref = ug.link;
- ref = ref.substring(1, ref.length());
- GraphicImpl graph = null;
- // graph = area.locateDef(ref);
- if (graph != null) {
- // probably not the best way to do this, should be able
- // to render without the style being set.
- // GraphicImpl parent = graph.getGraphicParent();
- // graph.setParent(area);
- // need to clip (if necessary) to the use area
- // the style of the linked element is as if is was
- // a direct descendant of the use element.
-
- renderElement(svgarea, graph, posx, posy, trans);
- // graph.setParent(parent);
- }
- } else if (area instanceof SVGPolylineElementImpl) {
- graphics.setColor(c);
- Vector points = ((SVGPolylineElementImpl) area).points;
- PathPoint p = null;
- Point2D.Double p1 = null;
- Point2D.Double p2 = null;
- if (points.size() > 0) {
- p = (PathPoint) points.elementAt(0);
- double xc = p.x * 1000f + posx;
- double yc = posy - p.y * 1000f;
- p1 = new Point2D.Double(xc / 1000f,
- pageHeight - yc / 1000f);
-
- int[] xarr = {(int) xc};
- int[] yarr = {(int) yc};
- graphics.drawPolyline(xarr, yarr, 1);
- }
- Line2D.Double aLine;
- for (int i = 1; i < points.size(); i++) {
- p = (PathPoint) points.elementAt(i);
- p2 = new Point2D.Double(p.x + posx / 1000f,
- pageHeight - (posy - p.y * 1000f) / 1000f);
- aLine = new Line2D.Double(p1, p2);
- graphics.draw(transformShape(trans, aLine));
- p1 = p2;
- }
- graphics.setColor(oldColor);
- } else if (area instanceof SVGPolygonElementImpl) {
- graphics.setColor(c);
- java.awt.Polygon aPolygon =
- convertPolygon(((SVGPolygonElementImpl) area),
- posx, posy);
- drawShape(transformShape(trans, aPolygon), di);
- graphics.setColor(oldColor);
- } else if (area instanceof SVGGElementImpl) {
- renderGArea(svgarea, (SVGGElementImpl) area, x, y,
- parentTransforms);
- } else if (area instanceof SVGPathElementImpl) {
- graphics.setColor(c);
- GeneralPath path =
- convertPath((SVGPathElementImpl) area, posx, posy);
- drawShape(transformShape(trans, path), di);
- graphics.setColor(oldColor);
- } else if (area instanceof SVGTextElementImpl) {
- MessageHandler.errorln("SVGTextElementImpl is not implemented yet.");
- // renderText(svgarea, (SVGTextElementImpl)area, 0, 0, di);
- } else if (area instanceof SVGArea) {
- // the x and y pos will be wrong!
- Enumeration e = ((SVGArea) area).getChildren().elements();
- while (e.hasMoreElements()) {
- Object el = e.nextElement();
- if (o instanceof GraphicImpl) {
- renderElement((SVGArea) area, (GraphicImpl) el, x,
- y, parentTransforms);
- }
- }
+ /**
+ * Displays a message in the User Agent interface.
+ * The given message is typically displayed in a status bar.
+ */
+ public void displayMessage(String message) {
+ System.out.println(message);
}
- // should be done with some cleanup code, so only
- // required values are reset.
- } // renderElement
-
-
- public void renderGArea(SVGArea svgarea, SVGGElementImpl area,
- int posx, int posy, Vector v) {
+ /**
+ * Returns a customized the pixel to mm factor.
+ */
+ public float getPixelToMM() {
+ return 0.264583333333333333333f; // 72 dpi
+ }
+ /**
+ * Returns the language settings.
+ */
+ public String getLanguages() {
+ return "en";//userLanguages;
+ }
- Vector trans = null;
- // trans = new Vector(area.oldgetTransform());
- // trans.addAll(0, v);
- /* Enumeration e = area.getChildren().elements();
- while (e.hasMoreElements()) {
- Object o = e.nextElement();
- if(o instanceof GraphicImpl) {
- renderElement(svgarea, (GraphicImpl)o, posx, posy, trans);
- }
- }*/
- }
- public void renderGArea(SVGArea svgarea, SVGGElementImpl area,
- int posx, int posy) {
- renderGArea(svgarea, area, posx, posy, new Vector());
- }
+ /**
+ * Returns the user stylesheet uri.
+ * @return null if no user style sheet was specified.
+ */
+ public String getUserStyleSheetURI() {
+ return null;//userStyleSheetURI;
+ }
+ /**
+ * Returns the class name of the XML parser.
+ */
+ public String getXMLParserClassName() {
+ String parserClassName =
+ System.getProperty("org.xml.sax.parser");
+ if (parserClassName == null) {
+ parserClassName = "org.apache.xerces.parsers.SAXParser";
+ }
+ return parserClassName;//application.getXMLParserClassName();
+ }
- /**
- * Applies SVGTransform to the shape and gets the transformed shape.
- * The type of the new shape may be different to the original type.
- */
- public Shape transformShape(Vector trans, Shape shape) {
- if (trans == null || trans.size() == 0) {
- return shape;
+ /**
+ * Opens a link in a new component.
+ * @param doc The current document.
+ * @param uri The document URI.
+ */
+ public void openLink(SVGAElement elt)
+ {
+ //application.openLink(uri);
}
- AffineTransform at;
- for (int i = trans.size() - 1; i >= 0; i--) {
- org.w3c.dom.svg.SVGTransform t =
- (org.w3c.dom.svg.SVGTransform) trans.elementAt(i);
- SVGMatrix matrix = t.getMatrix();
- at = new AffineTransform(matrix.getA(), matrix.getB(),
- matrix.getC(), matrix.getD(), matrix.getE(),
- matrix.getF());
- shape = at.createTransformedShape(shape);
+ public Point getClientAreaLocationOnScreen()
+ {
+ return new Point(0, 0);
}
- return shape;
- }
+ public void setSVGCursor(java.awt.Cursor cursor)
+ {
+ }
- /**
- * Mapps a SVG-Polygon to a AWT-Polygon.
- */
- public java.awt.Polygon convertPolygon(SVGPolygonElementImpl svgpl,
- int x, int y) {
- java.awt.Polygon aPolygon = new java.awt.Polygon();
- Vector points = svgpl.points;
-
- PathPoint p;
- for (int i = 0; i < points.size(); i++) {
- p = (PathPoint) points.elementAt(i);
- aPolygon.addPoint((int)(x / 1000f + p.x),
- pageHeight - (int)(y / 1000f - p.y));
+ public AffineTransform getTransform()
+ {
+ return currentTransform;
}
- return aPolygon;
- }
+ public Dimension2D getViewportSize()
+ {
+ return new Dimension(100, 100);
+ }
- // TODO: other attributes of DrawingInstruction protect too.
- protected DrawingInstruction createInstruction(GraphicImpl area,
- Hashtable style) {
- DrawingInstruction di = new DrawingInstruction();
- Object sp;
- sp = style.get("fill");
- if (sp != null && !(sp instanceof String && sp.equals("none"))) {
- di.fill = true;
+ public EventDispatcher getEventDispatcher()
+ {
+ return null;
}
- // ...
- return di;
- }
- // Draws a shape.
- // TODO: other attributes of DrawingInstruction protect too.
- protected void drawShape(Shape s, DrawingInstruction di) {
- if (di.fill) {
- graphics.fill(s);
- } else {
- graphics.draw(s);
+ public boolean supportExtension(String str)
+ {
+ return false;
}
- }
- /**
- * Mapps a SVG-Path to a AWT-GeneralPath.
- */
- public GeneralPath convertPath(SVGPathElementImpl svgpath, float x,
- float y) {
- Vector points = svgpath.pathElements;
- GeneralPath path = new GeneralPath();
-
- float lastx = 0;
- float lasty = 0;
- SVGPathSegImpl pathmoveto = null;
-
- for (Enumeration e = points.elements(); e.hasMoreElements();) {
- SVGPathSegImpl pc = (SVGPathSegImpl) e.nextElement();
- float[] vals = pc.getValues();
- float lastcx = 0;
- float lastcy = 0;
- switch (pc.getPathSegType()) {
- case SVGPathSeg.PATHSEG_MOVETO_ABS:
- lastx = vals[0];
- lasty = vals[1];
- pathmoveto = pc;
- path.moveTo(lastx + x / 1000f,
- pageHeight - y / 1000f + lasty);
- break;
- case SVGPathSeg.PATHSEG_MOVETO_REL:
- if (pathmoveto == null) {
- lastx = vals[0];
- lasty = vals[1];
- path.moveTo(lastx + x / 1000f,
- pageHeight - y / 1000f + lasty);
- pathmoveto = pc;
- } else {
- lastx += vals[0];
- lasty += vals[1];
- path.lineTo(lastx + x / 1000f,
- pageHeight - y / 1000f + lasty);
-
- }
- break;
- case SVGPathSeg.PATHSEG_LINETO_ABS:
- lastx = vals[0];
- lasty = vals[1];
- path.lineTo(lastx + x / 1000f,
- pageHeight - y / 1000f + lasty);
- break;
- case SVGPathSeg.PATHSEG_LINETO_REL:
- lastx += vals[0];
- lasty += vals[1];
- path.lineTo(lastx + x / 1000f,
- pageHeight - y / 1000f + lasty);
- break;
- case SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:
- lasty = vals[0];
- path.lineTo(lastx + x / 1000f,
- pageHeight - y / 1000f + lasty);
- break;
- case SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:
- lasty += vals[0];
- path.lineTo(lastx + x / 1000f,
- pageHeight - y / 1000f + lasty);
- break;
- case SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:
- lastx = vals[0];
- path.lineTo(lastx + x / 1000f,
- pageHeight - y / 1000f + lasty);
- break;
- case SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:
- lastx += vals[0];
- path.lineTo(lastx + x / 1000f,
- pageHeight - y / 1000f + lasty);
- break;
- case SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:
- lastx = vals[4];
- lasty = vals[5];
- lastcx = vals[2];
- lastcy = vals[3];
- path.curveTo(x / 1000f + vals[0],
- pageHeight - y / 1000f + vals[1],
- x / 1000f + lastcx,
- pageHeight - y / 1000f + lastcy,
- x / 1000f + lastx,
- pageHeight - y / 1000f + lasty);
- break;
- case SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:
- path.curveTo(x / 1000f + vals[0] + lastx,
- pageHeight - y / 1000f + vals[1] + lasty,
- x / 1000f + lastx + vals[2],
- pageHeight - y / 1000f + lasty + vals[3],
- x / 1000f + lastx + vals[4],
- pageHeight - y / 1000f + lasty + vals[5]);
- lastcx = vals[2] + lastx;
- lastcy = vals[3] + lasty;
- lastx += vals[4];
- lasty += vals[5];
- break;
- case SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
- if (lastcx == 0)
- lastcx = lastx;
- if (lastcy == 0)
- lastcy = lasty;
- lastx = vals[2];
- lasty = vals[3];
- path.curveTo(x / 1000f + lastcx,
- pageHeight - y / 1000f + lastcy,
- x / 1000f + vals[0],
- pageHeight - y / 1000f + vals[1],
- x / 1000f + lastx,
- pageHeight - y / 1000f + lasty);
- break;
- case SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
- if (lastcx == 0)
- lastcx = lastx;
- if (lastcy == 0)
- lastcy = lasty;
- path.curveTo(x / 1000f + lastcx,
- pageHeight - y / 1000f + lastcy,
- x / 1000f + lastx + vals[0],
- pageHeight - y / 1000f + lasty + vals[1],
- x / 1000f + lastx + vals[2],
- pageHeight - y / 1000f + lasty + vals[3]);
- lastx += vals[2];
- lasty += vals[3];
- break;
- case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:
- if (lastcx == 0)
- lastcx = lastx;
- if (lastcy == 0)
- lastcy = lasty;
- lastx = vals[0];
- lasty = vals[1];
- lastcx = 0;
- lastcy = 0;
- path.quadTo(x / 1000f + lastcx,
- pageHeight - y / 1000f + lastcy,
- x / 1000f + lastx,
- pageHeight - y / 1000f + lasty);
- break;
- case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:
- if (lastcx == 0)
- lastcx = lastx;
- if (lastcy == 0)
- lastcy = lasty;
-
- path.quadTo(x / 1000f + lastcx ,
- pageHeight - y / 1000f + lastcy,
- x / 1000f + lastx + vals[0],
- pageHeight - y / 1000f + lasty + vals[1]);
-
- lastx += vals[0];
- lasty += vals[1];
- lastcx = 0;
- lastcy = 0;
- break;
- case SVGPathSeg.PATHSEG_ARC_ABS:
- {
- // Arc2D.Double arc = new Arc2D.Double();
- // arc.setAngles(current point, end point); ....
- double rx = vals[0];
- double ry = vals[1];
- double theta = vals[2];
- boolean largearcflag = (vals[3] == 1.0);
- boolean sweepflag = (vals[4] == 1.0);
-
- double cx = lastx;
- double cy = lasty;
-
- path.curveTo(x / 1000f + lastx,
- pageHeight - y / 1000f + lasty,
- x / 1000f + vals[0],
- pageHeight - y / 1000f + vals[1],
- x / 1000f + vals[5],
- pageHeight - y / 1000f + vals[6]);
-
- lastcx = 0; //??
- lastcy = 0; //??
- lastx = vals[5];
- lasty = vals[6];
- }
- break;
- case SVGPathSeg.PATHSEG_ARC_REL:
- {
- double rx = vals[0];
- double ry = vals[1];
- double theta = vals[2];
- boolean largearcflag = (vals[3] == 1.0);
- boolean sweepflag = (vals[4] == 1.0);
-
- path.curveTo(x / 1000f + lastx,
- pageHeight - y / 1000f + lasty,
- x / 1000f + (vals[0] + lastx),
- pageHeight - y / 1000f + (vals[1] + lasty),
- x / 1000f + (vals[5] + lastx),
- pageHeight - y / 1000f + (vals[6] + lasty));
- lastcx = 0; //??
- lastcy = 0; //??
- lastx += vals[5];
- lasty += vals[6];
- }
- break;
- case SVGPathSeg.PATHSEG_CLOSEPATH:
- path.closePath();
- break;
-
-
- } // switch
- } // for points.elements()
-
- return path;
- } // convertPath
- /*
- if(di == null) {
- currentStream.add("S\n");
- } else {
- if(di.fill) {
- if(di.stroke) {
- if(!di.nonzero)
- currentStream.add("B*\n");
- else
- currentStream.add("B\n");
- } else {
- if(!di.nonzero)
- currentStream.add("f*\n");
- else
- currentStream.add("f\n");
- }
- } else {
- // if(di.stroke)
- currentStream.add("S\n");
- }
- }
- */
-
- /*
- * by pdfrenderer übernommen.
- *
- */
- class DrawingInstruction {
- boolean stroke = false;
- boolean nonzero = false; // non-zero fill rule "f*", "B*" operator
- boolean fill = false;
- int linecap = 0; // butt
- int linejoin = 0; // miter
- int miterwidth = 8;
- }
+ public boolean hasFeature(String str)
+ {
+ return false;
+ }
- public void renderForeignObjectArea(ForeignObjectArea area) {
- area.getObject().render(this);
+ public void registerExtension(BridgeExtension be)
+ {
+ }
}
-
}
-
-
-
diff --git a/src/org/apache/fop/render/mif/MIFRenderer.java b/src/org/apache/fop/render/mif/MIFRenderer.java
index 6ae5ffe33..07fa3e12a 100644
--- a/src/org/apache/fop/render/mif/MIFRenderer.java
+++ b/src/org/apache/fop/render/mif/MIFRenderer.java
@@ -67,7 +67,7 @@ import org.apache.fop.fo.*;
import org.apache.fop.layout.*;
import org.apache.fop.layout.inline.*;
import org.apache.fop.datatypes.*;
-import org.apache.fop.svg.PathPoint;
+import org.apache.fop.svg.*;
import org.apache.fop.mif.*;
import org.apache.fop.layout.*;
import org.apache.fop.image.*;
@@ -77,12 +77,6 @@ import org.w3c.dom.svg.*;
import org.w3c.dom.css.*;
import org.w3c.dom.svg.SVGLength;
-import org.apache.fop.dom.svg.*;
-import org.apache.fop.dom.svg.SVGRectElementImpl;
-import org.apache.fop.dom.svg.SVGTextElementImpl;
-import org.apache.fop.dom.svg.SVGLineElementImpl;
-import org.apache.fop.dom.svg.SVGArea;
-
// Java
import java.io.IOException;
import java.io.OutputStream;
diff --git a/src/org/apache/fop/render/pcl/PCLRenderer.java b/src/org/apache/fop/render/pcl/PCLRenderer.java
index e38e12745..e3f3972db 100755
--- a/src/org/apache/fop/render/pcl/PCLRenderer.java
+++ b/src/org/apache/fop/render/pcl/PCLRenderer.java
@@ -21,7 +21,7 @@ import org.apache.fop.layout.*;
import org.apache.fop.layout.inline.*;
import org.apache.fop.image.*;
-import org.apache.fop.dom.svg.SVGArea;
+import org.apache.fop.svg.SVGArea;
import org.w3c.dom.svg.SVGSVGElement;
@@ -538,9 +538,6 @@ System.out.println("PCLRenderer.renderSVGArea(" + area + ")");
// TODO - translate and clip to viewbox
- PCLSVGRenderer svgRenderer =
- new PCLSVGRenderer(this, area.getFontState(), currentFontName, currentFontSize, currentXPosition, currentYPosition, pageHeight, xoffset);
- svgRenderer.renderSVG(svg, x, y);
//currentStream.add(svgRenderer.getString());
//currentStream.add("Q\n");
diff --git a/src/org/apache/fop/render/pcl/PCLSVGRenderer.java b/src/org/apache/fop/render/pcl/PCLSVGRenderer.java
deleted file mode 100755
index 5543faa58..000000000
--- a/src/org/apache/fop/render/pcl/PCLSVGRenderer.java
+++ /dev/null
@@ -1,1400 +0,0 @@
-/* $Id$
- * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
- * For details on use and redistribution please refer to the
- * LICENSE file included with these sources."
- */
-
-//package com.eastpoint.chrysalis;
-package org.apache.fop.render.pcl;
-
-// FOP
-import org.apache.fop.messaging.MessageHandler;
-import org.apache.fop.fo.properties.*;
-import org.apache.fop.svg.PathPoint;
-import org.apache.fop.pdf.PDFColor;
-import org.apache.fop.layout.*;
-import org.apache.fop.image.*;
-
-import org.w3c.dom.*;
-import org.w3c.dom.svg.*;
-import org.w3c.dom.css.*;
-
-import org.apache.fop.dom.svg.*;
-
-// Java
-import java.util.Enumeration;
-import java.util.Vector;
-
-/**
- * Renderer that renders SVG to PCL
- */
-public class PCLSVGRenderer
-{
- FontState fontState;
-
- /** the current stream to add PCL commands to */
- PCLStream currentStream;
-
- /** the current (internal) font name */
- protected String currentFontName;
-
- /** the current font size in millipoints */
- protected int currentFontSize;
-
- /** the current vertical position in millipoints from bottom */
- protected int currentYPosition = 0;
-
- /** the current horizontal position in millipoints from left */
- protected int currentXPosition = 0;
-
- /** the current colour for use in svg */
- private PDFColor currentColour = new PDFColor(0, 0, 0);
-
- private PCLRenderer renderer;
-
- final boolean debug = false;
-
- private int pageHeight;
- private int rendxoffset;
-
- /**
- * create the SVG renderer
- */
- public PCLSVGRenderer(PCLRenderer rend, FontState fs, String font, int size, int xpos, int ypos, int ph, int xo)
- {
- renderer = rend;
- currentFontName = font;
- currentFontSize = size;
- currentYPosition = ypos;
- currentXPosition = xpos;
- fontState = fs;
-
- currentStream = rend.currentStream;
-
- pageHeight = ph;
- rendxoffset = xo;
- }
-
- /**
- * Renders an SVG element in an SVG document.
- * This renders each of the child elements.
- */
- protected void renderSVG(SVGSVGElement svg, int x, int y) {
- NodeList nl = svg.getChildNodes();
- for (int count = 0; count < nl.getLength(); count++) {
- Node n = nl.item(count);
- if (n instanceof SVGElement) {
- renderElement((SVGElement) n, x, y);
- }
- }
- }
-
- public void renderGArea(SVGGElement area, int posx, int posy) {
- NodeList nl = area.getChildNodes();
- for (int count = 0; count < nl.getLength(); count++) {
- Node n = nl.item(count);
- if (n instanceof SVGElement) {
- renderElement((SVGElement) n, posx, posy);
- }
- }
- }
-
- /**
- * Handles the SVG switch element.
- * The switch determines which of its child elements should be rendered
- * according to the required extensions, required features and system language.
- */
- protected void handleSwitchElement(int posx, int posy,
- SVGSwitchElement ael) {
- SVGStringList relist = ael.getRequiredExtensions();
- SVGStringList rflist = ael.getRequiredFeatures();
- SVGStringList sllist = ael.getSystemLanguage();
- NodeList nl = ael.getChildNodes();
- choices:
- for (int count = 0; count < nl.getLength(); count++) {
- org.w3c.dom.Node n = nl.item(count);
- // only render the first child that has a valid
- // test data
- if (n instanceof GraphicElement) {
- GraphicElement graphic = (GraphicElement) n;
- SVGStringList grelist = graphic.getRequiredExtensions();
- // if null it evaluates to true
- if (grelist != null) {
- if (grelist.getNumberOfItems() == 0) {
- if ((relist != null) &&
- relist.getNumberOfItems() != 0) {
- continue choices;
- }
- }
- for (int i = 0; i < grelist.getNumberOfItems(); i++) {
- String str = (String) grelist.getItem(i);
- if (relist == null) {
- // use default extension set
- // currently no extensions are supported
- // if(!(str.equals("http:// ??"))) {
- continue choices;
- // }
- } else {
- }
- }
- }
- SVGStringList grflist = graphic.getRequiredFeatures();
- if (grflist != null) {
- if (grflist.getNumberOfItems() == 0) {
- if ((rflist != null) &&
- rflist.getNumberOfItems() != 0) {
- continue choices;
- }
- }
- for (int i = 0; i < grflist.getNumberOfItems(); i++) {
- String str = (String) grflist.getItem(i);
- if (rflist == null) {
- // use default feature set
- if (!(str.equals("org.w3c.svg.static") ||
- str.equals("org.w3c.dom.svg.all"))) {
- continue choices;
- }
- } else {
- boolean found = false;
- for (int j = 0;
- j < rflist.getNumberOfItems(); j++) {
- if (rflist.getItem(j).equals(str)) {
- found = true;
- break;
- }
- }
- if (!found)
- continue choices;
- }
- }
- }
- SVGStringList gsllist = graphic.getSystemLanguage();
- if (gsllist != null) {
- if (gsllist.getNumberOfItems() == 0) {
- if ((sllist != null) &&
- sllist.getNumberOfItems() != 0) {
- continue choices;
- }
- }
- for (int i = 0; i < gsllist.getNumberOfItems(); i++) {
- String str = (String) gsllist.getItem(i);
- if (sllist == null) {
- // use default feature set
- if (!(str.equals("en"))) {
- continue choices;
- }
- } else {
- boolean found = false;
- for (int j = 0;
- j < sllist.getNumberOfItems(); j++) {
- if (sllist.getItem(j).equals(str)) {
- found = true;
- break;
- }
- }
- if (!found)
- continue choices;
- }
- }
- }
- renderElement((SVGElement) n, posx, posy);
- // only render the first valid one
- break;
- }
- }
- }
-
- protected void addLine(float x1, float y1, float x2, float y2, PDFColor sc, float sw)
- {
-if ( debug )
-System.out.println("PCLSVGRenderer.addLine(" + x1 + ", " + y1 + ", " + x2 + ", " + y2 + ", " + sc + ", " + sw + ")");
- if ( x1 == x2 )
- {
- addRect(x1 - sw/2, y1, sw, y2 - y1 + 1, 0, 0, sc, null, 0);
- }
- else if ( y1 == y2 || (Math.abs(y1 - y2) <= 0.24) ) // 72/300=0.24
- {
- addRect(x1, y1 - sw/2, x2 - x1 + 1, sw, 0, 0, sc, null, 0);
- }
- else if ( sc != null )
- {
- // Do something for these?
-
- // Convert dimensions to pixels.
- float cfact = 300f / 72f; // 300 dpi, 1pt=1/72in
- int ix1 = (int)(x1 * cfact);
- int iy1 = (int)(y1 * cfact);
- int ix2 = (int)(x2 * cfact);
- int iy2 = (int)(y2 * cfact);
- int isw = (int)(sw * cfact);
- int origix;
-
- // Normalize
- if ( iy1 > iy2 )
- {
- int tmp = ix1;
- ix1 = ix2;
- ix2 = tmp;
- tmp = iy1;
- iy1 = iy2;
- iy2 = tmp;
- }
- if ( ix1 > ix2 )
- {
- origix = ix2;
- ix1 -=ix2;
- ix2 = 0;
- }
- else
- {
- origix = ix1;
- ix2 -= ix1;
- ix1 = 0;
- }
-
- // Convert line width to a pixel run length.
-//System.out.println("PCLRenderer.addLine(" + ix1 + ", " + iy1 + ", " + ix2 + ", " + iy2 + ", " + isw + ")");
- int runlen = (int)Math.sqrt(Math.pow(isw, 2) * (1 + Math.pow((ix1 - ix2) / (iy1 - iy2), 2)));
-//System.out.println("PCLRenderer.addLine: runlen = " + runlen);
-
- // Set Transparency modes and select shading.
- currentStream.add("\033*v0n1O\033*c" + (int)(100 - ((0.3f * sc.red() + 0.59f * sc.green() + 0.11f * sc.blue()) * 100f)) + "G\033*v2T");
-
- // Draw the line.
- int d, dx, dy;
- int Aincr, Bincr;
- int xincr = 1;
- int x, y;
-
-
- dx = Math.abs(ix2 - ix1);
- dy = iy2 - iy1;
-
- if ( origix < 0 )
- MessageHandler.errorln("PCLSVGRenderer.addLine() WARNING: Horizontal position out of bounds.");
-
- if ( dx > dy )
- {
- xincr = dx / dy;
-
- // Move to starting position.
- currentStream.add("\033*p" + origix + "x" + iy1 + "Y");
- x = ix1 - runlen / 2;
- iy2 += (isw / 2);
- // Start raster graphics
- currentStream.add("\033*t300R\033*r" + dx + "s1A\033*b1M");
- }
- else
- {
- // Move to starting position.
- currentStream.add("\033*p" + (origix - runlen / 2) + "x" + iy1 + "Y");
- x = ix1;
- // Start raster graphics
- currentStream.add("\033*t300R\033*r1A\033*b1M");
- }
-
- if ( ix1 > ix2 )
- xincr *= -1;
- d = 2 * dx - dy;
- Aincr = 2 * (dx - dy);
- Bincr = 2 * dx;
-
- y = iy1;
-
- xferLineBytes(x, runlen, null, -1);
-
- for ( y = iy1 + 1 ; y <= iy2 ; y++ )
- {
- if ( d >= 0 )
- {
- x += xincr;
- d += Aincr;
- }
- else
- d += Bincr;
- xferLineBytes(x, runlen, null, -1);
- }
-
- // End raster graphics
- currentStream.add("\033*rB");
- // Return to regular print mode.
- currentStream.add("\033*v0t0n0O");
- }
- }
-
- private void xferLineBytes(int startpos, int bitcount, Vector save, int start2)
- {
-//System.out.println("PCLRenderer.xferLineBytes(" + startpos + ", " + bitcount + ")");
- int curbitpos = 0;
- if ( start2 > 0 && start2 <= (startpos + bitcount) )
- {
- bitcount += (start2 - startpos);
- start2 = 0;
- }
-
- char bytes[] = new char[((start2>startpos?start2:startpos) + bitcount) / 4 + 2];
- int dlen = 0;
- byte dbyte = 0;
- int bytepos = 0;
-
- do
- {
- int bits2set;
- if ( startpos < 0 )
- {
- bits2set = bitcount + startpos;
- startpos = 0;
- }
- else
- bits2set = bitcount;
-
- byte bittype = 0;
- do
- {
- if ( bytepos > 0 )
- {
- int inc = startpos - curbitpos;
- if ( (inc) >= (8 - bytepos) )
- {
- curbitpos += (8 - bytepos);
- bytepos = 0;
- bytes[dlen++] = (char)0;
- bytes[dlen++] = (char)dbyte;
- dbyte = 0;
- }
- else
- {
- bytepos += inc;
- dbyte = (byte)(dbyte ^ (byte)(Math.pow(2, 8 - bytepos) - 1));
- curbitpos += inc;
- }
- }
-
- // Set runs of whole bytes.
- int setbytes = (startpos - curbitpos) / 8;
- if ( setbytes > 0 )
- {
- curbitpos += setbytes * 8;
- while ( setbytes > 0 )
- {
- if ( setbytes > 256 )
- {
- bytes[dlen++] = 0xFF;
- setbytes -= 256;
- }
- else
- {
- bytes[dlen++] = (char)((setbytes - 1) & 0xFF);
- setbytes = 0;
- }
- bytes[dlen++] = (char)bittype;
- }
- }
- // move to position in the first byte.
- if ( curbitpos < startpos )
- {
- if ( bytepos == 0 )
- dbyte = bittype;
- bytepos += startpos - curbitpos;
- dbyte = (byte)(dbyte ^ (byte)(Math.pow(2, 8 - bytepos) - 1));
- curbitpos += bytepos;
- startpos += bits2set;
- }
- else
- {
- startpos += bits2set;
- }
-
- if ( bittype == 0 )
- bittype = (byte)0xFF;
- else
- bittype = 7;
- } while ( bittype != 7 );
-
- if ( start2 > 0 )
- {
- startpos = start2;
- start2 = -1;
- }
- else
- startpos = -1;
- } while ( startpos >= 0 );
- if ( bytepos > 0 )
- {
- bytes[dlen++] = (char)0;
- bytes[dlen++] = (char)dbyte;
- }
- if ( save == null )
- {
- currentStream.add("\033*b" + dlen + "W");
- currentStream.add(new String(bytes, 0, dlen));
- }
- else
- {
- String line = "\033*b" + dlen + "W" + new String(bytes, 0, dlen);
- currentStream.add(line);
- save.addElement(line);
- }
- }
-
- /**
- * add a filled rectangle to the current stream
- *
- * @param x the x position of left edge in millipoints
- * @param y the y position of top edge in millipoints
- * @param w the width in millipoints
- * @param h the height in millipoints
- * @param r the red component of edges
- * @param g the green component of edges
- * @param b the blue component of edges
- * @param fr the red component of the fill
- * @param fg the green component of the fill
- * @param fb the blue component of the fill
- */
- protected void addRect(float x, float y, float w, float h, float rx, float ry,
- PDFColor fc, PDFColor sc, float sw)
- {
-if ( debug )
-System.out.println("PCLSVGRenderer.addRect(" + x + ", " + y + ", " + w + ", " + h + ", " + rx + ", " + ry + ", " + fc + ", " + sc + ", " + sw + ")");
-
- if ( x < 0 || y < 0 )
- MessageHandler.errorln("PCLSVGRenderer.addRect() WARNING: Position out of bounds.");
-
- if ( rx == 0 || ry == 0 )
- {
- if ( fc != null )
- {
- int fillshade = (int)(100 - ((0.3f * fc.red() + 0.59f * fc.green() + 0.11f * fc.blue()) * 100f));
- currentStream.add("\033*v0n1O\033&a" + (x * 10) + "h" + ((y * 10)) + "V"
- + "\033*c" + (w * 10) + "h" + (h * 10) + "v" + fillshade + "g2P\033*v0n0O");
- }
- if ( sc != null && sw > 0 )
- {
- String lend = "v" + String.valueOf((int)(100 - ((0.3f * sc.red() + 0.59f * sc.green() + 0.11f * sc.blue()) * 100f))) + "g2P";
- currentStream.add("\033*v0n1O");
- currentStream.add("\033&a" + ((x - sw/2) * 10) + "h" + (((y - sw/2)) * 10) + "V"
- + "\033*c" + ((w + sw) * 10) + "h" + ((sw) * 10) + lend);
- currentStream.add("\033&a" + ((x - sw/2) * 10) + "h" + (((y - sw/2)) * 10) + "V"
- + "\033*c" + ((sw) * 10) + "h" + ((h + sw) * 10) + lend);
- currentStream.add("\033&a" + ((x + w - sw/2) * 10) + "h" + (((y - sw/2)) * 10) + "V"
- + "\033*c" + ((sw) * 10) + "h" + ((h + sw) * 10) + lend);
- currentStream.add("\033&a" + ((x - sw/2) * 10) + "h" + (((y + h - sw/2)) * 10) + "V"
- + "\033*c" + ((w + sw) * 10) + "h" + ((sw) * 10) + lend);
- currentStream.add("\033*v0n0O");
- }
- }
- else
- {
- // Convert dimensions to pixels.
- float cfact = 300f / 72f; // 300 dpi, 1pt=1/72in
- int ix = (int)(x * cfact);
- int iy = (int)(y * cfact);
- int iw = (int)(w * cfact);
- int ih = (int)(h * cfact);
- int irx = (int)(rx * cfact);
- int iry = (int)(ry * cfact);
- int isw = (int)(sw * cfact);
- int longwidth = 0;
- int pass = 0;
- PDFColor thecolor = null;
-
- do
- {
- if ( pass == 0 && fc != null )
- {
- thecolor = fc;
- }
- else if ( pass == 1 && sc != null )
- {
- int iswdiv2 = isw / 2;
- thecolor = sc;
- ix -= iswdiv2;
- iy -= iswdiv2;
- irx += iswdiv2;
- iry += iswdiv2;
- iw += isw;
- ih += isw;
- longwidth = (int)(isw * 1.414);
- }
- else
- thecolor = null;
-
-
- if ( thecolor != null )
- {
- int tx = 0;
- int ty = iry;
- long a = irx;
- long b = iry;
- long Asquared = (long)Math.pow(a, 2);
- long TwoAsquared = 2 * Asquared;
- long Bsquared = (long)Math.pow(b, 2);
- long TwoBsquared = 2 * Bsquared;
- long d = Bsquared - Asquared * b + Asquared / 4;
- long dx = 0;
- long dy = TwoAsquared * b;
- int rectlen = iw - 2 * irx;
- Vector bottomlines = new Vector();
-
- int x0 = tx;
-
- // Set Transparency modes and select shading.
- currentStream.add("\033*v0n1O\033*c" + (int)(100 - ((0.3f * thecolor.red() + 0.59f * thecolor.green() + 0.11f * thecolor.blue()) * 100f)) + "G\033*v2T");
- // Move to starting position.
- currentStream.add("\033*p" + ix + "x" + iy + "Y");
- // Start raster graphics
- currentStream.add("\033*t300R\033*r" + iw + "s1A\033*b1M");
-
- while ( dx < dy )
- {
- if ( d > 0 )
- {
- if ( pass == 0 || ty > (iry - isw) )
- xferLineBytes(irx - x0, rectlen + 2 * x0, bottomlines, -1);
- else
- xferLineBytes(irx - x0, longwidth, bottomlines, iw - irx + x0 - longwidth);
- x0 = tx + 1;
- ty--;
- dy -= TwoAsquared;
- d -= dy;
- }
- tx++;
- dx += TwoBsquared;
- d += Bsquared + dx;
- }
-
- d += (3 * (Asquared - Bsquared) / 2 - (dx + dy)) / 2;
-
- while ( ty > 0 )
- {
- if ( pass == 0 || ty >= (iry - isw) )
- xferLineBytes(irx - tx, rectlen + 2 * tx, bottomlines, -1);
- else
- xferLineBytes(irx - tx, isw, bottomlines, iw - irx + tx - isw);
-
- if ( d < 0 )
- {
- tx++;
- dx += TwoBsquared;
- d += dx;
- }
- ty--;
- dy -= TwoAsquared;
- d += Asquared - dy;
- }
-
- // Draw the middle part of the rectangle
- int midlen = ih - 2 * iry;
- if ( midlen > 0 )
- {
- if ( pass == 0 )
- xferLineBytes(0, iw, null, -1);
- else
- xferLineBytes(0, isw, null, iw - isw);
- currentStream.add("\033*b3M");
- for ( int countr = midlen - 1 ; countr > 0 ; countr-- )
- currentStream.add("\033*b0W");
- currentStream.add("\033*b1M");
- }
-
- // Draw the bottom.
- for ( int countr = bottomlines.size() - 1 ; countr >= 0 ; countr-- )
- currentStream.add((String)bottomlines.elementAt(countr));
-
- // End raster graphics
- currentStream.add("\033*rB");
- // Return to regular print mode.
- currentStream.add("\033*v0t0n0O");
- }
- pass++;
- } while ( pass < 2 );
- }
- }
-
- // Add a polyline or polygon. Does not support fills yet!!!
- protected void addPolyline(Vector points, int posx, int posy, PDFColor fc, PDFColor sc, float sw, boolean close)
- {
- PathPoint pc;
- float lastx = 0;
- float lasty = 0;
- float curx = 0;
- float cury = 0;
- float startx = 0;
- float starty = 0;
- Enumeration e = points.elements();
- if(e.hasMoreElements())
- {
- pc = (PathPoint)e.nextElement();
- lastx = rendxoffset / 10 + pc.x + posx / 1000;
- lasty = ((pageHeight / 10) - posy/1000) + pc.y;
- startx = lastx;
- starty = lasty;
- //currentStream.add(lastx + " " + lasty + " m\n");
- }
- while(e.hasMoreElements())
- {
- pc = (PathPoint)e.nextElement();
- curx = rendxoffset / 10 + pc.x + posx / 1000;
- cury = ((pageHeight / 10) - posy/1000) + pc.y;
- addLine(lastx, lasty, curx, cury, sc, sw);
- lastx = curx;
- lasty = cury;
- //currentStream.add(lastx + " " + lasty + " l\n");
- }
- if(close)
- {
- addLine(lastx, lasty, startx, starty, sc, sw);
- //currentStream.add("h\n");
- }
- //doDrawing(di);
- }
-
- public void renderImage(String href, float x, float y, float width, float height)
- {
- if ( x < 0 || y < 0 )
- MessageHandler.errorln("PCLSVGRenderer.renderImage() WARNING: Position out of bounds.");
-
- try
- {
- if ( href.indexOf(":") == -1 )
- href = "file:" + href;
- FopImage img = FopImageFactory.Make(href);
- if(img != null)
- {
- if ( img instanceof SVGImage )
- {
- SVGSVGElement svg = ((SVGImage)img).getSVGDocument().getRootElement();
- renderSVG(svg, (int)x * 1000, (int)y * 1000);
- }
- else
- {
- currentStream.add("\033&a" + (x * 10) + "h" + (y * 10) + "V");
- renderer.printBMP(img, (int)x, (int)y, (int)width, (int)height);
- }
-
- }
- }
- catch(Exception e)
- {
- MessageHandler.errorln("could not add image to SVG: " + href);
- }
- }
-
- /**
- * A symbol has a viewbox and preserve aspect ratio.
- */
- protected void renderSymbol(SVGSymbolElement symbol, int x, int y) {
- NodeList nl = symbol.getChildNodes();
- for (int count = 0; count < nl.getLength(); count++) {
- Node n = nl.item(count);
- if (n instanceof SVGElement) {
- renderElement((SVGElement) n, x, y);
- }
- }
- }
-
- /**
- * Main rendering selection.
- * This applies any transform ans style and then calls the appropriate
- * rendering method depending on the type of the element.
- */
- public void renderElement(SVGElement area, int posx, int posy)
- {
-if ( debug )
-System.out.println("PCLRenderer.renderElement(" + fontState + ", " + area + ", " + posx + ", " + posy + ")");
- int x = posx;
- int y = posy;
- SVGStylable style = null;
- if ( area instanceof SVGStylable )
- style = (SVGStylable)area;
- PDFColor fillColour = null;
- PDFColor strokeColour = null;
- float strokeWidth = 1;
-
- //currentStream.add("q\n");
- //if( area instanceof SVGTransformable )
- //{
- // SVGTransformable tf = (SVGTransformable)area;
- // SVGAnimatedTransformList trans = tf.getTransform();
- // SVGRect bbox = tf.getBBox();
- // if(trans != null) {
- // applyTransform(trans, bbox);
- // }
- //}
-
- if(style != null)
- {
- CSSValue sp;
- sp = style.getPresentationAttribute("fill");
- if (sp != null)
- {
- if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE)
- {
- if (((CSSPrimitiveValue) sp).getPrimitiveType() == CSSPrimitiveValue.CSS_RGBCOLOR)
- {
- RGBColor col = ((CSSPrimitiveValue) sp).getRGBColorValue();
- CSSPrimitiveValue val;
- val = col.getRed();
- float red = val.getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
- val = col.getGreen();
- float green = val.getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
- val = col.getBlue();
- float blue = val.getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
- fillColour = new PDFColor(red, green, blue);
- currentColour = fillColour;
- }
- else if ( ((CSSPrimitiveValue) sp).getPrimitiveType() == CSSPrimitiveValue.CSS_STRING)
- {
- String str = ((CSSPrimitiveValue) sp).getCssText();
- if ( str.equals("none") )
- {
- fillColour = null;
- }
- else if ( str.equals("currentColor") )
- {
- fillColour = currentColour;
- }
- }
- }
- }
- else
- {
- fillColour = new PDFColor(0, 0, 0);
- }
- sp = style.getPresentationAttribute("stroke");
- if ( sp != null )
- {
- if ( sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE )
- {
- if ( ((CSSPrimitiveValue) sp).getPrimitiveType() == CSSPrimitiveValue.CSS_RGBCOLOR )
- {
- RGBColor col = ((CSSPrimitiveValue) sp).getRGBColorValue();
- CSSPrimitiveValue val;
- val = col.getRed();
- float red = val.getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
- val = col.getGreen();
- float green = val.getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
- val = col.getBlue();
- float blue = val.getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
- strokeColour = new PDFColor(red, green, blue);
- }
- else if ( ((CSSPrimitiveValue) sp).getPrimitiveType() == CSSPrimitiveValue.CSS_STRING )
- {
- String str = ((CSSPrimitiveValue) sp).getCssText();
- if (str.equals("none"))
- {
- strokeColour = null;
- }
- }
- }
- }
- else
- {
- strokeColour = new PDFColor(0, 0, 0);
- }
- sp = style.getPresentationAttribute("stroke-width");
- if ( sp != null )
- {
- if ( sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE )
- {
- strokeWidth = ((CSSPrimitiveValue) sp).getFloatValue(CSSPrimitiveValue.CSS_PT);
- }
- }
- }
-
- if (area instanceof SVGRectElement)
- {
- SVGRectElement rg = (SVGRectElement)area;
- float rectx = rendxoffset / 10 + rg.getX().getBaseVal().getValue() + posx / 1000;
- float recty = ((pageHeight / 10) - posy/1000) + rg.getY().getBaseVal().getValue();
- float rx = rg.getRx().getBaseVal().getValue();
- float ry = rg.getRy().getBaseVal().getValue();
- float rw = rg.getWidth().getBaseVal().getValue();
- float rh = rg.getHeight().getBaseVal().getValue();
- addRect(rectx, recty, rw, rh, rx, ry, fillColour, strokeColour, strokeWidth);
- }
- else if (area instanceof SVGLineElement)
- {
- SVGLineElement lg = (SVGLineElement)area;
- float x1 = rendxoffset / 10 + lg.getX1().getBaseVal().getValue() + posx / 1000;
- float y1 = ((pageHeight / 10) - posy/1000) + lg.getY1().getBaseVal().getValue();
- float x2 = rendxoffset / 10 + lg.getX2().getBaseVal().getValue() + posx / 1000;
- float y2 = ((pageHeight / 10) - posy/1000) + lg.getY2().getBaseVal().getValue();
- addLine(x1,y1,x2,y2, strokeColour, strokeWidth);
- }
- else if (area instanceof SVGTextElementImpl)
- {
- //currentStream.add("BT\n");
- //renderText((SVGTextElementImpl)area, rendxoffset + posx / 1000f, ((float)(pageHeight / 10) - posy/1000f));
- //currentStream.add("ET\n");
- SVGTextRenderer str = new SVGTextRenderer(fontState, (SVGTextElementImpl)area, rendxoffset / 10 + posx / 1000f, ((float)(pageHeight / 10) - posy/1000f));
- str.renderText((SVGTextElementImpl)area);
- }
- else if (area instanceof SVGCircleElement)
- {
- SVGCircleElement cg = (SVGCircleElement)area;
- float cx = rendxoffset / 10 + cg.getCx().getBaseVal().getValue() + posx / 1000;
- float cy = ((pageHeight / 10) - posy/1000) + cg.getCy().getBaseVal().getValue();
- float r = cg.getR().getBaseVal().getValue();
- //addCircle(cx,cy,r, di);
- addRect(cx - r, cy - r, 2 * r, 2 * r, r, r, fillColour, strokeColour, strokeWidth);
- }
- else if (area instanceof SVGEllipseElement)
- {
- SVGEllipseElement cg = (SVGEllipseElement)area;
- float cx = rendxoffset / 10 + cg.getCx().getBaseVal().getValue() + posx / 1000;
- float cy = ((pageHeight / 10) - posy/1000) + cg.getCy().getBaseVal().getValue();
- float rx = cg.getRx().getBaseVal().getValue();
- float ry = cg.getRy().getBaseVal().getValue();
- //addEllipse(cx,cy,rx,ry, di);
- addRect(cx - rx, cy - ry, 2 * rx, 2 * ry, rx, ry, fillColour, strokeColour, strokeWidth);
- }
- else if (area instanceof SVGPathElementImpl)
- {
- //addPath(((SVGPathElementImpl)area).pathElements, posx, posy, di);
- }
- else if (area instanceof SVGPolylineElementImpl)
- {
- addPolyline(((SVGPolylineElementImpl)area).points, posx, posy, fillColour, strokeColour, strokeWidth, false);
- }
- else if (area instanceof SVGPolygonElementImpl)
- {
- addPolyline(((SVGPolylineElementImpl)area).points, posx, posy, fillColour, strokeColour, strokeWidth, true);
- }
- else if (area instanceof SVGGElementImpl)
- {
- renderGArea((SVGGElementImpl)area, x, y);
- }
- else if(area instanceof SVGUseElementImpl)
- {
- SVGUseElementImpl ug = (SVGUseElementImpl) area;
- String ref = ug.link;
- // ref = ref.substring(1, ref.length());
- SVGElement graph = null;
- graph = locateDef(ref, ug);
- if (graph != null) {
- // probably not the best way to do this, should be able
- // to render without the style being set.
- // SVGElement parent = graph.getGraphicParent();
- // graph.setParent(area);
- // need to clip (if necessary) to the use area
- // the style of the linked element is as if it was
- // a direct descendant of the use element.
-
- // scale to the viewBox
-
- if (graph instanceof SVGSymbolElement) {
- //currentStream.write("q\n");
- SVGSymbolElement symbol = (SVGSymbolElement) graph;
- SVGRect view = symbol.getViewBox().getBaseVal();
- float usex = ug.getX().getBaseVal().getValue();
- float usey = ug.getY().getBaseVal().getValue();
- float usewidth = ug.getWidth().getBaseVal().getValue();
- float useheight =
- ug.getHeight().getBaseVal().getValue();
- float scaleX;
- float scaleY;
- scaleX = usewidth / view.getWidth();
- scaleY = useheight / view.getHeight();
- //currentStream.write(usex + " " + usey + " m\n");
- //currentStream.write((usex + usewidth) + " " +
- // usey + " l\n");
- //currentStream.write((usex + usewidth) + " " +
- // (usey + useheight) + " l\n");
- //currentStream.write(usex + " " +
- // (usey + useheight) + " l\n");
- //currentStream.write("h\n");
- //currentStream.write("W\n");
- //currentStream.write("n\n");
- //currentStream.write(scaleX + " 0 0 " + scaleY +
- // " " + usex + " " + usey + " cm\n");
- renderSymbol(symbol, posx, posy);
- //currentStream.write("Q\n");
- } else {
- renderElement(graph, posx, posy);
- }
- // graph.setParent(parent);
- }
- else
- {
- MessageHandler.logln("Use Element: " + ref + " not found");
- }
- }
- else if (area instanceof SVGImageElementImpl)
- {
- SVGImageElementImpl ig = (SVGImageElementImpl)area;
- renderImage(ig.link, ig.x, ig.y, ig.width, ig.height);
- }
- else if (area instanceof SVGSVGElement)
- {
- //currentStream.write("q\n");
- SVGSVGElement svgel = (SVGSVGElement) area;
- float svgx = 0;
- if (svgel.getX() != null)
- svgx = svgel.getX().getBaseVal().getValue();
- float svgy = 0;
- if (svgel.getY() != null)
- svgy = svgel.getY().getBaseVal().getValue();
- //currentStream.write(1 + " 0 0 " + 1 + " " + svgx + " " +
- // svgy + " cm\n");
- renderSVG(svgel, (int)(x + 1000 * svgx),
- (int)(y + 1000 * svgy));
- //currentStream.write("Q\n");
- // } else if (area instanceof SVGSymbolElement) {
- // 'symbol' element is not rendered (except by 'use')
- }
- else if (area instanceof SVGAElement)
- {
- SVGAElement ael = (SVGAElement)area;
- org.w3c.dom.NodeList nl = ael.getChildNodes();
- for ( int count = 0 ; count < nl.getLength() ; count++ )
- {
- org.w3c.dom.Node n = nl.item(count);
- if ( n instanceof SVGElement )
- {
- if ( n instanceof GraphicElement )
- {
- SVGRect rect = ((GraphicElement)n).getBBox();
- if ( rect != null )
- {
-/* currentAnnotList = this.pdfDoc.makeAnnotList();
- currentPage.setAnnotList(currentAnnotList);
- String dest = linkSet.getDest();
- int linkType = linkSet.getLinkType();
- currentAnnotList.addLink(
- this.pdfDoc.makeLink(lrect.getRectangle(), dest, linkType));
- currentAnnotList = null;
-*/ }
- }
- renderElement((SVGElement)n, posx, posy);
- }
- }
- }
- else if ( area instanceof SVGSwitchElement )
- {
- handleSwitchElement(posx, posy, (SVGSwitchElement)area);
- }
- // should be done with some cleanup code, so only
- // required values are reset.
- //currentStream.add("Q\n");
- }
-
- /**
- * Adds an svg string to the output.
- * This handles the escaping of special pdf chars and deals with
- * whitespace.
- */
- protected float addSVGStr(FontState fs, float currentX, String str,
- boolean spacing) {
- boolean inbetween = false;
- boolean addedspace = false;
- StringBuffer pdf = new StringBuffer();
- for (int i = 0; i < str.length(); i++) {
- char ch = str.charAt(i);
- switch (ch)
- {
- case '\t':
- case ' ':
- if (spacing) {
- pdf = pdf.append(' ');
- currentX += fs.width(' ') / 1000f;
- } else {
- if (inbetween && !addedspace) {
- addedspace = true;
- pdf = pdf.append(' ');
- currentX += fs.width(' ') / 1000f;
- }
- }
- break;
- case '\n':
- case '\r':
- if (spacing) {
- pdf = pdf.append(' ');
- currentX += fs.width(' ') / 1000f;
- }
- break;
- default:
- addedspace = false;
- pdf = pdf.append(ch);
- currentX += fs.width(ch) / 1000f;
- inbetween = true;
- break;
- }
- }
- currentStream.add(pdf.toString());
- return currentX;
- }
-
- /**
- * Locates a defined element in an svg document.
- * Either gets the element defined by its "id" in the current
- * SVGDocument, or if the uri reference is to an external
- * document it loads the document and returns the element.
- */
- protected SVGElement locateDef(String ref, SVGElement currentElement) {
- int pos;
- ref = ref.trim();
- pos = ref.indexOf("#");
- if (pos == 0) {
- // local doc
- Document doc = currentElement.getOwnerDocument();
- Element ele =
- doc.getElementById(ref.substring(1, ref.length()));
- if (ele instanceof SVGElement) {
- return (SVGElement) ele;
- }
- } else if (pos != -1) {
- String href = ref.substring(0, pos);
- if (href.indexOf(":") == -1) {
- href = "file:" + href;
- }
- try {
- // this is really only to get a cached svg image
- FopImage img = FopImageFactory.Make(href);
- if (img instanceof SVGImage) {
- SVGDocument doc = ((SVGImage) img).getSVGDocument();
- Element ele = doc.getElementById(
- ref.substring(pos + 1, ref.length()));
- if (ele instanceof SVGElement) {
- return (SVGElement) ele;
- }
- }
- } catch (Exception e) {
- MessageHandler.errorln(e.toString());
- }
- }
- return null;
- }
-
- /**
- * This class is used to handle the rendering of svg text.
- * This is so that it can deal with the recursive rendering
- * of text markup, while keeping track of the state and position.
- */
- class SVGTextRenderer {
- FontState fs;
- String transstr;
- float currentX;
- float currentY;
- float baseX;
- float baseY;
- SVGMatrix matrix;
- float x;
- float y;
-
- SVGTextRenderer(FontState fontState, SVGTextElementImpl tg,
- float x, float y) {
- fs = fontState;
-
- //PDFNumber pdfNumber = new PDFNumber();
- SVGTransformList trans = tg.getTransform().getBaseVal();
- matrix = trans.consolidate().getMatrix();
- //transstr = (pdfNumber.doubleOut(matrix.getA()) + " " +
- // pdfNumber.doubleOut(matrix.getB()) + " " +
- // pdfNumber.doubleOut(matrix.getC()) + " " +
- // pdfNumber.doubleOut(-matrix.getD()) + " ");
- this.x = x;
- this.y = y;
- }
-
- void renderText(SVGTextElementImpl te) {
- float xoffset = 0;
-
- if (te.anchor.getEnum() != TextAnchor.START) {
- // This is a bit of a hack: The code below will update
- // the current position, so all I have to do is to
- // prevent that the code will write anything to the
- // PCL stream...
- currentStream.setDoOutput(false);
-
- _renderText (te, 0f, true);
-
- float width = currentX - te.x;
- currentStream.setDoOutput(true);
-
- if (te.anchor.getEnum() == TextAnchor.END) {
- xoffset = -width;
- } else if (te.anchor.getEnum() == TextAnchor.MIDDLE) {
- xoffset = -width/2;
- }
- }
-
- _renderText (te, xoffset, false);
- }
-
- void _renderText(SVGTextElementImpl te, float xoffset, boolean getWidthOnly)
- {
- //DrawingInstruction di = applyStyle(te, te);
- //if (di.fill) {
- // if (di.stroke) {
- // currentStream.write("2 Tr\n");
- // } else {
- // currentStream.write("0 Tr\n");
- // }
- //} else if (di.stroke) {
- // currentStream.write("1 Tr\n");
- //}
- updateFont(te, fs);
-
- float tx = te.x;
- float ty = te.y;
- currentX = x + tx + xoffset;
- currentY = y + ty;
- baseX = currentX;
- baseY = currentY;
- NodeList nodel = te.getChildNodes();
- // Vector list = te.textList;
- for (int count = 0; count < nodel.getLength(); count++) {
- Object o = nodel.item(count);
- //applyStyle(te, te);
- if ( o instanceof CharacterData )
- {
- String str = ((CharacterData) o).getData();
- //currentStream.write(transstr +
- // (currentX + matrix.getE()) + " " +
- // (baseY + matrix.getF()) + " Tm " + "(");
- boolean spacing = "preserve".equals(te.getXMLspace());
- //currentX = addSVGStr(fs, currentX, str, spacing);
- //currentStream.write(") Tj\n");
- currentStream.add("\033&a" + (currentX + matrix.getE())*10 + "h" + (baseY + matrix.getF())*10 + "V");
- currentX = addSVGStr(fs, currentX, str, spacing);
- }
- else if ( o instanceof SVGTextPathElementImpl )
- {
- SVGTextPathElementImpl tpg = (SVGTextPathElementImpl) o;
- String ref = tpg.str;
- SVGElement graph = null;
- graph = locateDef(ref, tpg);
- if (graph instanceof SVGPathElementImpl) {
- // probably not the best way to do this, should be able
- // to render without the style being set.
- // GraphicImpl parent = graph.getGraphicParent();
- // graph.setParent(tpg);
- // set text path??
- // how should this work
- // graph.setParent(parent);
- }
- } else if (o instanceof SVGTRefElementImpl) {
- SVGTRefElementImpl trg = (SVGTRefElementImpl) o;
- String ref = trg.ref;
- SVGElement element = locateDef(ref, trg);
- if (element instanceof SVGTextElementImpl) {
- // GraphicImpl parent = graph.getGraphicParent();
- // graph.setParent(trg);
- SVGTextElementImpl tele =
- (SVGTextElementImpl) element;
- // the style should be from tele, but it needs to be placed as a child
- // of trg to work
- //di = applyStyle(trg, trg);
- //if (di.fill) {
- // if (di.stroke) {
- // currentStream.write("2 Tr\n");
- // } else {
- // currentStream.write("0 Tr\n");
- // }
- //} else if (di.stroke) {
- // currentStream.write("1 Tr\n");
- //}
- boolean changed = false;
- FontState oldfs = fs;
- changed = updateFont(te, fs);
- NodeList nl = tele.getChildNodes();
- boolean spacing =
- "preserve".equals(trg.getXMLspace());
- renderTextNodes(spacing, nl,
- trg.getX().getBaseVal(),
- trg.getY().getBaseVal(),
- trg.getDx().getBaseVal(),
- trg.getDy().getBaseVal());
-
- if (changed) {
- fs = oldfs;
- //currentStream.write("/" +
- // fs.getFontName() + " " +
- // fs.getFontSize() / 1000f + " Tf\n");
- }
- // graph.setParent(parent);
- }
- } else if (o instanceof SVGTSpanElementImpl) {
- SVGTSpanElementImpl tsg = (SVGTSpanElementImpl) o;
- //applyStyle(tsg, tsg);
- boolean changed = false;
- FontState oldfs = fs;
- changed = updateFont(tsg, fs);
- boolean spacing = "preserve".equals(tsg.getXMLspace());
- renderTextNodes(spacing, tsg.getChildNodes(),
- tsg.getX().getBaseVal(),
- tsg.getY().getBaseVal(),
- tsg.getDx().getBaseVal(),
- tsg.getDy().getBaseVal());
-
- // currentX += fs.width(' ') / 1000f;
- if (changed) {
- fs = oldfs;
- //currentStream.write("/" + fs.getFontName() +
- // " " + fs.getFontSize() / 1000f + " Tf\n");
- }
- } else {
- MessageHandler.errorln("Error: unknown text element " + o);
- }
- }
- }
-
- void renderTextNodes(boolean spacing, NodeList nl,
- SVGLengthList xlist, SVGLengthList ylist,
- SVGLengthList dxlist, SVGLengthList dylist) {
- boolean inbetween = false;
- boolean addedspace = false;
- int charPos = 0;
- float xpos = currentX;
- float ypos = currentY;
-
- for (int count = 0; count < nl.getLength(); count++) {
- Node n = nl.item(count);
- if (n instanceof CharacterData) {
- //StringBuffer pdf = new StringBuffer();
- String str = ((CharacterData) n).getData();
- for (int i = 0; i < str.length(); i++) {
- char ch = str.charAt(i);
- xpos = currentX;
- ypos = currentY;
- if (ylist.getNumberOfItems() > charPos) {
- ypos = baseY + (ylist.getItem(charPos)).
- getValue();
- }
- if (dylist.getNumberOfItems() > charPos) {
- ypos = ypos + (dylist.getItem(charPos)).
- getValue();
- }
- if (xlist.getNumberOfItems() > charPos) {
- xpos = baseX + (xlist.getItem(charPos)).
- getValue();
- }
- if (dxlist.getNumberOfItems() > charPos) {
- xpos = xpos + (dxlist.getItem(charPos)).
- getValue();
- }
-
- switch (ch) {
- case '\t':
- case ' ':
- if (spacing) {
- currentX = xpos + fs.width(' ') /
- 1000f;
- currentY = ypos;
- charPos++;
- } else {
- if (inbetween && !addedspace) {
- addedspace = true;
- currentX = xpos + fs.width(' ')
- / 1000f;
- currentY = ypos;
- charPos++;
- }
- }
- break;
- case '\n':
- case '\r':
- if (spacing) {
- currentX = xpos + fs.width(' ') /
- 1000f;
- currentY = ypos;
- charPos++;
- }
- break;
- default:
- addedspace = false;
- //pdf = pdf.append(transstr +
- // (xpos + matrix.getE()) +
- // " " + (ypos +
- // matrix.getF()) + " Tm " +
- // "(" + ch + ") Tj\n");
- currentStream.add("\033&a" + (xpos + matrix.getE())*10 + "h" + (ypos + matrix.getF())*10 + "V" + ch);
- currentX = xpos + fs.width(ch) / 1000f;
- currentY = ypos;
- charPos++;
- inbetween = true;
- break;
- }
- //currentStream.write(pdf.toString());
- }
- }
- }
- }
-
- protected boolean updateFont(SVGStylable style, FontState fs) {
- boolean changed = false;
- String fontFamily = fs.getFontFamily();
- CSSValue sp = style.getPresentationAttribute("font-family");
- if (sp != null &&
- sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
- if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
- CSSPrimitiveValue.CSS_STRING) {
- fontFamily = sp.getCssText();
- }
- }
- if (!fontFamily.equals(fs.getFontFamily())) {
- changed = true;
- }
- String fontStyle = fs.getFontStyle();
- sp = style.getPresentationAttribute("font-style");
- if (sp != null &&
- sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
- if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
- CSSPrimitiveValue.CSS_STRING) {
- fontStyle = sp.getCssText();
- }
- }
- if (!fontStyle.equals(fs.getFontStyle())) {
- changed = true;
- }
- String fontWeight = fs.getFontWeight();
- sp = style.getPresentationAttribute("font-weight");
- if (sp != null &&
- sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
- if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
- CSSPrimitiveValue.CSS_STRING) {
- fontWeight = sp.getCssText();
- }
- }
- if (!fontWeight.equals(fs.getFontWeight())) {
- changed = true;
- }
- float newSize = fs.getFontSize() / 1000f;
- sp = style.getPresentationAttribute("font-size");
- if (sp != null &&
- sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
- // if(((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_NUMBER) {
- newSize = ((CSSPrimitiveValue) sp).getFloatValue(
- CSSPrimitiveValue.CSS_PT);
- // }
- }
- if (fs.getFontSize() / 1000f != newSize) {
- changed = true;
- }
- if (changed) {
- try {
- fs = new FontState(fs.getFontInfo(), fontFamily,
- fontStyle, fontWeight, (int)(newSize * 1000),
- FontVariant.NORMAL);
- } catch (Exception fope) {
- }
- this.fs = fs;
-
- //currentStream.write("/" + fs.getFontName() + " " +
- // newSize + " Tf\n");
- renderer.setFont(fs.getFontName(), newSize * 1000);
- } else {
- if (!currentFontName.equals(fs.getFontName()) ||
- currentFontSize != fs.getFontSize()) {
- // currentFontName = fs.getFontName();
- // currentFontSize = fs.getFontSize();
- //currentStream.write("/" + fs.getFontName() + " " +
- // (fs.getFontSize() / 1000) + " Tf\n");
- renderer.setFont(fs.getFontName(), fs.getFontSize());
- }
- }
- return changed;
- }
- }
-}
diff --git a/src/org/apache/fop/render/pdf/PDFRenderer.java b/src/org/apache/fop/render/pdf/PDFRenderer.java
index b524a7358..bd0d5761b 100644
--- a/src/org/apache/fop/render/pdf/PDFRenderer.java
+++ b/src/org/apache/fop/render/pdf/PDFRenderer.java
@@ -14,15 +14,26 @@ import org.apache.fop.image.FopImage;
import org.apache.fop.apps.FOPException;
import org.apache.fop.fo.properties.*;
import org.apache.fop.layout.inline.*;
+import org.apache.fop.datatypes.*;
+import org.apache.fop.svg.*;
import org.apache.fop.pdf.*;
import org.apache.fop.layout.*;
import org.apache.fop.image.*;
import org.apache.fop.extensions.*;
import org.apache.fop.datatypes.IDReferences;
-import org.w3c.dom.svg.*;
+import org.apache.batik.bridge.*;
+import org.apache.batik.swing.svg.*;
+import org.apache.batik.swing.gvt.*;
+import org.apache.batik.gvt.*;
+import org.apache.batik.gvt.renderer.*;
+import org.apache.batik.gvt.filter.*;
+import org.apache.batik.gvt.event.*;
-import org.apache.fop.dom.svg.*;
+import org.w3c.dom.*;
+import org.w3c.dom.svg.*;
+import org.w3c.dom.css.*;
+import org.w3c.dom.svg.SVGLength;
// Java
import java.io.IOException;
@@ -30,6 +41,12 @@ import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Vector;
import java.util.Hashtable;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Dimension2D;
+import java.awt.Point;
+import java.awt.RenderingHints;
+import java.awt.font.FontRenderContext;
+import java.awt.Dimension;
/**
* Renderer that renders areas to PDF
@@ -295,6 +312,7 @@ public class PDFRenderer extends PrintRenderer {
case Overflow.HIDDEN:
break;
}
+
area.getObject().render(this);
currentStream.add("Q\n");
currentStream.add("BT\n");
@@ -356,20 +374,67 @@ public class PDFRenderer extends PrintRenderer {
}
// transform so that the coordinates (0,0) is from the top left
// and positive is down and to the right. (0,0) is where the
- // viewBox puts it.
- currentStream.add(sx + " 0 0 " + sy + " " + xOffset / 1000f +
- " " + yOffset / 1000f + " cm\n");
+ // viewBox puts it.
+ currentStream.add(sx + " 0 0 " + sy + " " +
+ xOffset / 1000f + " " + yOffset / 1000f + " cm\n");
+
- SVGRenderer svgRenderer =
- new SVGRenderer(area.getFontState(), pdfDoc,
+ SVGDocument doc = area.getSVGDocument();
+
+ UserAgent userAgent = new MUserAgent(new AffineTransform());
+
+ GVTBuilder builder = new GVTBuilder();
+ GraphicsNodeRenderContext rc = getRenderContext();
+ BridgeContext ctx = new BridgeContext(userAgent, rc);
+ GraphicsNode root;
+ //System.out.println("creating PDFGraphics2D");
+ PDFGraphics2D graphics = new PDFGraphics2D(true, area.getFontState(), pdfDoc,
currentFontName, currentFontSize, currentXPosition,
currentYPosition);
- svgRenderer.renderSVG(svg, 0, 0);
- currentStream.add(svgRenderer.getString());
+ graphics.setGraphicContext(new org.apache.batik.ext.awt.g2d.GraphicContext());
+ graphics.setRenderingHints(rc.getRenderingHints());
+ try {
+ root = builder.build(ctx, doc);
+ root.paint(graphics, rc);
+ currentStream.add(graphics.getString());
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
currentStream.add("Q\n");
}
+ public GraphicsNodeRenderContext getRenderContext() {
+ GraphicsNodeRenderContext nodeRenderContext = null;
+ if (nodeRenderContext == null) {
+ RenderingHints hints = new RenderingHints(null);
+ hints.put(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+
+ hints.put(RenderingHints.KEY_INTERPOLATION,
+ RenderingHints.VALUE_INTERPOLATION_BILINEAR);
+
+ FontRenderContext fontRenderContext =
+ new FontRenderContext(new AffineTransform(), true, true);
+
+ TextPainter textPainter = new StrokingTextPainter();
+
+ GraphicsNodeRableFactory gnrFactory =
+ new ConcreteGraphicsNodeRableFactory();
+
+ nodeRenderContext =
+ new GraphicsNodeRenderContext(new AffineTransform(),
+ null,
+ hints,
+ fontRenderContext,
+ textPainter,
+ gnrFactory);
+ nodeRenderContext.setTextPainter(textPainter);
+ }
+
+ return nodeRenderContext;
+ }
+
/**
* render inline area to PDF
*
@@ -709,4 +774,118 @@ public class PDFRenderer extends PrintRenderer {
renderOutline((Outline) e.nextElement());
}
}
+
+ protected class MUserAgent implements UserAgent {
+ AffineTransform currentTransform = null;
+ /**
+ * Creates a new SVGUserAgent.
+ */
+ protected MUserAgent(AffineTransform at) {
+ currentTransform = at;
+ }
+
+ /**
+ * Displays an error message.
+ */
+ public void displayError(String message) {
+ System.err.println(message);
+ }
+
+ /**
+ * Displays an error resulting from the specified Exception.
+ */
+ public void displayError(Exception ex) {
+ ex.printStackTrace(System.err);
+ }
+
+ /**
+ * Displays a message in the User Agent interface.
+ * The given message is typically displayed in a status bar.
+ */
+ public void displayMessage(String message) {
+ System.out.println(message);
+ }
+
+ /**
+ * Returns a customized the pixel to mm factor.
+ */
+ public float getPixelToMM() {
+ return 0.264583333333333333333f; // 72 dpi
+ }
+
+ /**
+ * Returns the language settings.
+ */
+ public String getLanguages() {
+ return "en";//userLanguages;
+ }
+
+ /**
+ * Returns the user stylesheet uri.
+ * @return null if no user style sheet was specified.
+ */
+ public String getUserStyleSheetURI() {
+ return null;//userStyleSheetURI;
+ }
+
+ /**
+ * Returns the class name of the XML parser.
+ */
+ public String getXMLParserClassName() {
+ String parserClassName =
+ System.getProperty("org.xml.sax.parser");
+ if (parserClassName == null) {
+ parserClassName = "org.apache.xerces.parsers.SAXParser";
+ }
+ return parserClassName;//application.getXMLParserClassName();
+ }
+
+ /**
+ * Opens a link in a new component.
+ * @param doc The current document.
+ * @param uri The document URI.
+ */
+ public void openLink(SVGAElement elt)
+ {
+ //application.openLink(uri);
+ }
+
+ public Point getClientAreaLocationOnScreen()
+ {
+ return new Point(0, 0);
+ }
+
+ public void setSVGCursor(java.awt.Cursor cursor)
+ {
+ }
+
+ public AffineTransform getTransform()
+ {
+ return currentTransform;
+ }
+
+ public Dimension2D getViewportSize()
+ {
+ return new Dimension(100, 100);
+ }
+
+ public EventDispatcher getEventDispatcher()
+ {
+ return null;
+ }
+
+ public boolean supportExtension(String str)
+ {
+ return false;
+ }
+
+ public boolean hasFeature(String str)
+ {
+ return false;
+ }
+
+ public void registerExtension(BridgeExtension be)
+ {
+ }
+ }
}
diff --git a/src/org/apache/fop/render/pdf/SVGRenderer.java b/src/org/apache/fop/render/pdf/SVGRenderer.java
deleted file mode 100644
index f56d4a553..000000000
--- a/src/org/apache/fop/render/pdf/SVGRenderer.java
+++ /dev/null
@@ -1,2759 +0,0 @@
-/*-- $Id$ --
-
- ============================================================================
- The Apache Software License, Version 1.1
- ============================================================================
-
- Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
-
- Redistribution and use in source and binary forms, with or without modifica-
- tion, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
- 3. The end-user documentation included with the redistribution, if any, must
- include the following acknowledgment: "This product includes software
- developed by the Apache Software Foundation (http://www.apache.org/)."
- Alternately, this acknowledgment may appear in the software itself, if
- and wherever such third-party acknowledgments normally appear.
-
- 4. The names "FOP" and "Apache Software Foundation" must not be used to
- endorse or promote products derived from this software without prior
- written permission. For written permission, please contact
- apache@apache.org.
-
- 5. Products derived from this software may not be called "Apache", nor may
- "Apache" appear in their name, without prior written permission of the
- Apache Software Foundation.
-
- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
- DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- This software consists of voluntary contributions made by many individuals
- on behalf of the Apache Software Foundation and was originally created by
- James Tauber <jtauber@jtauber.com>. For more information on the Apache
- Software Foundation, please see <http://www.apache.org/>.
-
- */
-
-package org.apache.fop.render.pdf;
-
-// FOP
-import org.apache.fop.messaging.MessageHandler;
-import org.apache.fop.image.ImageArea;
-import org.apache.fop.image.FopImage;
-import org.apache.fop.apps.FOPException;
-import org.apache.fop.fo.properties.*;
-import org.apache.fop.layout.*;
-import org.apache.fop.datatypes.*;
-import org.apache.fop.svg.PathPoint;
-import org.apache.fop.pdf.*;
-import org.apache.fop.layout.*;
-import org.apache.fop.image.*;
-
-import org.w3c.dom.*;
-import org.w3c.dom.svg.*;
-import org.w3c.dom.css.*;
-import org.w3c.dom.svg.SVGLength;
-
-import org.apache.fop.dom.svg.*;
-import org.apache.fop.dom.svg.SVGRectElementImpl;
-import org.apache.fop.dom.svg.SVGTextElementImpl;
-import org.apache.fop.dom.svg.SVGLineElementImpl;
-import org.apache.fop.dom.svg.SVGArea;
-
-// Java
-import java.io.IOException;
-import java.io.StringWriter;
-import java.util.Enumeration;
-import java.awt.Rectangle;
-import java.util.Vector;
-import java.util.Hashtable;
-
-/**
- * Renderer that renders SVG to PDF
- */
-public class SVGRenderer {
-
- /** the PDF Document being created */
- protected PDFDocument pdfDoc;
-
- protected FontState fontState;
-
- /** the /Resources object of the PDF document being created */
- // protected PDFResources pdfResources;
-
- /** the current stream to add PDF commands to */
- StringWriter currentStream = new StringWriter();
-
- /** the current (internal) font name */
- protected String currentFontName;
-
- /** the current font size in millipoints */
- protected int currentFontSize;
-
- /** the current vertical position in millipoints from bottom */
- protected int currentYPosition = 0;
-
- /** the current horizontal position in millipoints from left */
- protected int currentXPosition = 0;
-
- /** the current colour for use in svg */
- private PDFColor currentColour = new PDFColor(0, 0, 0);
-
- // The toRadians() and toDegrees() methods of the Math class are not available in JDK 1.1, so reproduce here
- /**
- * Converts an angle measured in degrees to the equivalent angle
- * measured in radians.
- *
- * @param angdeg an angle, in degrees
- * @return the measurement of the angle <code>angdeg</code>
- * in radians.
- * @since JDK1.2
- */
- public static double toRadians(double angdeg) {
- return angdeg / 180.0 * Math.PI;
- }
- /**
- * Converts an angle measured in radians to the equivalent angle
- * measured in degrees.
- *
- * @param angrad an angle, in radians
- * @return the measurement of the angle <code>angrad</code>
- * in degrees.
- * @since JDK1.2
- */
- public static double toDegrees(double angrad) {
- return angrad * 180.0 / Math.PI;
- }
-
- /**
- * create the SVG renderer
- */
- public SVGRenderer(FontState fs, PDFDocument doc, String font,
- int size, int xpos, int ypos) {
- pdfDoc = doc;
- currentFontName = font;
- currentFontSize = size;
- currentYPosition = ypos;
- currentXPosition = xpos;
- fontState = fs;
- }
-
- public String getString() {
- return currentStream.toString();
- }
-
- /**
- * Renders an SVG element in an SVG document.
- * This renders each of the child elements.
- */
- protected void renderSVG(SVGSVGElement svg, int x, int y) {
- NodeList nl = svg.getChildNodes();
- for (int count = 0; count < nl.getLength(); count++) {
- Node n = nl.item(count);
- if (n instanceof SVGElement) {
- renderElement((SVGElement) n, x, y);
- }
- }
- }
-
- public void renderGArea(SVGGElement area, int posx, int posy) {
- NodeList nl = area.getChildNodes();
- for (int count = 0; count < nl.getLength(); count++) {
- Node n = nl.item(count);
- if (n instanceof SVGElement) {
- renderElement((SVGElement) n, posx, posy);
- }
- }
- }
-
- /**
- * Handles the SVG switch element.
- * The switch determines which of its child elements should be rendered
- * according to the required extensions, required features and system language.
- */
- protected void handleSwitchElement(int posx, int posy,
- SVGSwitchElement ael) {
- SVGStringList relist = ael.getRequiredExtensions();
- SVGStringList rflist = ael.getRequiredFeatures();
- SVGStringList sllist = ael.getSystemLanguage();
- NodeList nl = ael.getChildNodes();
- choices:
- for (int count = 0; count < nl.getLength(); count++) {
- org.w3c.dom.Node n = nl.item(count);
- // only render the first child that has a valid
- // test data
- if (n instanceof GraphicElement) {
- GraphicElement graphic = (GraphicElement) n;
- SVGStringList grelist = graphic.getRequiredExtensions();
- // if null it evaluates to true
- if (grelist != null) {
- if (grelist.getNumberOfItems() == 0) {
- if ((relist != null) &&
- relist.getNumberOfItems() != 0) {
- continue choices;
- }
- }
- for (int i = 0; i < grelist.getNumberOfItems(); i++) {
- String str = (String) grelist.getItem(i);
- if (relist == null) {
- // use default extension set
- // currently no extensions are supported
- // if(!(str.equals("http:// ??"))) {
- continue choices;
- // }
- } else {
- }
- }
- }
- SVGStringList grflist = graphic.getRequiredFeatures();
- if (grflist != null) {
- if (grflist.getNumberOfItems() == 0) {
- if ((rflist != null) &&
- rflist.getNumberOfItems() != 0) {
- continue choices;
- }
- }
- for (int i = 0; i < grflist.getNumberOfItems(); i++) {
- String str = (String) grflist.getItem(i);
- if (rflist == null) {
- // use default feature set
- if (!(str.equals("org.w3c.svg.static") ||
- str.equals("org.w3c.dom.svg.all"))) {
- continue choices;
- }
- } else {
- boolean found = false;
- for (int j = 0;
- j < rflist.getNumberOfItems(); j++) {
- if (rflist.getItem(j).equals(str)) {
- found = true;
- break;
- }
- }
- if (!found)
- continue choices;
- }
- }
- }
- SVGStringList gsllist = graphic.getSystemLanguage();
- if (gsllist != null) {
- if (gsllist.getNumberOfItems() == 0) {
- if ((sllist != null) &&
- sllist.getNumberOfItems() != 0) {
- continue choices;
- }
- }
- for (int i = 0; i < gsllist.getNumberOfItems(); i++) {
- String str = (String) gsllist.getItem(i);
- if (sllist == null) {
- // use default feature set
- if (!(str.equals("en"))) {
- continue choices;
- }
- } else {
- boolean found = false;
- for (int j = 0;
- j < sllist.getNumberOfItems(); j++) {
- if (sllist.getItem(j).equals(str)) {
- found = true;
- break;
- }
- }
- if (!found)
- continue choices;
- }
- }
- }
- renderElement((SVGElement) n, posx, posy);
- // only render the first valid one
- break;
- }
- }
- }
-
- /**
- * add a line to the current stream
- *
- * @param x1 the start x location in millipoints
- * @param y1 the start y location in millipoints
- * @param x2 the end x location in millipoints
- * @param y2 the end y location in millipoints
- * @param th the thickness in millipoints
- * @param r the red component
- * @param g the green component
- * @param b the blue component
- */
- protected void addLine(float x1, float y1, float x2, float y2,
- DrawingInstruction di) {
- String str;
- PDFNumber pdfNumber = new PDFNumber();
- str = "" + pdfNumber.doubleOut(x1) + " " + pdfNumber.doubleOut(y1) + " m " + pdfNumber.doubleOut(x2) + " " + pdfNumber.doubleOut(y2) + " l";
- if (di != null && di.fill)
- currentStream.write(str + " f\n"); // ??
- currentStream.write(str + " S\n");
- }
-
- /**
- * Add an SVG circle
- * Uses bezier curves to approximate the shape of a circle.
- */
- protected void addCircle(float cx, float cy, float r,
- DrawingInstruction di) {
- PDFNumber pdfNumber = new PDFNumber();
- String str;
- str = "" + pdfNumber.doubleOut(cx) + " " + pdfNumber.doubleOut((cy - r)) + " m\n" + "" +
- pdfNumber.doubleOut((cx + 21 * r / 40f)) + " " + pdfNumber.doubleOut((cy - r)) + " " +
- pdfNumber.doubleOut((cx + r)) + " " + pdfNumber.doubleOut((cy - 21 * r / 40f)) + " " +
- pdfNumber.doubleOut((cx + r)) + " " + pdfNumber.doubleOut(cy) + " c\n" + "" + pdfNumber.doubleOut((cx + r)) + " " +
- pdfNumber.doubleOut((cy + 21 * r / 40f)) + " " + pdfNumber.doubleOut((cx + 21 * r / 40f)) +
- " " + pdfNumber.doubleOut((cy + r)) + " " + pdfNumber.doubleOut(cx) + " " + pdfNumber.doubleOut((cy + r)) + " c\n" +
- "" + pdfNumber.doubleOut((cx - 21 * r / 40f)) + " " + pdfNumber.doubleOut((cy + r)) + " " +
- pdfNumber.doubleOut(cx - r) + " " + pdfNumber.doubleOut(cy + 21 * r / 40f) + " " +
- pdfNumber.doubleOut(cx - r) + " " + pdfNumber.doubleOut(cy) + " c\n" + "" + pdfNumber.doubleOut(cx - r) + " " +
- pdfNumber.doubleOut(cy - 21 * r / 40f) + " " + pdfNumber.doubleOut(cx - 21 * r / 40f) +
- " " + pdfNumber.doubleOut(cy - r) + " " + pdfNumber.doubleOut(cx) + " " + pdfNumber.doubleOut(cy - r) + " c\n";
-
- currentStream.write(str);
- doDrawing(di);
- }
-
- /**
- * Add an SVG ellips
- * Uses bezier curves to approximate the shape of an ellipse.
- */
- protected void addEllipse(float cx, float cy, float rx, float ry,
- DrawingInstruction di) {
- PDFNumber pdfNumber = new PDFNumber();
- String str;
- str = "" + pdfNumber.doubleOut(cx) + " " + pdfNumber.doubleOut(cy - ry) + " m\n" + "" +
- pdfNumber.doubleOut(cx + 21 * rx / 40f) + " " + pdfNumber.doubleOut(cy - ry) + " " +
- pdfNumber.doubleOut(cx + rx) + " " + pdfNumber.doubleOut(cy - 21 * ry / 40f) + " " +
- pdfNumber.doubleOut(cx + rx) + " " + pdfNumber.doubleOut(cy) + " c\n" + "" + pdfNumber.doubleOut(cx + rx) + " " +
- pdfNumber.doubleOut(cy + 21 * ry / 40f) + " " + pdfNumber.doubleOut(cx + 21 * rx / 40f) +
- " " + pdfNumber.doubleOut(cy + ry) + " " + pdfNumber.doubleOut(cx) + " " + pdfNumber.doubleOut(cy + ry) +
- " c\n" + "" + pdfNumber.doubleOut(cx - 21 * rx / 40f) + " " + pdfNumber.doubleOut(cy + ry) +
- " " + pdfNumber.doubleOut(cx - rx) + " " + pdfNumber.doubleOut(cy + 21 * ry / 40f) + " " +
- pdfNumber.doubleOut(cx - rx) + " " + pdfNumber.doubleOut(cy) + " c\n" + "" + pdfNumber.doubleOut(cx - rx) + " " +
- pdfNumber.doubleOut(cy - 21 * ry / 40f) + " " + pdfNumber.doubleOut(cx - 21 * rx / 40f) +
- " " + pdfNumber.doubleOut(cy - ry) + " " + pdfNumber.doubleOut(cx) + " " + pdfNumber.doubleOut(cy - ry) + " c\n";
- currentStream.write(str);
- doDrawing(di);
- }
-
- /**
- * add an SVG rectangle to the current stream.
- * If there are curved edges then these are rendered using bezier curves.
- *
- * @param x the x position of left edge
- * @param y the y position of top edge
- * @param w the width
- * @param h the height
- * @param rx the x radius curved edge
- * @param ry the y radius curved edge
- */
- protected void addRect(float x, float y, float w, float h,
- float rx, float ry, DrawingInstruction di) {
- PDFNumber pdfNumber = new PDFNumber();
- String str = "";
- if (rx == 0.0 && ry == 0.0) {
- str = "" + pdfNumber.doubleOut(x) + " " + pdfNumber.doubleOut(y) + " " + pdfNumber.doubleOut(w) + " " + pdfNumber.doubleOut(h) + " re\n";
- } else {
- if (ry == 0.0)
- ry = rx;
- if (rx > w / 2.0f)
- rx = w / 2.0f;
- if (ry > h / 2.0f)
- ry = h / 2.0f;
- str = "" + pdfNumber.doubleOut(x + rx) + " " + pdfNumber.doubleOut(y) + " m\n";
- str += "" + pdfNumber.doubleOut(x + w - rx) + " " + pdfNumber.doubleOut(y) + " l\n";
- str += "" + pdfNumber.doubleOut(x + w - 19 * rx / 40) + " " + pdfNumber.doubleOut(y) + " " +
- pdfNumber.doubleOut(x + w) + " " + pdfNumber.doubleOut(y + 19 * ry / 40) + " " +
- pdfNumber.doubleOut(x + w) + " " + pdfNumber.doubleOut(y + ry) + " c\n";
- str += "" + pdfNumber.doubleOut(x + w) + " " + pdfNumber.doubleOut(y + h - ry) + " l\n";
- str += "" + pdfNumber.doubleOut(x + w) + " " + pdfNumber.doubleOut(y + h - 19 * ry / 40) + " " +
- pdfNumber.doubleOut(x + w - 19 * rx / 40) + " " + pdfNumber.doubleOut(y + h) + " " +
- pdfNumber.doubleOut(x + w - rx) + " " + pdfNumber.doubleOut(y + h) + " c\n";
- str += "" + pdfNumber.doubleOut(x + rx) + " " + pdfNumber.doubleOut(y + h) + " l\n";
- str += "" + pdfNumber.doubleOut(x + 19 * rx / 40) + " " + pdfNumber.doubleOut(y + h) + " " + pdfNumber.doubleOut(x) +
- " " + pdfNumber.doubleOut(y + h - 19 * ry / 40) + " " + pdfNumber.doubleOut(x) + " " +
- pdfNumber.doubleOut(y + h - ry) + " c\n";
- str += "" + pdfNumber.doubleOut(x) + " " + pdfNumber.doubleOut(y + ry) + " l\n";
- str += "" + pdfNumber.doubleOut(x) + " " + pdfNumber.doubleOut(y + 19 * ry / 40) + " " +
- pdfNumber.doubleOut(x + 19 * rx / 40) + " " + pdfNumber.doubleOut(y) + " " + pdfNumber.doubleOut(x + rx) +
- " " + pdfNumber.doubleOut(y) + " c\n";
- }
- currentStream.write(str);
- doDrawing(di);
- }
-
- /**
- * Adds an SVG path to the current streem.
- * An SVG path is made up of a list of drawing instructions that are rendered
- * out in order.
- * Arcs don't work.
- */
- protected void addPath(Vector points, int posx, int posy,
- DrawingInstruction di) {
- PDFNumber pdfNumber = new PDFNumber();
- SVGPathSegImpl pathmoveto = null;
- float lastx = 0;
- float lasty = 0;
- float lastmovex = 0;
- float lastmovey = 0;
- float[] cxs;
- float tempx;
- float tempy;
- float lastcx = 0;
- float lastcy = 0;
- for (Enumeration e = points.elements(); e.hasMoreElements();) {
- SVGPathSegImpl pc = (SVGPathSegImpl) e.nextElement();
- float[] vals = pc.getValues();
- switch (pc.getPathSegType()) {
- case SVGPathSeg.PATHSEG_MOVETO_ABS:
- pathmoveto = pc;
- lastx = vals[0];
- lasty = vals[1];
- currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " m\n");
- lastcx = 0;
- lastcy = 0;
- lastmovex = lastx;
- lastmovey = lasty;
- break;
- case SVGPathSeg.PATHSEG_MOVETO_REL:
- // the test cases seem to interprete this command differently
- // it seems if there is an 'm' then the current path is closed
- // then the point is move to a place relative to the point
- // after doing the close
- if (pathmoveto == null) {
- lastx += vals[0];
- lasty += vals[1];
- pathmoveto = pc;
- currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " m\n");
- } else {
- lastx += vals[0];
- lasty += vals[1];
- pathmoveto = pc;
- currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " l\n");
- }
- lastmovex = lastx;
- lastmovey = lasty;
- lastcx = 0;
- lastcy = 0;
- break;
- case SVGPathSeg.PATHSEG_LINETO_ABS:
- lastx = vals[0];
- lasty = vals[1];
- currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " l\n");
- lastcx = 0;
- lastcy = 0;
- break;
- case SVGPathSeg.PATHSEG_LINETO_REL:
- lastx += vals[0];
- lasty += vals[1];
- currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " l\n");
- lastcx = 0;
- lastcy = 0;
- break;
- case SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:
- lasty = vals[0];
- currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " l\n");
- lastcx = 0;
- lastcy = 0;
- break;
- case SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:
- lasty += vals[0];
- currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " l\n");
- lastcx = 0;
- lastcy = 0;
- break;
- case SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:
- lastx = vals[0];
- currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " l\n");
- lastcx = 0;
- lastcy = 0;
- break;
- case SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:
- lastx += vals[0];
- currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " l\n");
- lastcx = 0;
- lastcy = 0;
- break;
- case SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:
- lastx = vals[4];
- lasty = vals[5];
- lastcx = vals[2];
- lastcy = vals[3];
- currentStream.write(pdfNumber.doubleOut(vals[0]) + " " + pdfNumber.doubleOut(vals[1]) +
- " " + pdfNumber.doubleOut(vals[2]) + " " + pdfNumber.doubleOut(vals[3]) + " " +
- pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " c\n");
- break;
- case SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:
- currentStream.write(pdfNumber.doubleOut(vals[0] + lastx) + " " +
- pdfNumber.doubleOut(vals[1] + lasty) + " " +
- pdfNumber.doubleOut(vals[2] + lastx) + " " +
- pdfNumber.doubleOut(vals[3] + lasty) + " " +
- pdfNumber.doubleOut(vals[4] + lastx) + " " +
- pdfNumber.doubleOut(vals[5] + lasty) + " c\n");
- lastcx = vals[2] + lastx;
- lastcy = vals[3] + lasty;
- lastx += vals[4];
- lasty += vals[5];
- break;
- case SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
- if (lastcx == 0) {
- lastcx = lastx;
- }
- if (lastcy == 0) {
- lastcy = lasty;
- }
- lastcx = lastx + (lastx - lastcx);
- lastcy = lasty + (lasty - lastcy);
- lastx = vals[2];
- lasty = vals[3];
- currentStream.write(pdfNumber.doubleOut(lastcx) + " " + pdfNumber.doubleOut(lastcy) + " " +
- pdfNumber.doubleOut(vals[0]) + " " + pdfNumber.doubleOut(vals[1]) + " " +
- pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " c\n");
- lastcx = vals[0];
- lastcy = vals[1];
- break;
- case SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
- if (lastcx == 0) {
- lastcx = lastx;
- }
- if (lastcy == 0) {
- lastcy = lasty;
- }
- lastcx = lastx + (lastx - lastcx);
- lastcy = lasty + (lasty - lastcy);
- currentStream.write(pdfNumber.doubleOut(lastcx) + " " + pdfNumber.doubleOut(lastcy) + " " +
- pdfNumber.doubleOut(vals[0] + lastx) + " " +
- pdfNumber.doubleOut(vals[1] + lasty) + " " +
- pdfNumber.doubleOut(vals[2] + lastx) + " " +
- pdfNumber.doubleOut(vals[3] + lasty) + " c\n");
- lastcx = (vals[0] + lastx);
- lastcy = (vals[1] + lasty);
- lastx += vals[2];
- lasty += vals[3];
- break;
- case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:
- if (lastcx == 0) {
- lastcx = lastx;
- }
- if (lastcy == 0) {
- lastcy = lasty;
- }
- tempx = lastx;
- tempy = lasty;
- lastx = vals[2];
- lasty = vals[3];
- currentStream.write(pdfNumber.doubleOut(vals[0]) + " " + pdfNumber.doubleOut(vals[1]) + " " +
- pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " y\n");
- cxs = calculateLastControl(tempx, tempy, lastx, lasty, -tempx + vals[0], -tempy + vals[1]);
- lastcx = cxs[0];
- lastcy = cxs[1];
- break;
- case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:
- if (lastcx == 0) {
- lastcx = lastx;
- }
- if (lastcy == 0) {
- lastcy = lasty;
- }
- currentStream.write(pdfNumber.doubleOut(vals[0] + lastx) + " " + pdfNumber.doubleOut(vals[1] + lasty) + " " +
- pdfNumber.doubleOut(vals[2] + lastx) + " " +
- pdfNumber.doubleOut(vals[3] + lasty) + " y\n");
- cxs = calculateLastControl(lastx, lasty, lastx + vals[2], lasty + vals[3], vals[0], vals[1]);
- lastcx = cxs[0];
- lastcy = cxs[1];
- lastx += vals[2];
- lasty += vals[3];
- break;
- case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
- if (lastcx == 0) {
- lastcx = lastx;
- }
- if (lastcy == 0) {
- lastcy = lasty;
- }
- tempx = lastx;
- tempy = lasty;
- lastcx = lastx + (lastx - lastcx);
- lastcy = lasty + (lasty - lastcy);
- lastx = vals[0];
- lasty = vals[1];
- currentStream.write(pdfNumber.doubleOut(lastcx) + " " + pdfNumber.doubleOut(lastcy) + " " +
- pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " y\n");
- cxs = calculateLastControl(tempx, tempy, lastx, lasty, -tempx + lastcx, -tempy + lastcy);
- lastcx = cxs[0];
- lastcy = cxs[1];
- break;
- case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
- if (lastcx == 0) {
- lastcx = lastx;
- }
- if (lastcy == 0) {
- lastcy = lasty;
- }
- lastcx = lastx + (lastx - lastcx);
- lastcy = lasty + (lasty - lastcy);
- currentStream.write(pdfNumber.doubleOut(lastcx) + " " + pdfNumber.doubleOut(lastcy) + " " +
- pdfNumber.doubleOut(vals[0] + lastx) + " " +
- pdfNumber.doubleOut(vals[1] + lasty) + " y\n");
- cxs = calculateLastControl(lastx, lasty, lastx + vals[0], lasty + vals[1], -lastx + lastcx, -lasty + lastcy);
- lastcx = cxs[0];
- lastcy = cxs[1];
- lastx += vals[0];
- lasty += vals[1];
- break;
- case SVGPathSeg.PATHSEG_ARC_ABS:
- {
- addArc(lastx, lasty, vals[0], vals[1], vals[2], (vals[3] != 0.0), (vals[4] != 0.0),
- vals[5], vals[6]);
- lastcx = 0; //??
- lastcy = 0; //??
- lastx = vals[5];
- lasty = vals[6];
- }
- break;
- case SVGPathSeg.PATHSEG_ARC_REL:
- {
- addArc(lastx, lasty, vals[0], vals[1], vals[2], (vals[3] != 0.0), (vals[4] != 0.0),
- lastx + vals[5], lasty + vals[6]);
- lastcx = 0; //??
- lastcy = 0; //??
- lastx += vals[5];
- lasty += vals[6];
- }
- break;
- case SVGPathSeg.PATHSEG_CLOSEPATH:
- currentStream.write("h\n");
- pathmoveto = null;
- lastx = lastmovex;
- lasty = lastmovey;
- break;
- }
- }
- doDrawing(di);
- }
-
- /**
- * Calculate the last control point for a bezier curve.
- * This is used to find the last control point for a curve where
- * only the first control point is specified.
- * The control point is a reflection of the first control point
- * which results in an even smooth curve. The curve is symmetrical.
- */
- protected float[] calculateLastControl(float x1, float y1, float x2, float y2, float relx, float rely)
- {
- float vals[] = new float[2];
- relx = -relx;
- rely = -rely;
- float dist = (float)Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
- float costheta = (float)(x2 - x1) / dist;
- float sinetheta = (float)(y2 - y1) / dist;
- float temp = relx;
- relx = relx * costheta + rely * sinetheta;
- rely = -temp * sinetheta + rely * costheta;
- relx = -relx;
- temp = relx;
- relx = relx * costheta - rely * sinetheta;
- rely = temp * sinetheta + rely * costheta;
- vals[0] = x2 - relx;
- vals[1] = y2 - rely;
- return vals;
- }
-
- protected void addArc(double startx, double starty, double rx, double ry,
- double angle,
- boolean largeArcFlag,
- boolean sweepFlag,
- double x, double y)
- {
- PDFNumber pdfNumber = new PDFNumber();
- if((startx == x) && (starty == y)) {
- return;
- }
- // Ensure radii are valid
- if (rx == 0 || ry == 0) {
- currentStream.write(pdfNumber.doubleOut(x) + " " + pdfNumber.doubleOut(y) + " l\n");
- return;
- }
- if(rx < 0)
- rx = -rx;
- if(ry < 0)
- ry = -ry;
- // Convert angle from degrees to radians
- angle = toRadians(angle % 360.0);
-
- double x0 = startx;
- double y0 = starty;
- // Compute the half distance between the current and the final point
- double dx2 = (x0 - x) / 2.0;
- double dy2 = (y0 - y) / 2.0;
-
- double cosAngle = Math.cos(angle);
- double sinAngle = Math.sin(angle);
-
- // Step 1 : Compute (x1, y1)
- double x1 = (cosAngle * dx2 + sinAngle * dy2);
- double y1 = (-sinAngle * dx2 + cosAngle * dy2);
-
- double Prx = rx * rx;
- double Pry = ry * ry;
- double Px1 = x1 * x1;
- double Py1 = y1 * y1;
- // check that radii are large enough
- double radiiCheck = Px1/Prx + Py1/Pry;
- if (radiiCheck > 1) {
- rx = Math.sqrt(radiiCheck) * rx;
- ry = Math.sqrt(radiiCheck) * ry;
- Prx = rx * rx;
- Pry = ry * ry;
- }
-
- // Step 2 : Compute (cx1, cy1)
- double sign = (largeArcFlag == sweepFlag) ? -1 : 1;
- double sq = ((Prx*Pry)-(Prx*Py1)-(Pry*Px1)) / ((Prx*Py1)+(Pry*Px1));
- sq = (sq < 0) ? 0 : sq;
- double coef = (sign * Math.sqrt(sq));
- double cx1 = coef * ((rx * y1) / ry);
- double cy1 = coef * -((ry * x1) / rx);
-
- // Step 3 : Compute (cx, cy) from (cx1, cy1)
- double sx2 = (x0 + x) / 2.0;
- double sy2 = (y0 + y) / 2.0;
- double cx = sx2 + (cosAngle * cx1 - sinAngle * cy1);
- double cy = sy2 + (sinAngle * cx1 + cosAngle * cy1);
-
- // Step 4 : Compute the angleStart (angle1) and the angleExtent (dangle)
- double ux = (x1 - cx1) / rx;
- double uy = (y1 - cy1) / ry;
- double vx = (-x1 - cx1) / rx;
- double vy = (-y1 - cy1) / ry;
- double p, n;
- // Compute the angle start
- n = Math.sqrt((ux * ux) + (uy * uy));
- p = ux; // (1 * ux) + (0 * uy)
- sign = (uy < 0) ? -1d : 1d;
- double angleStart = toDegrees(sign * Math.acos(p / n));
-
- // Compute the angle extent
- n = Math.sqrt((ux * ux + uy * uy) * (vx * vx + vy * vy));
- p = ux * vx + uy * vy;
- sign = (ux * vy - uy * vx < 0) ? -1d : 1d;
- double angleExtent = toDegrees(sign * Math.acos(p / n));
- if(!sweepFlag && angleExtent > 0) {
- angleExtent -= 360f;
- } else if (sweepFlag && angleExtent < 0) {
- angleExtent += 360f;
- }
- angleExtent %= 360f;
- angleStart %= 360f;
-
- // arc attempt with lines
-// System.out.println("start:" + angleStart + " : " + angleExtent + " sweep:" + sweepFlag);
- double newx = startx;
- double newy = starty;
- double currentAngle = angleStart + angle;
- boolean wrap = (sweepFlag ? angleStart > angleExtent : angleStart < angleExtent);
- boolean wrapped = false;
-
-/* newx = Math.cos(toRadians(angle)) * rx * Math.cos(toRadians(currentAngle)) - Math.sin(toRadians(angle)) * ry * Math.sin(toRadians(currentAngle)) + cx;
- newy = Math.sin(toRadians(angle)) * rx * Math.cos(toRadians(currentAngle)) + Math.cos(toRadians(angle)) * ry * Math.sin(toRadians(currentAngle)) + cy;
- System.out.println("ox:" + startx + " oy: " + starty + " nx:" + newx + " ny:" + newy);
- newx = Math.cos(toRadians(angle)) * rx * Math.cos(toRadians(angleStart + angleExtent)) - Math.sin(toRadians(angle)) * ry * Math.sin(toRadians(angleStart + angleExtent)) + cx;
- newy = Math.sin(toRadians(angle)) * rx * Math.cos(toRadians(angleStart + angleExtent)) + Math.cos(toRadians(angle)) * ry * Math.sin(toRadians(angleStart + angleExtent)) + cy;
- System.out.println("ox:" + x + " oy: " + y + " nx:" + newx + " ny:" + newy);*/
-
- while(true) {
- newx = Math.cos(toRadians(angle)) * rx * Math.cos(toRadians(currentAngle)) - Math.sin(toRadians(angle)) * ry * Math.sin(toRadians(currentAngle)) + cx;
- newy = Math.sin(toRadians(angle)) * rx * Math.cos(toRadians(currentAngle)) + Math.cos(toRadians(angle)) * ry * Math.sin(toRadians(currentAngle)) + cy;
- currentStream.write(pdfNumber.doubleOut(newx) + " " + pdfNumber.doubleOut(newy) + " l\n");
- currentAngle = (currentAngle + (sweepFlag ? 1 : -1) * 5.0);
- if((sweepFlag && currentAngle > (angleStart + angleExtent)) || (!sweepFlag && currentAngle < (angleStart + angleExtent))) {
- break;
- }
- }
- currentStream.write(pdfNumber.doubleOut(x) + " " + pdfNumber.doubleOut(y) + " l\n");
- }
-
- /**
- * Adds an SVG polyline or polygon.
- * A polygon is merely a closed polyline.
- * This is made up from a set of points that straight lines are drawn between.
- */
- protected void addPolyline(Vector points, DrawingInstruction di,
- boolean close) {
- PDFNumber pdfNumber = new PDFNumber();
- PathPoint pc;
- float lastx = 0;
- float lasty = 0;
- Enumeration e = points.elements();
- if (e.hasMoreElements()) {
- pc = (PathPoint) e.nextElement();
- lastx = pc.x;
- lasty = pc.y;
- currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " m\n");
- }
- while (e.hasMoreElements()) {
- pc = (PathPoint) e.nextElement();
- lastx = pc.x;
- lasty = pc.y;
- currentStream.write(pdfNumber.doubleOut(lastx) + " " + pdfNumber.doubleOut(lasty) + " l\n");
- }
- if (close)
- currentStream.write("h\n");
- doDrawing(di);
- }
-
- /**
- * Writes the drawing instruction out to the current stream
- * depending on what type of drawing is required.
- */
- protected void doDrawing(DrawingInstruction di) {
- if (di == null) {
- currentStream.write("S\n");
- } else {
- if (di.fill) {
- if (di.stroke) {
- if (!di.nonzero)
- currentStream.write("B*\n");
- else
- currentStream.write("B\n");
- } else {
- if (!di.nonzero)
- currentStream.write("f*\n");
- else
- currentStream.write("f\n");
- }
- } else {
- // if(di.stroke)
- currentStream.write("S\n");
- }
- }
- }
-
- /**
- * Renders an svg image to the current stream.
- * This uses the FopImageFactory to load the image and then renders it.
- */
- public void renderImage(String href, float x, float y, float width,
- float height) {
- try {
- if (href.indexOf(":") == -1) {
- href = "file:" + href;
- }
- FopImage img = FopImageFactory.Make(href);
- PDFNumber pdfNumber = new PDFNumber();
- if (img instanceof SVGImage) {
- SVGSVGElement svg =
- ((SVGImage) img).getSVGDocument().getRootElement();
- currentStream.write("q\n" + pdfNumber.doubleOut(width /
- svg.getWidth().getBaseVal().getValue()) + " 0 0 " +
- pdfNumber.doubleOut(height /
- svg.getHeight().getBaseVal().getValue()) + " 0 0 cm\n");
- renderSVG(svg, (int) x * 1000, (int) y * 1000);
- currentStream.write("Q\n");
- // renderSVG(svg);
- } else if (img != null) {
- int xObjectNum = this.pdfDoc.addImage(img);
- currentStream.write("q\n1 0 0 -1 0 " +
- pdfNumber.doubleOut(2 * y + height) + " cm\n" + pdfNumber.doubleOut(width) + " 0 0 " +
- pdfNumber.doubleOut(height) + " " + pdfNumber.doubleOut(x) + " " + pdfNumber.doubleOut(y) + " cm\n" + "/Im" +
- xObjectNum + " Do\nQ\n");
- // img.close();
- }
- } catch (Exception e) {
- MessageHandler.errorln("could not add image to SVG: " + href);
- }
- }
-
- /**
- * A symbol has a viewbox and preserve aspect ratio.
- */
- protected void renderSymbol(SVGSymbolElement symbol, int x, int y) {
- NodeList nl = symbol.getChildNodes();
- for (int count = 0; count < nl.getLength(); count++) {
- Node n = nl.item(count);
- if (n instanceof SVGElement) {
- renderElement((SVGElement) n, x, y);
- }
- }
- }
-
- /**
- * Handles the construction of an SVG gradient.
- * This gets the gradient element and creates the pdf info
- * in the pdf document.
- * The type of gradient is determined by what class the gradient element is.
- */
- protected void handleGradient(String sp, DrawingInstruction di,
- boolean fill, SVGElement area) {
- // should be a url to a gradient
- String url = (String) sp;
- if (url.startsWith("url(")) {
- String address;
- int b1 = url.indexOf("(");
- int b2 = url.indexOf(")");
- address = url.substring(b1 + 1, b2);
- SVGElement gi = null;
- gi = locateDef(address, area);
- if (gi instanceof SVGLinearGradientElement) {
- SVGLinearGradientElement linear =
- (SVGLinearGradientElement) gi;
- handleLinearGradient(linear, di, fill, area);
- } else if (gi instanceof SVGRadialGradientElement) {
- SVGRadialGradientElement radial =
- (SVGRadialGradientElement) gi;
- handleRadialGradient(radial, di, fill, area);
- } else if (gi instanceof SVGPatternElement) {
- SVGPatternElement pattern = (SVGPatternElement) gi;
- handlePattern(pattern, di, fill, area);
- } else {
- MessageHandler.errorln("WARNING Invalid fill reference :" +
- gi + ":" + address);
- }
- }
- }
-
- protected void handlePattern(SVGPatternElement pattern,
- DrawingInstruction di, boolean fill, SVGElement area) {
- SVGAnimatedLength x, y, width, height;
- short pattUnits = SVGUnitTypes.SVG_UNIT_TYPE_UNKNOWN;
- NodeList stops = null;
- x = pattern.getX();
- y = pattern.getY();
- width = pattern.getWidth();
- height = pattern.getHeight();
- NodeList nl = pattern.getChildNodes();
- SVGPatternElement ref = (SVGPatternElement) locateDef(
- pattern.getHref().getBaseVal(), pattern);
- while (ref != null) {
- if (x == null) {
- x = ref.getX();
- pattUnits = ref.getPatternUnits().getBaseVal();
- }
- if (y == null) {
- y = ref.getY();
- }
- if (width == null) {
- width = ref.getWidth();
- }
- if (height == null) {
- height = ref.getHeight();
- }
- if (nl.getLength() == 0) {
- nl = ref.getChildNodes();
- }
- ref = (SVGPatternElement) locateDef(
- ref.getHref().getBaseVal(), ref);
- }
- if (x == null) {
- SVGLength length = new SVGLengthImpl();
- length.newValueSpecifiedUnits(
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0);
- x = new SVGAnimatedLengthImpl(length);
- }
- if (y == null) {
- SVGLength length = new SVGLengthImpl();
- length.newValueSpecifiedUnits(
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0);
- y = new SVGAnimatedLengthImpl(length);
- }
- if (width == null) {
- SVGLength length = new SVGLengthImpl();
- length.newValueSpecifiedUnits(
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 1);
- width = new SVGAnimatedLengthImpl(length);
- }
- if (height == null) {
- SVGLength length = new SVGLengthImpl();
- length.newValueSpecifiedUnits(
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 1);
- height = new SVGAnimatedLengthImpl(length);
- }
-
- StringWriter realStream = currentStream;
- currentStream = new StringWriter();
-
- currentStream.write("q\n");
- // this makes the pattern the right way up, since it is outside the original
- // transform around the whole svg document
- currentStream.write("1 0 0 -1 0 " +
- height.getBaseVal().getValue() + " cm\n");
- for (int count = 0; count < nl.getLength(); count++) {
- Node n = nl.item(count);
- if (n instanceof SVGElement) {
- renderElement((SVGElement) n, 0, 0);
- }
- }
- currentStream.write("Q\n");
-
- double xval = x.getBaseVal().getValue() + currentXPosition / 1000f;
- double yval = -y.getBaseVal().getValue() + currentYPosition / 1000f;
- if (area instanceof GraphicElement) {
- SVGRect bbox = ((GraphicElement) area).getBBox();
- if (bbox != null) {
- // xval += bbox.getX();
- // yval -= bbox.getY();
- }
- }
- double widthval = width.getBaseVal().getValue();
- double heightval = height.getBaseVal().getValue();
- Vector bbox = new Vector();
- bbox.addElement(new Double(0));
- bbox.addElement(new Double(0));
- bbox.addElement(new Double(widthval));
- bbox.addElement(new Double(heightval));
- Vector translate = new Vector();
- // combine with pattern transform
- translate.addElement(new Double(1));
- translate.addElement(new Double(0));
- translate.addElement(new Double(0));
- translate.addElement(new Double(1));
- translate.addElement(new Double(xval));
- translate.addElement(new Double(yval));
- // need to handle PDFResources
- PDFPattern myPat =
- this.pdfDoc.makePattern(1, null, 1, 1, bbox, widthval,
- heightval, translate, null, currentStream.getBuffer());
-
- currentStream = realStream;
- currentStream.write(myPat.getColorSpaceOut(fill));
- if (fill)
- di.fill = true;
- else
- di.stroke = true;
- }
-
- protected void handleLinearGradient(
- SVGLinearGradientElement linear, DrawingInstruction di,
- boolean fill, SVGElement area) {
- // first get all the gradient values
- // if values not present follow the href
- // the gradient units will be where the vals are specified
- // the spread method will be where there are stop elements
- SVGAnimatedLength ax1, ax2, ay1, ay2;
- short spread = SVGGradientElement.SVG_SPREADMETHOD_UNKNOWN;
- short gradUnits = SVGUnitTypes.SVG_UNIT_TYPE_UNKNOWN;
- NodeList stops = null;
- ax1 = linear.getX1();
- ax2 = linear.getX2();
- ay1 = linear.getY1();
- ay2 = linear.getY2();
- stops = linear.getChildNodes();
- SVGLinearGradientElement ref = (SVGLinearGradientElement) locateDef(
- linear.getHref().getBaseVal(), linear);
- while (ref != null) {
- if (ax1 == null) {
- ax1 = ref.getX1();
- gradUnits = ref.getGradientUnits().getBaseVal();
- }
- if (ax2 == null) {
- ax2 = ref.getX2();
- }
- if (ay1 == null) {
- ay1 = ref.getY1();
- }
- if (ay2 == null) {
- ay2 = ref.getY2();
- }
- if (stops.getLength() == 0) {
- stops = ref.getChildNodes();
- }
- ref = (SVGLinearGradientElement) locateDef(
- ref.getHref().getBaseVal(), ref);
- }
- if (ax1 == null) {
- SVGLength length = new SVGLengthImpl();
- length.newValueSpecifiedUnits(
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0);
- ax1 = new SVGAnimatedLengthImpl(length);
- }
- if (ax2 == null) {
- // if x2 is not specified then it should be 100%
- SVGLength length = new SVGLengthImpl();
- length.newValueSpecifiedUnits(
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 1);
- ax2 = new SVGAnimatedLengthImpl(length);
- }
- if (ay1 == null) {
- SVGLength length = new SVGLengthImpl();
- length.newValueSpecifiedUnits(
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0);
- ay1 = new SVGAnimatedLengthImpl(length);
- }
- if (ay2 == null) {
- SVGLength length = new SVGLengthImpl();
- length.newValueSpecifiedUnits(
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0);
- ay2 = new SVGAnimatedLengthImpl(length);
- }
- SVGAnimatedTransformList an = linear.getGradientTransform();
- SVGMatrix transform = null;
- if(an != null)
- transform = an.getBaseVal().consolidate().getMatrix();
- Vector theCoords = null;
- if (gradUnits == SVGUnitTypes.SVG_UNIT_TYPE_UNKNOWN)
- gradUnits = linear.getGradientUnits().getBaseVal();
- // spread: pad (normal), reflect, repeat
- spread = linear.getSpreadMethod().getBaseVal();
- if (gradUnits == SVGUnitTypes.SVG_UNIT_TYPE_USERSPACEONUSE) {
- if (area instanceof SVGTransformable) {
- SVGTransformable tf = (SVGTransformable) area;
- double x1, y1, x2, y2;
- x1 = ax1.getBaseVal().getValue();
- y1 = -ay1.getBaseVal().getValue();
- x2 = ax2.getBaseVal().getValue();
- y2 = -ay2.getBaseVal().getValue();
- SVGMatrix matrix = tf.getScreenCTM();
- if(transform != null)
- matrix = matrix.multiply(transform);
- double oldx = x1;
- x1 = matrix.getA() * x1 + matrix.getC() * y1 +
- matrix.getE();
- y1 = matrix.getB() * oldx + matrix.getD() * y1 -
- matrix.getF();
- oldx = x2;
- x2 = matrix.getA() * x2 + matrix.getC() * y2 +
- matrix.getE();
- y2 = matrix.getB() * oldx + matrix.getD() * y2 -
- matrix.getF();
- theCoords = new Vector();
- if (spread == SVGGradientElement.SVG_SPREADMETHOD_REFLECT) {
- } else if (spread ==
- SVGGradientElement.SVG_SPREADMETHOD_REFLECT) {
- } else {
- theCoords.addElement(
- new Double(currentXPosition / 1000f + x1));
- theCoords.addElement(
- new Double(currentYPosition / 1000f + y1));
- theCoords.addElement(
- new Double(currentXPosition / 1000f + x2));
- theCoords.addElement(
- new Double(currentYPosition / 1000f + y2));
- }
- }
- } else if (area instanceof GraphicElement) {
- SVGRect rect = ((GraphicElement) area).getBBox();
- if (rect != null) {
- theCoords = new Vector();
- SVGLength val;
- val = ax1.getBaseVal();
- if (val.getUnitType() ==
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
- SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
- theCoords.addElement(
- new Double(currentXPosition / 1000f +
- rect.getX() +
- val.getValue() * rect.getWidth()));
- } else {
- theCoords.addElement(
- new Double(currentXPosition / 1000f +
- val.getValue()));
- }
- val = ay1.getBaseVal();
- if (val.getUnitType() ==
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
- SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
- theCoords.addElement(
- new Double(currentYPosition / 1000f -
- rect.getY() -
- val.getValue() * rect.getHeight()));
- } else {
- theCoords.addElement(
- new Double(currentYPosition / 1000f -
- val.getValue()));
- }
- val = ax2.getBaseVal();
- if (val.getUnitType() ==
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
- SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
- theCoords.addElement(
- new Double(currentXPosition / 1000f +
- rect.getX() +
- val.getValue() * rect.getWidth()));
- } else {
- theCoords.addElement(
- new Double(currentXPosition / 1000f +
- val.getValue()));
- }
- val = ay2.getBaseVal();
- if (val.getUnitType() ==
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
- SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
- theCoords.addElement(
- new Double(currentYPosition / 1000f -
- rect.getY() -
- val.getValue() * rect.getHeight()));
- } else {
- theCoords.addElement(
- new Double(currentYPosition / 1000f -
- val.getValue()));
- }
- }
- }
- if (theCoords == null) {
- theCoords = new Vector();
- theCoords.addElement( new Double(currentXPosition / 1000f +
- ax1.getBaseVal().getValue()));
- theCoords.addElement( new Double(currentYPosition / 1000f -
- ay1.getBaseVal().getValue()));
- theCoords.addElement( new Double(currentXPosition / 1000f +
- ax2.getBaseVal().getValue()));
- theCoords.addElement( new Double(currentYPosition / 1000f -
- ay2.getBaseVal().getValue()));
- }
-
- Vector theExtend = new Vector();
- theExtend.addElement(new Boolean(true));
- theExtend.addElement(new Boolean(true));
-
- Vector theDomain = new Vector();
- theDomain.addElement(new Double(0));
- theDomain.addElement(new Double(1));
-
- Vector theEncode = new Vector();
- theEncode.addElement(new Double(0));
- theEncode.addElement(new Double(1));
- theEncode.addElement(new Double(0));
- theEncode.addElement(new Double(1));
-
- Vector theBounds = new Vector();
- theBounds.addElement(new Double(0));
- theBounds.addElement(new Double(1));
-
- Vector theFunctions = new Vector();
-
- NodeList nl = stops;
- Vector someColors = new Vector();
- float lastoffset = 0;
- Vector lastVector = null;
- SVGStopElementImpl stop;
- if (nl.getLength() == 0) {
- // the color should be "none"
- if (fill)
- di.fill = false;
- else
- di.stroke = false;
- return;
- } else if (nl.getLength() == 1) {
- stop = (SVGStopElementImpl) nl.item(0);
- CSSValue cv = stop.getPresentationAttribute("stop-color");
- if (cv == null) {
- // maybe using color
- cv = stop.getPresentationAttribute("color");
- }
- if (cv == null) {
- // problems
- MessageHandler.errorln("no stop-color or color in stop element");
- return;
- }
- PDFColor color = new PDFColor(0, 0, 0);
- if (cv != null &&
- cv.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
- if (((CSSPrimitiveValue) cv).getPrimitiveType() ==
- CSSPrimitiveValue.CSS_RGBCOLOR) {
- RGBColor col =
- ((CSSPrimitiveValue) cv).getRGBColorValue();
- CSSPrimitiveValue val;
- val = col.getRed();
- float red = val.getFloatValue(
- CSSPrimitiveValue.CSS_NUMBER);
- val = col.getGreen();
- float green = val.getFloatValue(
- CSSPrimitiveValue.CSS_NUMBER);
- val = col.getBlue();
- float blue = val.getFloatValue(
- CSSPrimitiveValue.CSS_NUMBER);
- color = new PDFColor(red, green, blue);
- }
- }
- currentStream.write(color.getColorSpaceOut(fill));
- if (fill)
- di.fill = true;
- else
- di.stroke = true;
- return;
- }
- for (int count = 0; count < nl.getLength(); count++) {
- stop = (SVGStopElementImpl) nl.item(count);
- CSSValue cv = stop.getPresentationAttribute("stop-color");
- if (cv == null) {
- // maybe using color
- cv = stop.getPresentationAttribute("color");
- }
- if (cv == null) {
- // problems
- MessageHandler.errorln("no stop-color or color in stop element");
- continue;
- }
- PDFColor color = new PDFColor(0, 0, 0);
- if (cv != null &&
- cv.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
- if (((CSSPrimitiveValue) cv).getPrimitiveType() ==
- CSSPrimitiveValue.CSS_RGBCOLOR) {
- RGBColor col =
- ((CSSPrimitiveValue) cv).getRGBColorValue();
- CSSPrimitiveValue val;
- val = col.getRed();
- float red = val.getFloatValue(
- CSSPrimitiveValue.CSS_NUMBER);
- val = col.getGreen();
- float green = val.getFloatValue(
- CSSPrimitiveValue.CSS_NUMBER);
- val = col.getBlue();
- float blue = val.getFloatValue(
- CSSPrimitiveValue.CSS_NUMBER);
- color = new PDFColor(red, green, blue);
- currentColour = color;
- }
- }
- float offset = stop.getOffset().getBaseVal();
- Vector colVector = color.getVector();
- // create bounds from last to offset
- if (lastVector != null) {
- Vector theCzero = lastVector;
- Vector theCone = colVector;
- PDFFunction myfunc =
- this.pdfDoc.makeFunction(2, theDomain, null,
- theCzero, theCone, 1.0);
- theFunctions.addElement(myfunc);
- }
- lastoffset = offset;
- lastVector = colVector;
- someColors.addElement(color);
- }
- ColorSpace aColorSpace = new ColorSpace(ColorSpace.DEVICE_RGB);
- /* PDFFunction myfunky = this.pdfDoc.makeFunction(3,
- theDomain, null,
- theFunctions, null,
- theEncode);
- PDFShading myShad = null;
- myShad = this.pdfDoc.makeShading(
- 2, aColorSpace,
- null, null, false,
- theCoords, null, myfunky,theExtend);
- PDFPattern myPat = this.pdfDoc.makePattern(2, myShad, null, null, null);*/
- PDFPattern myPat = this.pdfDoc.createGradient(false, aColorSpace,
- someColors, null, theCoords);
- currentStream.write(myPat.getColorSpaceOut(fill));
- if (fill)
- di.fill = true;
- else
- di.stroke = true;
- }
-
- protected void handleRadialGradient(
- SVGRadialGradientElement radial, DrawingInstruction di,
- boolean fill, SVGElement area) {
- // first get all the gradient values
- // if values not present follow the href
- // the gradient units will be where the vals are specified
- SVGAnimatedLength acx, acy, ar, afx, afy;
- short gradUnits = radial.getGradientUnits().getBaseVal();
- NodeList stops = null;
- acx = radial.getCx();
- acy = radial.getCy();
- ar = radial.getR();
- afx = radial.getFx();
- afy = radial.getFy();
- stops = radial.getChildNodes();
- SVGRadialGradientElement ref = (SVGRadialGradientElement) locateDef(
- radial.getHref().getBaseVal(), radial);
- while (ref != null) {
- if (acx == null) {
- acx = ref.getCx();
- gradUnits = ref.getGradientUnits().getBaseVal();
- }
- if (acy == null) {
- acy = ref.getCy();
- }
- if (ar == null) {
- ar = ref.getR();
- }
- if (afx == null) {
- afx = ref.getFx();
- }
- if (afy == null) {
- afy = ref.getFy();
- }
- if (stops.getLength() == 0) {
- stops = ref.getChildNodes();
- }
- ref = (SVGRadialGradientElement) locateDef(
- ref.getHref().getBaseVal(), ref);
- }
- if (acx == null) {
- SVGLength length = new SVGLengthImpl();
- length.newValueSpecifiedUnits(
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0.5f);
- acx = new SVGAnimatedLengthImpl(length);
- }
- if (acy == null) {
- SVGLength length = new SVGLengthImpl();
- length.newValueSpecifiedUnits(
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0.5f);
- acy = new SVGAnimatedLengthImpl(length);
- }
- if (ar == null) {
- SVGLength length = new SVGLengthImpl();
- length.newValueSpecifiedUnits(
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 1);
- ar = new SVGAnimatedLengthImpl(length);
- }
- if (afx == null) {
- SVGLength length = new SVGLengthImpl();
- length.newValueSpecifiedUnits(
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0.5f);
- afx = new SVGAnimatedLengthImpl(length);
- }
- if (afy == null) {
- SVGLength length = new SVGLengthImpl();
- length.newValueSpecifiedUnits(
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE, 0.5f);
- afy = new SVGAnimatedLengthImpl(length);
- }
- ColorSpace aColorSpace = new ColorSpace(ColorSpace.DEVICE_RGB);
- org.w3c.dom.NodeList nl = stops;
- SVGStopElementImpl stop;
- if (nl.getLength() == 0) {
- // the color should be "none"
- if (fill)
- di.fill = false;
- else
- di.stroke = false;
- return;
- } else if (nl.getLength() == 1) {
- stop = (SVGStopElementImpl) nl.item(0);
- CSSValue cv = stop.getPresentationAttribute("stop-color");
- if (cv == null) {
- // maybe using color
- cv = stop.getPresentationAttribute("color");
- }
- if (cv == null) {
- // problems
- MessageHandler.errorln("no stop-color or color in stop element");
- return;
- }
- PDFColor color = new PDFColor(0, 0, 0);
- if (cv != null &&
- cv.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
- if (((CSSPrimitiveValue) cv).getPrimitiveType() ==
- CSSPrimitiveValue.CSS_RGBCOLOR) {
- RGBColor col =
- ((CSSPrimitiveValue) cv).getRGBColorValue();
- CSSPrimitiveValue val;
- val = col.getRed();
- float red = val.getFloatValue(
- CSSPrimitiveValue.CSS_NUMBER);
- val = col.getGreen();
- float green = val.getFloatValue(
- CSSPrimitiveValue.CSS_NUMBER);
- val = col.getBlue();
- float blue = val.getFloatValue(
- CSSPrimitiveValue.CSS_NUMBER);
- color = new PDFColor(red, green, blue);
- }
- }
- currentStream.write(color.getColorSpaceOut(fill));
- if (fill)
- di.fill = true;
- else
- di.stroke = true;
- return;
- }
- Hashtable table = null;
- Vector someColors = new Vector();
- Vector theCoords = null;
- Vector theBounds = new Vector();
- // the coords should be relative to the current object
- // check value types, eg. %
- if (gradUnits == SVGUnitTypes.SVG_UNIT_TYPE_USERSPACEONUSE) {
- if (area instanceof SVGTransformable) {
- SVGTransformable tf = (SVGTransformable) area;
- double x1, y1, x2, y2;
- x1 = acx.getBaseVal().getValue();
- y1 = -acy.getBaseVal().getValue();
- x2 = afx.getBaseVal().getValue();
- y2 = -afy.getBaseVal().getValue();
- SVGMatrix matrix = tf.getScreenCTM();
- double oldx = x1;
- x1 = matrix.getA() * x1 + matrix.getB() * y1 +
- matrix.getE();
- y1 = matrix.getC() * oldx + matrix.getD() * y1 +
- matrix.getF();
- oldx = x2;
- x2 = matrix.getA() * x2 + matrix.getB() * y2 +
- matrix.getE();
- y2 = matrix.getC() * oldx + matrix.getD() * y2 +
- matrix.getF();
- theCoords = new Vector();
- // if(spread == SVGGradientElement.SVG_SPREADMETHOD_REFLECT) {
- // } else if(spread== SVGGradientElement.SVG_SPREADMETHOD_REFLECT) {
- // } else {
- theCoords.addElement(
- new Double(currentXPosition / 1000f + x1));
- // the y val needs to be adjust by 2 * R * rotation
- // depending on if this value is from an x or y coord
- // before transformation
- theCoords.addElement(
- new Double(currentYPosition / 1000f - y1 +
- (matrix.getC() - matrix.getD()) * 2 *
- ar.getBaseVal().getValue()));
- theCoords.addElement(new Double(0));
- theCoords.addElement(
- new Double(currentXPosition / 1000f + x2));
- theCoords.addElement(
- new Double(currentYPosition / 1000f - y2 +
- (matrix.getC() - matrix.getD()) * 2 *
- ar.getBaseVal().getValue()));
- theCoords.addElement(
- new Double(ar.getBaseVal().getValue()));
- // }
- }
- } else if (gradUnits ==
- SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX &&
- area instanceof GraphicElement) {
- SVGRect rect = ((GraphicElement) area).getBBox();
- if (rect != null) {
- theCoords = new Vector();
- SVGLength val;
- val = acx.getBaseVal();
- if (val.getUnitType() ==
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
- SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
- theCoords.addElement(
- new Double(currentXPosition / 1000f +
- rect.getX() +
- val.getValue() * rect.getWidth()));
- } else {
- theCoords.addElement(
- new Double(currentXPosition / 1000f +
- val.getValue()));
- }
- val = acy.getBaseVal();
- if (val.getUnitType() ==
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
- SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
- theCoords.addElement(
- new Double(currentYPosition / 1000f -
- rect.getY() -
- val.getValue() * rect.getHeight()));
- } else {
- theCoords.addElement(
- new Double(currentYPosition / 1000f -
- val.getValue()));
- }
- theCoords.addElement(new Double(0));
- val = afx.getBaseVal();
- if (val.getUnitType() ==
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
- SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
- theCoords.addElement(
- new Double(currentXPosition / 1000f +
- rect.getX() +
- val.getValue() * rect.getWidth()));
- } else {
- theCoords.addElement(
- new Double(currentXPosition / 1000f +
- val.getValue()));
- }
- val = afy.getBaseVal();
- if (val.getUnitType() ==
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
- SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
- theCoords.addElement(
- new Double(currentYPosition / 1000f -
- rect.getY() -
- val.getValue() * rect.getHeight()));
- } else {
- theCoords.addElement(
- new Double(currentYPosition / 1000f -
- val.getValue()));
- }
- val = ar.getBaseVal();
- if (val.getUnitType() ==
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE || gradUnits ==
- SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
- theCoords.addElement(
- new Double(val.getValue() * rect.getHeight()));
- } else {
- theCoords.addElement(new Double(val.getValue()));
- }
- }
- }
- if (theCoords == null) {
- // percentage values are expressed according to the viewport.
- SVGElement vp =
- ((GraphicElement) area).getNearestViewportElement();
- if (area instanceof GraphicElement) {
- SVGRect rect = ((GraphicElement) area).getBBox();
- if (rect != null) {
- theCoords = new Vector();
- SVGLength val = acx.getBaseVal();
- if (val.getUnitType() ==
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE ||
- gradUnits ==
- SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
- theCoords.addElement(
- new Double(currentXPosition / 1000f +
- rect.getX() +
- val.getValue() * rect.getWidth()));
- } else {
- theCoords.addElement(
- new Double(currentXPosition / 1000f +
- val.getValue()));
- }
- val = acy.getBaseVal();
- if (val.getUnitType() ==
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE ||
- gradUnits ==
- SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
- theCoords.addElement(
- new Double(currentYPosition / 1000f -
- rect.getY() -
- val.getValue() * rect.getHeight()));
- } else {
- theCoords.addElement(
- new Double(currentYPosition / 1000f -
- val.getValue()));
- }
- theCoords.addElement(new Double(0));
- val = afx.getBaseVal();
- if (val.getUnitType() ==
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE ||
- gradUnits ==
- SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
- theCoords.addElement(
- new Double(currentXPosition / 1000f +
- rect.getX() +
- val.getValue() * rect.getWidth()));
- } else {
- theCoords.addElement(
- new Double(currentXPosition / 1000f +
- val.getValue()));
- }
- val = afy.getBaseVal();
- if (val.getUnitType() ==
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE ||
- gradUnits ==
- SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
- theCoords.addElement(
- new Double(currentYPosition / 1000f -
- rect.getY() -
- val.getValue() * rect.getHeight()));
- } else {
- theCoords.addElement(
- new Double(currentYPosition / 1000f -
- val.getValue()));
- }
- val = ar.getBaseVal();
- if (val.getUnitType() ==
- SVGLength.SVG_LENGTHTYPE_PERCENTAGE ||
- gradUnits ==
- SVGUnitTypes.SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
- theCoords.addElement( new Double(val.getValue() *
- rect.getHeight()));
- } else {
- theCoords.addElement(new Double(val.getValue()));
- }
- }
- }
- }
- if (theCoords == null) {
- theCoords = new Vector();
- theCoords.addElement( new Double(currentXPosition / 1000f +
- acx.getBaseVal().getValue()));
- theCoords.addElement( new Double(currentYPosition / 1000f -
- acy.getBaseVal().getValue()));
- theCoords.addElement(new Double(0));
- theCoords.addElement( new Double(currentXPosition / 1000f +
- afx.getBaseVal().getValue())); // Fx
- theCoords.addElement(
- new Double(currentYPosition / 1000f -
- afy.getBaseVal().getValue())); // Fy
- theCoords.addElement(
- new Double(ar.getBaseVal().getValue()));
- }
- float lastoffset = 0;
- for (int count = 0; count < nl.getLength(); count++) {
- stop = (SVGStopElementImpl) nl.item(count);
- CSSValue cv = stop.getPresentationAttribute("stop-color");
- if (cv == null) {
- // maybe using color
- cv = stop.getPresentationAttribute("color");
- }
- if (cv == null) {
- // problems
- MessageHandler.errorln("no stop-color or color in stop element");
- continue;
- }
- PDFColor color = new PDFColor(0, 0, 0);
- if (cv != null &&
- cv.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
- if (((CSSPrimitiveValue) cv).getPrimitiveType() ==
- CSSPrimitiveValue.CSS_RGBCOLOR) {
- RGBColor col =
- ((CSSPrimitiveValue) cv).getRGBColorValue();
- CSSPrimitiveValue val;
- val = col.getRed();
- float red = val.getFloatValue(
- CSSPrimitiveValue.CSS_NUMBER);
- val = col.getGreen();
- float green = val.getFloatValue(
- CSSPrimitiveValue.CSS_NUMBER);
- val = col.getBlue();
- float blue = val.getFloatValue(
- CSSPrimitiveValue.CSS_NUMBER);
- color = new PDFColor(red, green, blue);
- }
- }
- float offset = stop.getOffset().getBaseVal();
- // create bounds from last to offset
- lastoffset = offset;
- someColors.addElement(color);
- }
- PDFPattern myPat = this.pdfDoc.createGradient(true, aColorSpace,
- someColors, theBounds, theCoords);
-
- currentStream.write(myPat.getColorSpaceOut(fill));
- if (fill)
- di.fill = true;
- else
- di.stroke = true;
- }
-
- /*
- * This sets up the style for drawing objects.
- * Should only set style for elements that have changes.
- *
- */
- // need mask drawing
- class DrawingInstruction {
- boolean stroke = false;
- boolean nonzero = false; // non-zero fill rule "f*", "B*" operator
- boolean fill = false;
- int linecap = 0; // butt
- int linejoin = 0; // miter
- int miterwidth = 8;
- }
- protected DrawingInstruction applyStyle(SVGElement area,
- SVGStylable style) {
- DrawingInstruction di = new DrawingInstruction();
- CSSValue sp;
- sp = style.getPresentationAttribute("fill");
- if (sp != null) {
- if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
- if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
- CSSPrimitiveValue.CSS_RGBCOLOR) {
- RGBColor col =
- ((CSSPrimitiveValue) sp).getRGBColorValue();
- CSSPrimitiveValue val;
- val = col.getRed();
- float red = val.getFloatValue(
- CSSPrimitiveValue.CSS_NUMBER);
- val = col.getGreen();
- float green = val.getFloatValue(
- CSSPrimitiveValue.CSS_NUMBER);
- val = col.getBlue();
- float blue = val.getFloatValue(
- CSSPrimitiveValue.CSS_NUMBER);
- PDFColor fillColour = new PDFColor(red, green, blue);
- currentColour = fillColour;
- currentStream.write(fillColour.getColorSpaceOut(true));
- di.fill = true;
- } else if ( ((CSSPrimitiveValue) sp).getPrimitiveType() ==
- CSSPrimitiveValue.CSS_URI) {
- // gradient
- String str = ((CSSPrimitiveValue) sp).getCssText();
- handleGradient(str, di, true, area);
- } else if ( ((CSSPrimitiveValue) sp).getPrimitiveType() ==
- CSSPrimitiveValue.CSS_STRING) {
- String str = ((CSSPrimitiveValue) sp).getCssText();
- if (str.equals("none")) {
- di.fill = false;
- } else if (str.equals("currentColor")) {
- currentStream.write(
- currentColour.getColorSpaceOut(true));
- di.fill = true;
- // } else {
- // handleGradient(str, true, area);
- }
- }
- }
- } else {
- PDFColor fillColour = new PDFColor(0, 0, 0);
- currentStream.write(fillColour.getColorSpaceOut(true));
- }
- sp = style.getPresentationAttribute("fill-rule");
- if (sp != null) {
- if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
- if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
- CSSPrimitiveValue.CSS_STRING) {
- if (sp.getCssText().equals("nonzero")) {
- di.nonzero = true;
- }
- }
- }
- } else {
- }
- sp = style.getPresentationAttribute("stroke");
- if (sp != null) {
- if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
- if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
- CSSPrimitiveValue.CSS_RGBCOLOR) {
- RGBColor col =
- ((CSSPrimitiveValue) sp).getRGBColorValue();
- CSSPrimitiveValue val;
- val = col.getRed();
- float red = val.getFloatValue(
- CSSPrimitiveValue.CSS_NUMBER);
- val = col.getGreen();
- float green = val.getFloatValue(
- CSSPrimitiveValue.CSS_NUMBER);
- val = col.getBlue();
- float blue = val.getFloatValue(
- CSSPrimitiveValue.CSS_NUMBER);
- PDFColor fillColour = new PDFColor(red, green, blue);
- currentStream.write(
- fillColour.getColorSpaceOut(false));
- di.stroke = true;
- } else if ( ((CSSPrimitiveValue) sp).getPrimitiveType() ==
- CSSPrimitiveValue.CSS_URI) {
- // gradient
- String str = ((CSSPrimitiveValue) sp).getCssText();
- handleGradient(str, di, false, area);
- } else if ( ((CSSPrimitiveValue) sp).getPrimitiveType() ==
- CSSPrimitiveValue.CSS_STRING) {
- String str = ((CSSPrimitiveValue) sp).getCssText();
- if (str.equals("none")) {
- di.stroke = false;
- // } else {
- // handleGradient(str, false, area);
- }
- }
- }
- } else {
- PDFColor fillColour = new PDFColor(0, 0, 0);
- currentStream.write(fillColour.getColorSpaceOut(false));
- }
- sp = style.getPresentationAttribute("stroke-linecap");
- if (sp != null) {
- if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
- if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
- CSSPrimitiveValue.CSS_STRING) {
- String str = sp.getCssText();
- // butt, round ,square
- if (str.equals("butt")) {
- currentStream.write(0 + " J\n");
- } else if (str.equals("round")) {
- currentStream.write(1 + " J\n");
- } else if (str.equals("square")) {
- currentStream.write(2 + " J\n");
- }
- }
- }
- } else {
- }
- sp = style.getPresentationAttribute("stroke-linejoin");
- if (sp != null) {
- if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
- if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
- CSSPrimitiveValue.CSS_STRING) {
- String str = sp.getCssText();
- if (str.equals("miter")) {
- currentStream.write(0 + " j\n");
- } else if (str.equals("round")) {
- currentStream.write(1 + " j\n");
- } else if (str.equals("bevel")) {
- currentStream.write(2 + " j\n");
- }
- }
- }
- } else {
- }
- sp = style.getPresentationAttribute("stroke-miterlimit");
- if (sp != null) {
- if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
- float width;
- width = ((CSSPrimitiveValue) sp).getFloatValue(
- CSSPrimitiveValue.CSS_PT);
- PDFNumber pdfNumber = new PDFNumber();
- currentStream.write(pdfNumber.doubleOut(width) + " M\n");
- }
- } else {
- }
- sp = style.getPresentationAttribute("stroke-width");
- if (sp != null) {
- if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
- float width;
- width = ((CSSPrimitiveValue) sp).getFloatValue(
- CSSPrimitiveValue.CSS_PT);
- PDFNumber pdfNumber = new PDFNumber();
- currentStream.write(pdfNumber.doubleOut(width) + " w\n");
- }
- }
- sp = style.getPresentationAttribute("stroke-dasharray");
- if (sp != null) {
- if (sp.getValueType() == CSSValue.CSS_VALUE_LIST) {
- currentStream.write("[ ");
- CSSValueList list = (CSSValueList) sp;
- for (int count = 0; count < list.getLength(); count++) {
- CSSValue val = list.item(count);
- if (val.getValueType() ==
- CSSValue.CSS_PRIMITIVE_VALUE) {
- currentStream.write(
- ((CSSPrimitiveValue) val).getFloatValue(
- CSSPrimitiveValue.CSS_NUMBER) + " ");
- }
- }
- currentStream.write("] ");
- sp = style.getPresentationAttribute("stroke-dashoffset");
- if (sp != null && sp.getValueType() ==
- CSSValue.CSS_PRIMITIVE_VALUE) {
- currentStream.write(
- ((CSSPrimitiveValue) sp).getFloatValue(
- CSSPrimitiveValue.CSS_NUMBER) + " d\n");
- } else {
- currentStream.write("0 d\n");
- }
- }
- }
- sp = style.getPresentationAttribute("clip-path");
- if (sp != null) {
- String clipurl;
- if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
- if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
- CSSPrimitiveValue.CSS_URI) {
- clipurl = ((CSSPrimitiveValue) sp).getCssText();
- if (clipurl.startsWith("url(")) {
- int b1 = clipurl.indexOf("(");
- int b2 = clipurl.indexOf(")");
- clipurl = clipurl.substring(b1 + 1, b2);
- }
- // get def of mask and set mask
- SVGElement graph = null;
- graph = locateDef(clipurl, area);
- if (graph != null) {
- MessageHandler.logln("clip path: " + graph);
- // render the clip path elements and make it the clip
- // renderElement(svgarea, graph, posx, posy);
- }
- }
- }
- }
- sp = style.getPresentationAttribute("mask");
- if (sp != null) {
- String maskurl;
- if (sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
- if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
- CSSPrimitiveValue.CSS_URI) {
- maskurl = ((CSSPrimitiveValue) sp).getCssText();
- // System.out.println("mask: " + maskurl);
- // get def of mask and set mask
- if (maskurl.startsWith("url(")) {
- int b1 = maskurl.indexOf("(");
- int b2 = maskurl.indexOf(")");
- maskurl = maskurl.substring(b1 + 1, b2);
- }
- SVGElement graph = null;
- graph = locateDef(maskurl, area);
- if (graph != null) {
- MessageHandler.logln("mask: " + graph);
- // SVGElement parent = graph.getGraphicParent();
- // graph.setParent(area);
- // renderElement(svgarea, graph, posx, posy);
- // graph.setParent(parent);
- }
- }
- }
- }
- return di;
- }
-
- protected void applyTransform(SVGAnimatedTransformList trans) {
- PDFNumber pdfNumber = new PDFNumber();
- SVGTransformList list = trans.getBaseVal();
- for (int count = 0; count < list.getNumberOfItems(); count++) {
- SVGMatrix matrix =
- ((SVGTransform) list.getItem(count)).getMatrix();
- currentStream.write(pdfNumber.doubleOut(matrix.getA(), 5) +
- " " + pdfNumber.doubleOut(matrix.getB(), 5) + " " +
- pdfNumber.doubleOut(matrix.getC(), 5) + " " +
- pdfNumber.doubleOut(matrix.getD(), 5) + " " +
- pdfNumber.doubleOut(matrix.getE(), 5) + " " +
- pdfNumber.doubleOut(matrix.getF(), 5) + " cm\n");
- }
- }
-
- /**
- * Main rendering selection.
- * This applies any transform and style and then calls the appropriate
- * rendering method depending on the type of element.
- */
- public void renderElement(SVGElement area, int posx, int posy) {
- int x = posx;
- int y = posy;
- // CSSStyleDeclaration style = null;
- // if(area instanceof SVGStylable)
- // style = ((SVGStylable)area).getStyle();
- DrawingInstruction di = null;
-
- currentStream.write("q\n");
- if (area instanceof SVGTransformable) {
- SVGTransformable tf = (SVGTransformable) area;
- SVGAnimatedTransformList trans = tf.getTransform();
- if (trans != null) {
- applyTransform(trans);
- }
- }
-
- if (area instanceof SVGStylable) {
- di = applyStyle(area, (SVGStylable) area);
- }
-
- if (area instanceof SVGRectElement) {
- SVGRectElement rg = (SVGRectElement) area;
- float rectx = rg.getX().getBaseVal().getValue();
- float recty = rg.getY().getBaseVal().getValue();
- float rx = rg.getRx().getBaseVal().getValue();
- float ry = rg.getRy().getBaseVal().getValue();
- float rw = rg.getWidth().getBaseVal().getValue();
- float rh = rg.getHeight().getBaseVal().getValue();
- addRect(rectx, recty, rw, rh, rx, ry, di);
- } else if (area instanceof SVGLineElement) {
- SVGLineElement lg = (SVGLineElement) area;
- float x1 = lg.getX1().getBaseVal().getValue();
- float y1 = lg.getY1().getBaseVal().getValue();
- float x2 = lg.getX2().getBaseVal().getValue();
- float y2 = lg.getY2().getBaseVal().getValue();
- addLine(x1, y1, x2, y2, di);
- } else if (area instanceof SVGTextElementImpl) {
- // currentStream.add("q\n");
- // currentStream.add(1 + " " + 0 + " " + 0 + " " + 1 + " " + 0 + " " + 0 + " cm\n");
- currentStream.write("BT\n");
- renderText((SVGTextElementImpl) area, 0, 0, di);
- currentStream.write("ET\n");
- // currentStream.add("Q\n");
- } else if (area instanceof SVGCircleElement) {
- SVGCircleElement cg = (SVGCircleElement) area;
- float cx = cg.getCx().getBaseVal().getValue();
- float cy = cg.getCy().getBaseVal().getValue();
- float r = cg.getR().getBaseVal().getValue();
- addCircle(cx, cy, r, di);
- } else if (area instanceof SVGEllipseElement) {
- SVGEllipseElement cg = (SVGEllipseElement) area;
- float cx = cg.getCx().getBaseVal().getValue();
- float cy = cg.getCy().getBaseVal().getValue();
- float rx = cg.getRx().getBaseVal().getValue();
- float ry = cg.getRy().getBaseVal().getValue();
- addEllipse(cx, cy, rx, ry, di);
- } else if (area instanceof SVGPathElementImpl) {
- addPath(((SVGPathElementImpl) area).pathElements, posx,
- posy, di);
- } else if (area instanceof SVGPolylineElementImpl) {
- addPolyline(((SVGPolylineElementImpl) area).points, di, false);
- } else if (area instanceof SVGPolygonElementImpl) {
- addPolyline(((SVGPolygonElementImpl) area).points, di, true);
- } else if (area instanceof SVGGElementImpl) {
- renderGArea((SVGGElementImpl) area, x, y);
- } else if (area instanceof SVGUseElementImpl) {
- SVGUseElementImpl ug = (SVGUseElementImpl) area;
- String ref = ug.link;
- // ref = ref.substring(1, ref.length());
- SVGElement graph = null;
- graph = locateDef(ref, ug);
- if (graph != null) {
- // probably not the best way to do this, should be able
- // to render without the style being set.
- // SVGElement parent = graph.getGraphicParent();
- // graph.setParent(area);
- // need to clip (if necessary) to the use area
- // the style of the linked element is as if it was
- // a direct descendant of the use element.
-
- // scale to the viewBox
-
- if (graph instanceof SVGSymbolElement) {
- currentStream.write("q\n");
- SVGSymbolElement symbol = (SVGSymbolElement) graph;
- SVGRect view = symbol.getViewBox().getBaseVal();
- float usex = ug.getX().getBaseVal().getValue();
- float usey = ug.getY().getBaseVal().getValue();
- float usewidth = ug.getWidth().getBaseVal().getValue();
- float useheight =
- ug.getHeight().getBaseVal().getValue();
- float scaleX;
- float scaleY;
- scaleX = usewidth / view.getWidth();
- scaleY = useheight / view.getHeight();
- currentStream.write(usex + " " + usey + " m\n");
- currentStream.write((usex + usewidth) + " " +
- usey + " l\n");
- currentStream.write((usex + usewidth) + " " +
- (usey + useheight) + " l\n");
- currentStream.write(usex + " " +
- (usey + useheight) + " l\n");
- currentStream.write("h\n");
- currentStream.write("W\n");
- currentStream.write("n\n");
- currentStream.write(scaleX + " 0 0 " + scaleY +
- " " + usex + " " + usey + " cm\n");
- renderSymbol(symbol, posx, posy);
- currentStream.write("Q\n");
- } else {
- renderElement(graph, posx, posy);
- }
- // graph.setParent(parent);
- }
- else {
- MessageHandler.logln("Use Element: " + ref + " not found");
- }
- } else if (area instanceof SVGImageElementImpl) {
- SVGImageElementImpl ig = (SVGImageElementImpl) area;
- renderImage(ig.link, ig.x, ig.y, ig.width, ig.height);
- } else if (area instanceof SVGSVGElement) {
- currentStream.write("q\n");
- SVGSVGElement svgel = (SVGSVGElement) area;
- float svgx = 0;
- if (svgel.getX() != null)
- svgx = svgel.getX().getBaseVal().getValue();
- float svgy = 0;
- if (svgel.getY() != null)
- svgy = svgel.getY().getBaseVal().getValue();
- currentStream.write(1 + " 0 0 " + 1 + " " + svgx + " " +
- svgy + " cm\n");
- renderSVG(svgel, (int)(x + 1000 * svgx),
- (int)(y + 1000 * svgy));
- currentStream.write("Q\n");
- // } else if (area instanceof SVGSymbolElement) {
- // 'symbol' element is not rendered (except by 'use')
- } else if (area instanceof SVGAElement) {
- SVGAElement ael = (SVGAElement) area;
- org.w3c.dom.NodeList nl = ael.getChildNodes();
- for (int count = 0; count < nl.getLength(); count++) {
- org.w3c.dom.Node n = nl.item(count);
- if (n instanceof SVGElement) {
- if (n instanceof GraphicElement) {
- SVGRect rect = ((GraphicElement) n).getBBox();
- if (rect != null) {
- /* currentAnnotList = this.pdfDoc.makeAnnotList();
- currentPage.setAnnotList(currentAnnotList);
- String dest = linkSet.getDest();
- int linkType = linkSet.getLinkType();
- currentAnnotList.addLink(
- this.pdfDoc.makeLink(lrect.getRectangle(), dest, linkType));
- currentAnnotList = null;
- */ }
- }
- renderElement((SVGElement) n, posx, posy);
- }
- }
- } else if (area instanceof SVGSwitchElement) {
- handleSwitchElement(posx, posy, (SVGSwitchElement) area);
- }
- // should be done with some cleanup code, so only
- // required values are reset.
- currentStream.write("Q\n");
- }
-
- /**
- * Todo: underline, linethrough, textpath
- */
- public void renderText(SVGTextElementImpl tg, float x, float y,
- DrawingInstruction di) {
- SVGTextRenderer str = new SVGTextRenderer(fontState, tg, x, y);
- str.renderText(tg);
- }
-
- /**
- * Adds an svg string to the output.
- * This handles the escaping of special pdf chars and deals with
- * whitespace.
- */
- protected float addSVGStr(FontState fs, float currentX, String str, boolean spacing) {
- boolean inbetween = false;
- boolean addedspace = false;
- StringBuffer pdf = new StringBuffer();
- Font f = (Font) fs.getFontInfo().getFonts().get(fs.getFontName());
- boolean useMultiByte = false;
- if (f instanceof CIDFont)
- useMultiByte=true;
- String startText = useMultiByte ? "<" : "(";
- String endText = useMultiByte ? ">" : ")";
-
- pdf.append(startText);
-
- if ( useMultiByte ) {
- String enc = ((CIDFont)f).getCharEncoding();
- try {
- str = new String(str.getBytes(enc), "8859_1");
- } catch (java.io.UnsupportedEncodingException ex) { }
- }
-
- for (int i = 0; i < str.length(); i++) {
- char ch = fs.mapChar(str.charAt(i));
- if ( useMultiByte ) {
- switch ( str.charAt( i ))
- {
- case '\t':
- case ' ':
- if (spacing) {
- pdf = pdf.append( endText );
-
- pdf = pdf.append( startText );
- currentX += fs.width(fs.mapChar(' ')) / 1000f;
- } else {
- if (inbetween && !addedspace) {
- addedspace = true;
- pdf = pdf.append( endText );
- pdf = pdf.append(" ");
- pdf = pdf.append(Float.toString(-fs.width(fs.mapChar(' '))));
- pdf = pdf.append(" ");
- pdf = pdf.append( startText );
- currentX += fs.width(fs.mapChar(' ')) / 1000f;
- }
- }
- break;
- case '\n':
- case '\r':
- if (spacing) {
- pdf = pdf.append( endText );
- pdf = pdf.append(" ");
- pdf = pdf.append(Float.toString(-fs.width(fs.mapChar(' '))));
- pdf = pdf.append(" ");
- pdf = pdf.append( startText );
- currentX += fs.width(fs.mapChar(' ')) / 1000f;
- }
- break;
- default:
- pdf = pdf.append(getUnicodeString( ch));
- currentX += fs.width(ch) / 1000f;
- inbetween = true;
- addedspace = false;
- break;
- }
- } else if (ch > 127) {
- pdf = pdf.append("\\");
- pdf = pdf.append(Integer.toOctalString((int) ch));
- currentX += fs.width(ch) / 1000f;
- inbetween = true;
- addedspace = false;
- } else {
- switch (ch) {
- case '(' :
- pdf = pdf.append("\\(");
- currentX += fs.width(ch) / 1000f;
- inbetween = true;
- addedspace = false;
- break;
- case ')' :
- pdf = pdf.append("\\)");
- currentX += fs.width(ch) / 1000f;
- inbetween = true;
- addedspace = false;
- break;
- case '\\' :
- pdf = pdf.append("\\\\");
- currentX += fs.width(ch) / 1000f;
- inbetween = true;
- addedspace = false;
- break;
- case '\t':
- case ' ':
- if (spacing) {
- pdf = pdf.append(' ');
- currentX += fs.width(' ') / 1000f;
- } else {
- if (inbetween && !addedspace) {
- addedspace = true;
- pdf = pdf.append(' ');
- currentX += fs.width(' ') / 1000f;
- }
- }
- break;
- case '\n':
- case '\r':
- if (spacing) {
- pdf = pdf.append(' ');
- currentX += fs.width(' ') / 1000f;
- }
- break;
- default:
- addedspace = false;
- pdf = pdf.append(ch);
- currentX += fs.width(ch) / 1000f;
- inbetween = true;
- break;
- }
- }
- }
- pdf.append(endText);
- currentStream.write(pdf.toString());
- return currentX;
- }
-
- /**
- * Locates a defined element in an svg document.
- * Either gets the element defined by its "id" in the current
- * SVGDocument, or if the uri reference is to an external
- * document it loads the document and returns the element.
- */
- protected SVGElement locateDef(String ref, SVGElement currentElement) {
- int pos;
- ref = ref.trim();
- pos = ref.indexOf("#");
- if (pos == 0) {
- // local doc
- Document doc = currentElement.getOwnerDocument();
- Element ele =
- doc.getElementById(ref.substring(1, ref.length()));
- if (ele instanceof SVGElement) {
- return (SVGElement) ele;
- }
- } else if (pos != -1) {
- String href = ref.substring(0, pos);
- if (href.indexOf(":") == -1) {
- href = "file:" + href;
- }
- try {
- // this is really only to get a cached svg image
- FopImage img = FopImageFactory.Make(href);
- if (img instanceof SVGImage) {
- SVGDocument doc = ((SVGImage) img).getSVGDocument();
- Element ele = doc.getElementById(
- ref.substring(pos + 1, ref.length()));
- if (ele instanceof SVGElement) {
- return (SVGElement) ele;
- }
- }
- } catch (Exception e) {
- MessageHandler.errorln(e.toString());
- }
- }
- return null;
- }
-
- /**
- * This class is used to handle the rendering of svg text.
- * This is so that it can deal with the recursive rendering
- * of text markup, while keeping track of the state and position.
- */
- class SVGTextRenderer {
- FontState fs;
- String transstr;
- float currentX;
- float currentY;
- float baseX;
- float baseY;
- SVGMatrix matrix;
- float x;
- float y;
-
- SVGTextRenderer(FontState fontState, SVGTextElementImpl tg,
- float x, float y) {
- fs = fontState;
-
- PDFNumber pdfNumber = new PDFNumber();
- SVGTransformList trans = tg.getTransform().getBaseVal();
- matrix = trans.consolidate().getMatrix();
- transstr = (pdfNumber.doubleOut(matrix.getA()) + " " +
- pdfNumber.doubleOut(matrix.getB()) + " " +
- pdfNumber.doubleOut(matrix.getC()) + " " +
- pdfNumber.doubleOut(-matrix.getD()) + " ");
- this.x = x;
- this.y = y;
- }
-
- void renderText(SVGTextElementImpl te) {
- float xoffset = 0;
-
- if (te.anchor.getEnum() != TextAnchor.START) {
- // This is a bit of a hack: The code below will update
- // the current position, so all I have to do is to
- // prevent that the code will write anything to the
- // PDF stream...
- StringWriter oldStream = currentStream;
- currentStream = new StringWriter ();
- FontState saveFS = fs;
- _renderText (te, 0f, true);
-
- float width = currentX - te.x;
- currentStream = oldStream;
- fs = saveFS;
-
- if (te.anchor.getEnum() == TextAnchor.END) {
- xoffset = -width;
- } else if (te.anchor.getEnum() == TextAnchor.MIDDLE) {
- xoffset = -width/2;
- }
- }
-
- _renderText (te, xoffset, false);
- }
-
- void _renderText(SVGTextElementImpl te, float xoffset, boolean getWidthOnly) {
- DrawingInstruction di = applyStyle(te, te);
- if (di.fill) {
- if (di.stroke) {
- currentStream.write("2 Tr\n");
- } else {
- currentStream.write("0 Tr\n");
- }
- } else if (di.stroke) {
- currentStream.write("1 Tr\n");
- }
- updateFont(te, fs);
-
- float tx = te.x;
- float ty = te.y;
- currentX = x + tx + xoffset;
- currentY = y + ty;
- baseX = currentX;
- baseY = currentY;
- NodeList nodel = te.getChildNodes();
- // Vector list = te.textList;
- for (int count = 0; count < nodel.getLength(); count++) {
- Object o = nodel.item(count);
- applyStyle(te, te);
- if (o instanceof CharacterData) {
- String str = ((CharacterData) o).getData();
- currentStream.write(transstr +
- (currentX + matrix.getE()) + " " +
- (baseY + matrix.getF()) + " Tm [" );
- boolean spacing = "preserve".equals(te.getXMLspace());
- currentX = addSVGStr(fs, currentX, str, spacing);
- currentStream.write(" ] TJ\n");
- } else if (o instanceof SVGTextPathElementImpl) {
- SVGTextPathElementImpl tpg = (SVGTextPathElementImpl) o;
- String ref = tpg.str;
- SVGElement graph = null;
- graph = locateDef(ref, tpg);
- if (graph instanceof SVGPathElementImpl) {
- // probably not the best way to do this, should be able
- // to render without the style being set.
- // GraphicImpl parent = graph.getGraphicParent();
- // graph.setParent(tpg);
- // set text path??
- // how should this work
- // graph.setParent(parent);
- }
- } else if (o instanceof SVGTRefElementImpl) {
- SVGTRefElementImpl trg = (SVGTRefElementImpl) o;
- String ref = trg.ref;
- SVGElement element = locateDef(ref, trg);
- if (element instanceof SVGTextElementImpl) {
- // GraphicImpl parent = graph.getGraphicParent();
- // graph.setParent(trg);
- SVGTextElementImpl tele =
- (SVGTextElementImpl) element;
- // the style should be from tele, but it needs to be placed as a child
- // of trg to work
- di = applyStyle(trg, trg);
- if (di.fill) {
- if (di.stroke) {
- currentStream.write("2 Tr\n");
- } else {
- currentStream.write("0 Tr\n");
- }
- } else if (di.stroke) {
- currentStream.write("1 Tr\n");
- }
- boolean changed = false;
- FontState oldfs = fs;
- changed = updateFont(te, fs);
- NodeList nl = tele.getChildNodes();
- boolean spacing =
- "preserve".equals(trg.getXMLspace());
- renderTextNodes(spacing, nl,
- trg.getX().getBaseVal(),
- trg.getY().getBaseVal(),
- trg.getDx().getBaseVal(),
- trg.getDy().getBaseVal());
-
- if (changed) {
- fs = oldfs;
- currentStream.write("/" +
- fs.getFontName() + " " +
- fs.getFontSize() / 1000f + " Tf\n");
- }
- // graph.setParent(parent);
- }
- } else if (o instanceof SVGTSpanElementImpl) {
- SVGTSpanElementImpl tsg = (SVGTSpanElementImpl) o;
- applyStyle(tsg, tsg);
- boolean changed = false;
- FontState oldfs = fs;
- changed = updateFont(tsg, fs);
- boolean spacing = "preserve".equals(tsg.getXMLspace());
- renderTextNodes(spacing, tsg.getChildNodes(),
- tsg.getX().getBaseVal(),
- tsg.getY().getBaseVal(),
- tsg.getDx().getBaseVal(),
- tsg.getDy().getBaseVal());
-
- // currentX += fs.width(' ') / 1000f;
- if (changed) {
- fs = oldfs;
- currentStream.write("/" + fs.getFontName() +
- " " + fs.getFontSize() / 1000f + " Tf\n");
- }
- } else {
- MessageHandler.errorln("Error: unknown text element " + o);
- }
- }
- }
-
- void renderTextNodes(boolean spacing, NodeList nl,
- SVGLengthList xlist, SVGLengthList ylist,
- SVGLengthList dxlist, SVGLengthList dylist) {
- boolean inbetween = false;
- boolean addedspace = false;
- int charPos = 0;
- float xpos = currentX;
- float ypos = currentY;
-
- for (int count = 0; count < nl.getLength(); count++) {
- Node n = nl.item(count);
- if (n instanceof CharacterData) {
- StringBuffer pdf = new StringBuffer();
- String str = ((CharacterData) n).getData();
- for (int i = 0; i < str.length(); i++) {
- char ch = str.charAt(i);
- xpos = currentX;
- ypos = currentY;
- if (ylist.getNumberOfItems() > charPos) {
- ypos = baseY + (ylist.getItem(charPos)).
- getValue();
- }
- if (dylist.getNumberOfItems() > charPos) {
- ypos = ypos + (dylist.getItem(charPos)).
- getValue();
- }
- if (xlist.getNumberOfItems() > charPos) {
- xpos = baseX + (xlist.getItem(charPos)).
- getValue();
- }
- if (dxlist.getNumberOfItems() > charPos) {
- xpos = xpos + (dxlist.getItem(charPos)).
- getValue();
- }
- if (ch > 127) {
- pdf = pdf.append(transstr +
- (xpos + matrix.getE()) + " " +
- (ypos + matrix.getF()) + " Tm " +
- "(" + "\\" +
- Integer.toOctalString((int) ch) +
- ") Tj\n");
- currentX = xpos + fs.width(ch) / 1000f;
- currentY = ypos;
- charPos++;
- inbetween = true;
- addedspace = false;
- } else {
- switch (ch) {
- case '(' :
- pdf = pdf.append(transstr +
- (xpos + matrix.getE()) +
- " " + (ypos +
- matrix.getF()) + " Tm " +
- "(" + "\\(" + ") Tj\n");
- currentX = xpos + fs.width(ch) / 1000f;
- currentY = ypos;
- charPos++;
- inbetween = true;
- addedspace = false;
- break;
- case ')' :
- pdf = pdf.append(transstr +
- (xpos + matrix.getE()) +
- " " + (ypos +
- matrix.getF()) + " Tm " +
- "(" + "\\)" + ") Tj\n");
- currentX = xpos + fs.width(ch) / 1000f;
- currentY = ypos;
- charPos++;
- inbetween = true;
- addedspace = false;
- break;
- case '\\' :
- pdf = pdf.append(transstr +
- (xpos + matrix.getE()) +
- " " + (ypos +
- matrix.getF()) + " Tm " +
- "(" + "\\\\" + ") Tj\n");
- currentX = xpos + fs.width(ch) / 1000f;
- currentY = ypos;
- charPos++;
- inbetween = true;
- addedspace = false;
- break;
- case '\t':
- case ' ':
- if (spacing) {
- currentX = xpos + fs.width(' ') /
- 1000f;
- currentY = ypos;
- charPos++;
- } else {
- if (inbetween && !addedspace) {
- addedspace = true;
- currentX = xpos + fs.width(' ')
- / 1000f;
- currentY = ypos;
- charPos++;
- }
- }
- break;
- case '\n':
- case '\r':
- if (spacing) {
- currentX = xpos + fs.width(' ') /
- 1000f;
- currentY = ypos;
- charPos++;
- }
- break;
- default:
- addedspace = false;
- pdf = pdf.append(transstr +
- (xpos + matrix.getE()) +
- " " + (ypos +
- matrix.getF()) + " Tm " +
- "(" + ch + ") Tj\n");
- currentX = xpos + fs.width(ch) / 1000f;
- currentY = ypos;
- charPos++;
- inbetween = true;
- break;
- }
- }
- currentStream.write(pdf.toString());
- }
- }
- }
- }
-
- protected boolean updateFont(SVGStylable style, FontState fs) {
- boolean changed = false;
- String fontFamily = fs.getFontFamily();
- CSSValue sp = style.getPresentationAttribute("font-family");
- if (sp != null &&
- sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
- if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
- CSSPrimitiveValue.CSS_STRING) {
- fontFamily = sp.getCssText();
- }
- }
- if (!fontFamily.equals(fs.getFontFamily())) {
- changed = true;
- }
- String fontStyle = fs.getFontStyle();
- sp = style.getPresentationAttribute("font-style");
- if (sp != null &&
- sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
- if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
- CSSPrimitiveValue.CSS_STRING) {
- fontStyle = sp.getCssText();
- }
- }
- if (!fontStyle.equals(fs.getFontStyle())) {
- changed = true;
- }
- String fontWeight = fs.getFontWeight();
- sp = style.getPresentationAttribute("font-weight");
- if (sp != null &&
- sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
- if (((CSSPrimitiveValue) sp).getPrimitiveType() ==
- CSSPrimitiveValue.CSS_STRING) {
- fontWeight = sp.getCssText();
- }
- }
- if (!fontWeight.equals(fs.getFontWeight())) {
- changed = true;
- }
- float newSize = fs.getFontSize() / 1000f;
- sp = style.getPresentationAttribute("font-size");
- if (sp != null &&
- sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
- // if(((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_NUMBER) {
- newSize = ((CSSPrimitiveValue) sp).getFloatValue(
- CSSPrimitiveValue.CSS_PT);
- // }
- }
- if (fs.getFontSize() / 1000f != newSize) {
- changed = true;
- }
- if (changed) {
- try {
- // FIX-ME: should get the font-variant property
- fs = new FontState(fs.getFontInfo(), fontFamily,
- fontStyle, fontWeight, (int)(newSize * 1000),
- FontVariant.NORMAL);
- } catch (Exception fope) {
- }
- this.fs = fs;
-
- currentStream.write("/" + fs.getFontName() + " " +
- newSize + " Tf\n");
- } else {
- if (!currentFontName.equals(fs.getFontName()) ||
- currentFontSize != fs.getFontSize()) {
- // currentFontName = fs.getFontName();
- // currentFontSize = fs.getFontSize();
- currentStream.write("/" + fs.getFontName() + " " +
- (fs.getFontSize() / 1000f) + " Tf\n");
- }
- }
- return changed;
- }
- }
-
- /**
- * Convert a char to a multibyte hex representation
- */
- private String getUnicodeString(char c) {
-
- StringBuffer buf = new StringBuffer(4);
-
- byte[] uniBytes = null;
- try {
- char[] a = {c};
- uniBytes = new String(a).getBytes("UnicodeBigUnmarked");
- } catch (Exception e) {
- // This should never fail
- }
-
- for (int i = 0; i < uniBytes.length; i++) {
- int b = (uniBytes[i] < 0) ? (int)(256 + uniBytes[i]) :
- (int) uniBytes[i];
-
- String hexString = Integer.toHexString(b);
- if (hexString.length() == 1)
- buf = buf.append("0"+hexString);
- else
- buf = buf.append(hexString);
- }
-
- return buf.toString();
-
- }
-
-
-}
diff --git a/src/org/apache/fop/render/txt/TXTRenderer.java b/src/org/apache/fop/render/txt/TXTRenderer.java
index 98ffe018d..32efcd893 100755
--- a/src/org/apache/fop/render/txt/TXTRenderer.java
+++ b/src/org/apache/fop/render/txt/TXTRenderer.java
@@ -21,7 +21,8 @@ import org.apache.fop.pdf.PDFPathPaint;
import org.apache.fop.pdf.PDFColor;
import org.apache.fop.image.*;
-import org.apache.fop.dom.svg.SVGArea;
+import org.apache.fop.svg.SVGArea;
+
import org.w3c.dom.svg.SVGSVGElement;
// Java
diff --git a/src/org/apache/fop/render/xml/XMLRenderer.java b/src/org/apache/fop/render/xml/XMLRenderer.java
index 767ccab04..d0044ebf1 100644
--- a/src/org/apache/fop/render/xml/XMLRenderer.java
+++ b/src/org/apache/fop/render/xml/XMLRenderer.java
@@ -53,8 +53,6 @@ package org.apache.fop.render.xml;
// FOP
import org.apache.fop.svg.*;
import org.apache.fop.messaging.MessageHandler;
-import org.apache.fop.dom.svg.*;
-import org.apache.fop.dom.svg.SVGArea;
import org.apache.fop.render.Renderer;
import org.apache.fop.image.ImageArea;
import org.apache.fop.layout.*;