diff options
author | Keiron Liddle <keiron@apache.org> | 2001-05-17 07:48:06 +0000 |
---|---|---|
committer | Keiron Liddle <keiron@apache.org> | 2001-05-17 07:48:06 +0000 |
commit | c824ede99cb449252823876b6224f6ed75e799cd (patch) | |
tree | 771770e0d8604c5511de0249b4072817fc483736 /src/org/apache/fop/render | |
parent | f89f05c27124377ec9497b30d4d75874a2bec67b (diff) | |
download | xmlgraphics-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.java | 2 | ||||
-rw-r--r-- | src/org/apache/fop/render/Renderer.java | 2 | ||||
-rw-r--r-- | src/org/apache/fop/render/awt/AWTRenderer.java | 679 | ||||
-rw-r--r-- | src/org/apache/fop/render/mif/MIFRenderer.java | 8 | ||||
-rwxr-xr-x | src/org/apache/fop/render/pcl/PCLRenderer.java | 5 | ||||
-rwxr-xr-x | src/org/apache/fop/render/pcl/PCLSVGRenderer.java | 1400 | ||||
-rw-r--r-- | src/org/apache/fop/render/pdf/PDFRenderer.java | 197 | ||||
-rw-r--r-- | src/org/apache/fop/render/pdf/SVGRenderer.java | 2759 | ||||
-rwxr-xr-x | src/org/apache/fop/render/txt/TXTRenderer.java | 3 | ||||
-rw-r--r-- | src/org/apache/fop/render/xml/XMLRenderer.java | 2 |
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.*; |