diff options
author | Keiron Liddle <keiron@apache.org> | 2002-06-18 13:42:56 +0000 |
---|---|---|
committer | Keiron Liddle <keiron@apache.org> | 2002-06-18 13:42:56 +0000 |
commit | 64c1fb1421bb717edda576a916dc7a566967169c (patch) | |
tree | 106908e06d86a78e62b9bf364d76db1212a4483e /src | |
parent | 84be81fe4e07fab92ccbcd8d77fbf4c6d66a8c71 (diff) | |
download | xmlgraphics-fop-64c1fb1421bb717edda576a916dc7a566967169c.tar.gz xmlgraphics-fop-64c1fb1421bb717edda576a916dc7a566967169c.zip |
implemented links in svg both for standalone and in fo documents
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194898 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r-- | src/org/apache/fop/area/CTM.java | 4 | ||||
-rw-r--r-- | src/org/apache/fop/pdf/PDFAnnotList.java | 2 | ||||
-rw-r--r-- | src/org/apache/fop/pdf/PDFDocument.java | 17 | ||||
-rw-r--r-- | src/org/apache/fop/pdf/PDFLink.java | 4 | ||||
-rw-r--r-- | src/org/apache/fop/pdf/PDFPage.java | 23 | ||||
-rw-r--r-- | src/org/apache/fop/pdf/PDFState.java | 34 | ||||
-rw-r--r-- | src/org/apache/fop/render/pdf/PDFRenderer.java | 12 | ||||
-rw-r--r-- | src/org/apache/fop/render/pdf/PDFXMLHandler.java | 28 | ||||
-rw-r--r-- | src/org/apache/fop/svg/PDFANode.java | 17 | ||||
-rw-r--r-- | src/org/apache/fop/svg/PDFDocumentGraphics2D.java | 4 | ||||
-rw-r--r-- | src/org/apache/fop/svg/PDFGraphics2D.java | 37 | ||||
-rw-r--r-- | src/org/apache/fop/svg/PDFTextElementBridge.java | 4 | ||||
-rw-r--r-- | src/org/apache/fop/svg/PDFTranscoder.java | 5 |
13 files changed, 120 insertions, 71 deletions
diff --git a/src/org/apache/fop/area/CTM.java b/src/org/apache/fop/area/CTM.java index d31fed9a3..d506d3feb 100644 --- a/src/org/apache/fop/area/CTM.java +++ b/src/org/apache/fop/area/CTM.java @@ -210,4 +210,8 @@ public class CTM implements Serializable { public String toPDFctm() { return a + " " + b + " " + c + " " + d + " " + e/1000f + " " + f/1000f; } + + public double[] toArray() { + return new double[] {a, b, c, d, e / 1000.0, f / 1000.0}; + } } diff --git a/src/org/apache/fop/pdf/PDFAnnotList.java b/src/org/apache/fop/pdf/PDFAnnotList.java index 1a23d85d5..5aa805670 100644 --- a/src/org/apache/fop/pdf/PDFAnnotList.java +++ b/src/org/apache/fop/pdf/PDFAnnotList.java @@ -44,7 +44,7 @@ public class PDFAnnotList extends PDFObject { * * @param link the PDFLink to add. */ - public void addLink(PDFLink link) { + public void addAnnot(PDFObject link) { this.links.addElement(link); this.count++; } diff --git a/src/org/apache/fop/pdf/PDFDocument.java b/src/org/apache/fop/pdf/PDFDocument.java index a88402511..a719124d3 100644 --- a/src/org/apache/fop/pdf/PDFDocument.java +++ b/src/org/apache/fop/pdf/PDFDocument.java @@ -28,6 +28,7 @@ import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.awt.Rectangle; /** @@ -953,7 +954,7 @@ public class PDFDocument { * create a PDFPage with the next object number, the given * resources, contents and dimensions */ - PDFPage page = new PDFPage(++this.objectcount, resources, + PDFPage page = new PDFPage(this, ++this.objectcount, resources, pagewidth, pageheight); /* add it to the list of objects */ @@ -965,6 +966,20 @@ public class PDFDocument { public void addPage(PDFPage page) { /* add it to the list of objects */ this.objects.add(page); + + if(pendingLinks != null) { + for(Iterator iter = pendingLinks.iterator(); iter.hasNext(); ) { + PendingLink pl = (PendingLink)iter.next(); + PDFGoTo gt = new PDFGoTo(++this.objectcount, + page.referencePDF()); + gt.setDestination(pl.dest); + addTrailerObject(gt); + PDFInternalLink internalLink = + new PDFInternalLink(gt.referencePDF()); + pl.link.setAction(internalLink); + } + pendingLinks = null; + } } /** diff --git a/src/org/apache/fop/pdf/PDFLink.java b/src/org/apache/fop/pdf/PDFLink.java index 6af94f1d8..dbe8138af 100644 --- a/src/org/apache/fop/pdf/PDFLink.java +++ b/src/org/apache/fop/pdf/PDFLink.java @@ -52,8 +52,8 @@ public class PDFLink extends PDFObject { public byte[] toPDF() { String p = this.number + " " + this.generation + " obj\n" + "<< /Type /Annot\n" + "/Subtype /Link\n" + "/Rect [ " - + (ulx / 1000f) + " " + (uly / 1000f) + " " - + (brx / 1000f) + " " + (bry / 1000f) + " ]\n" + "/C [ " + + (ulx) + " " + (uly) + " " + + (brx) + " " + (bry) + " ]\n" + "/C [ " + this.color + " ]\n" + "/Border [ 0 0 0 ]\n" + "/A " + this.action.getAction() + "\n" + "/H /I\n>>\nendobj\n"; return p.getBytes(); diff --git a/src/org/apache/fop/pdf/PDFPage.java b/src/org/apache/fop/pdf/PDFPage.java index 320a0def7..f0fcfad8c 100644 --- a/src/org/apache/fop/pdf/PDFPage.java +++ b/src/org/apache/fop/pdf/PDFPage.java @@ -52,6 +52,7 @@ public class PDFPage extends PDFObject { * the list of annotation objects for this page */ protected PDFAnnotList annotList; + protected PDFDocument document; /** * create a /Page object @@ -62,13 +63,14 @@ public class PDFPage extends PDFObject { * @param pagewidth the page's width in points * @param pageheight the page's height in points */ - public PDFPage(int number, PDFResources resources, PDFStream contents, + public PDFPage(PDFDocument doc, int number, PDFResources resources, PDFStream contents, int pagewidth, int pageheight) { /* generic creation of object */ super(number); /* set fields using parameters */ + this.document = doc; this.resources = resources; this.contents = contents; this.pagewidth = pagewidth; @@ -85,13 +87,14 @@ public class PDFPage extends PDFObject { * @param pagewidth the page's width in points * @param pageheight the page's height in points */ - public PDFPage(int number, PDFResources resources, + public PDFPage(PDFDocument doc, int number, PDFResources resources, int pagewidth, int pageheight) { /* generic creation of object */ super(number); /* set fields using parameters */ + this.document = doc; this.resources = resources; this.pagewidth = pagewidth; this.pageheight = pageheight; @@ -122,17 +125,11 @@ public class PDFPage extends PDFObject { * * @param annotList a PDFAnnotList list of annotations */ - public void setAnnotList(PDFAnnotList annotList) { - this.annotList = annotList; - } - - /** - * get this page's annotation list - * - * @return annotList a PDFAnnotList list of annotations - */ - public PDFAnnotList getAnnotList() { - return this.annotList; + public void addAnnotation(PDFObject annot) { + if(this.annotList == null) { + this.annotList = document.makeAnnotList(); + } + this.annotList.addAnnot(annot); } public void addShading(PDFShading shading) { diff --git a/src/org/apache/fop/pdf/PDFState.java b/src/org/apache/fop/pdf/PDFState.java index ddc66993d..45d91c5fb 100644 --- a/src/org/apache/fop/pdf/PDFState.java +++ b/src/org/apache/fop/pdf/PDFState.java @@ -10,9 +10,11 @@ package org.apache.fop.pdf; import java.awt.Shape; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import java.awt.Color; import java.awt.Paint; +import java.awt.geom.AffineTransform; /** * This keeps information about the current state when writing to pdf. @@ -57,7 +59,7 @@ public class PDFState { boolean text = false; int dashOffset = 0; int[] dashArray = new int[0]; - double[] transform = new double[]{1, 0, 0, 1, 0, 0}; + AffineTransform transform = new AffineTransform(); float fontSize = 0; String fontName = ""; Shape clip = null; @@ -89,6 +91,8 @@ public class PDFState { saveMap.put(CLIP, clip); stateStack.add(saveMap); + + transform = new AffineTransform(); } public void pop() { @@ -106,7 +110,7 @@ public class PDFState { text = ((Boolean)saveMap.get(TEXT)).booleanValue(); dashOffset = ((Integer)saveMap.get(DASHOFFSET)).intValue(); dashArray = (int[])saveMap.get(DASHARRAY); - transform = (double[])saveMap.get(TRANSFORM); + transform = (AffineTransform)saveMap.get(TRANSFORM); fontSize = ((Float)saveMap.get(FONTSIZE)).floatValue(); fontName = (String)saveMap.get(FONTNAME); clip = (Shape)saveMap.get(CLIP); @@ -165,17 +169,25 @@ public class PDFState { clip = cl; } - public boolean checkTransform(double[] vals) { - for(int count = 0; count < transform.length; count++) { - if(transform[count] != vals[count]) { - return true; - } - } - return false; + public boolean checkTransform(AffineTransform tf) { + return !tf.equals(transform); } - public void setTransform(double[] vals) { - transform = vals; + public void setTransform(AffineTransform tf) { + transform.concatenate(tf); + } + + public AffineTransform getTransform() { + AffineTransform tf; + AffineTransform at = new AffineTransform(); + for(Iterator iter = stateStack.iterator(); iter.hasNext(); ) { + HashMap map = (HashMap)iter.next(); + tf = (AffineTransform)map.get(TRANSFORM); + at.concatenate(tf); + } + at.concatenate(transform); + + return at; } } diff --git a/src/org/apache/fop/render/pdf/PDFRenderer.java b/src/org/apache/fop/render/pdf/PDFRenderer.java index 9633c6b3e..c61c9cf86 100644 --- a/src/org/apache/fop/render/pdf/PDFRenderer.java +++ b/src/org/apache/fop/render/pdf/PDFRenderer.java @@ -33,6 +33,7 @@ import org.w3c.dom.Document; import java.io.IOException; import java.io.OutputStream; import java.awt.geom.Rectangle2D; +import java.awt.geom.AffineTransform; import java.util.HashMap; import java.util.List; @@ -99,6 +100,8 @@ public class PDFRenderer extends PrintRenderer { PDFPage currentPage; // drawing state + PDFState currentState = null; + PDFColor currentColor; String currentFontName = ""; int currentFontSize = 0; @@ -215,6 +218,9 @@ public class PDFRenderer extends PrintRenderer { pageReferences.put(page, currentPage.referencePDF()); } currentStream = this.pdfDoc.makeStream(); + + currentState = new PDFState(); + currentState.setTransform(new AffineTransform(1, 0, 0, -1, 0, (int) Math.round(pageHeight / 1000))); // Transform origin at top left to origin at bottom left currentStream.add("1 0 0 -1 0 " + (int) Math.round(pageHeight / 1000) + " cm\n"); @@ -233,6 +239,9 @@ public class PDFRenderer extends PrintRenderer { protected void startVParea(CTM ctm) { // Set the given CTM in the graphics state + currentState.push(); + currentState.setTransform(new AffineTransform(ctm.toArray())); + currentStream.add("q\n"); // multiply with current CTM currentStream.add(ctm.toPDFctm() + " cm\n"); @@ -243,6 +252,7 @@ public class PDFRenderer extends PrintRenderer { protected void endVParea() { currentStream.add("ET\n"); currentStream.add("Q\n"); + currentState.pop(); } protected void renderRegion(RegionReference region) { @@ -527,6 +537,8 @@ public class PDFRenderer extends PrintRenderer { context.setUserAgent(userAgent); context.setProperty(PDFXMLHandler.PDF_DOCUMENT, pdfDoc); + context.setProperty(PDFXMLHandler.PDF_STATE, currentState); + context.setProperty(PDFXMLHandler.PDF_PAGE, currentPage); context.setProperty(PDFXMLHandler.PDF_STREAM, currentStream); context.setProperty(PDFXMLHandler.PDF_X, new Integer(currentBlockIPPosition)); context.setProperty(PDFXMLHandler.PDF_Y, new Integer(currentBPPosition)); diff --git a/src/org/apache/fop/render/pdf/PDFXMLHandler.java b/src/org/apache/fop/render/pdf/PDFXMLHandler.java index d5d2e5166..b0b95898e 100644 --- a/src/org/apache/fop/render/pdf/PDFXMLHandler.java +++ b/src/org/apache/fop/render/pdf/PDFXMLHandler.java @@ -44,6 +44,8 @@ import java.awt.geom.AffineTransform; */ public class PDFXMLHandler implements XMLHandler { public static final String PDF_DOCUMENT = "pdfDoc"; +public static final String PDF_STATE = "pdfState"; +public static final String PDF_PAGE = "pdfPage"; public static final String PDF_STREAM = "pdfStream"; public static final String PDF_X = "x"; public static final String PDF_Y = "y"; @@ -71,6 +73,8 @@ public static final String PDF_YPOS = "ypos"; public static PDFInfo getPDFInfo(RendererContext context) { PDFInfo pdfi = new PDFInfo(); pdfi.pdfDoc = (PDFDocument)context.getProperty(PDF_DOCUMENT); + pdfi.pdfState = (PDFState)context.getProperty(PDF_STATE); + pdfi.pdfPage = (PDFPage)context.getProperty(PDF_PAGE); pdfi.currentStream = (PDFStream)context.getProperty(PDF_STREAM); pdfi.x = ((Integer)context.getProperty(PDF_X)).intValue(); pdfi.y = ((Integer)context.getProperty(PDF_Y)).intValue(); @@ -84,6 +88,8 @@ public static final String PDF_YPOS = "ypos"; public static class PDFInfo { PDFDocument pdfDoc; + PDFState pdfState; + PDFPage pdfPage; public PDFStream currentStream; int x; int y; @@ -108,12 +114,14 @@ public static final String PDF_YPOS = "ypos"; GVTBuilder builder = new GVTBuilder(); BridgeContext ctx = new BridgeContext(ua); - TextPainter textPainter = null; - textPainter = new PDFTextPainter(pdfInfo.fs); - ctx.setTextPainter(textPainter); + PDFTextElementBridge tBridge = new PDFTextElementBridge(pdfInfo.fs); + ctx.putBridge(tBridge); PDFAElementBridge aBridge = new PDFAElementBridge(); - aBridge.setCurrentTransform(new AffineTransform(sx, 0, 0, sy, xOffset / 1000f, yOffset / 1000f)); + // to get the correct transform we need to use the PDFState + AffineTransform transform = pdfInfo.pdfState.getTransform(); + transform.translate(xOffset / 1000f, yOffset / 1000f); + aBridge.setCurrentTransform(transform); ctx.putBridge(aBridge); GraphicsNode root; @@ -156,12 +164,17 @@ public static final String PDF_YPOS = "ypos"; } PDFGraphics2D graphics = new PDFGraphics2D(true, pdfInfo.fs, pdfInfo.pdfDoc, - pdfInfo.currentFontName, + pdfInfo.pdfPage, pdfInfo.currentFontName, pdfInfo.currentFontSize, pdfInfo.currentXPosition, pdfInfo.currentYPosition); graphics.setGraphicContext(new org.apache.batik.ext.awt.g2d.GraphicContext()); - + pdfInfo.pdfState.push(); + transform = new AffineTransform(); + // TODO scale to viewbox + transform.translate(xOffset / 1000f, yOffset / 1000f); + pdfInfo.pdfState.setTransform(transform); + graphics.setPDFState(pdfInfo.pdfState); try { root.paint(graphics); pdfInfo.currentStream.add(graphics.getString()); @@ -170,9 +183,8 @@ public static final String PDF_YPOS = "ypos"; + e.getMessage(), e); } - //currentAnnotList = graphics.getAnnotList(); - pdfInfo.currentStream.add("Q\n"); + pdfInfo.pdfState.pop(); } } } diff --git a/src/org/apache/fop/svg/PDFANode.java b/src/org/apache/fop/svg/PDFANode.java index a4e28a88e..5117cd76b 100644 --- a/src/org/apache/fop/svg/PDFANode.java +++ b/src/org/apache/fop/svg/PDFANode.java @@ -59,11 +59,11 @@ public class PDFANode extends CompositeGraphicsNode { Shape outline = getOutline(); if(destination.startsWith("#svgView(viewBox(")) { type = org.apache.fop.layout.LinkSet.INTERNAL; - String nums = destination.substring(18, destination.length() - 2); + String nums = destination.substring(17, destination.length() - 2); float x = 0; float y = 0; float width = 0; - float height; + float height = 0; int count = 0; try { StringTokenizer st = new StringTokenizer(nums, ","); @@ -88,12 +88,21 @@ public class PDFANode extends CompositeGraphicsNode { } } } catch(Exception e) { + e.printStackTrace(); } + Rectangle2D destRect = new Rectangle2D.Float(x, y, width, height); + destRect = transform.createTransformedShape(destRect).getBounds(); // these numbers need conversion to current // svg position and scaled for the page - destination = "" + x + " " + y + " " + 200 / width; + x = (float)destRect.getX(); + y = (float)destRect.getY(); + width = (float)destRect.getWidth(); + height = (float)destRect.getHeight(); + + destination = "" + x + " " + y + " " + + (x + width) + " " + (y + height); } - pdfg.addLink(outline, transform, destination, type); + pdfg.addLink(getBounds(), transform, destination, type); } } } diff --git a/src/org/apache/fop/svg/PDFDocumentGraphics2D.java b/src/org/apache/fop/svg/PDFDocumentGraphics2D.java index 3ddbba1df..355837630 100644 --- a/src/org/apache/fop/svg/PDFDocumentGraphics2D.java +++ b/src/org/apache/fop/svg/PDFDocumentGraphics2D.java @@ -37,7 +37,6 @@ import org.apache.batik.ext.awt.g2d.GraphicContext; public class PDFDocumentGraphics2D extends PDFGraphics2D { OutputStream stream; - PDFPage currentPage; PDFStream pdfStream; int width; int height; @@ -156,9 +155,6 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D { PDFResources pdfResources = this.pdfDoc.getResources(); currentPage.setContents(pdfStream); this.pdfDoc.addPage(currentPage); - if(currentAnnotList != null) { - currentPage.setAnnotList(currentAnnotList); - } if (fontInfo != null) { FontSetup.addToResources(this.pdfDoc, fontInfo); } diff --git a/src/org/apache/fop/svg/PDFGraphics2D.java b/src/org/apache/fop/svg/PDFGraphics2D.java index ed14b988e..e4ada44ba 100644 --- a/src/org/apache/fop/svg/PDFGraphics2D.java +++ b/src/org/apache/fop/svg/PDFGraphics2D.java @@ -51,17 +51,13 @@ public class PDFGraphics2D extends AbstractGraphics2D { * the PDF Document being created */ protected PDFDocument pdfDoc; + protected PDFPage currentPage; /** * the current state of the pdf graphics */ PDFState graphicsState; - /** - * the current annotation list to add annotations to - */ - PDFAnnotList currentAnnotList = null; - protected FontState fontState; protected FontState ovFontState = null; @@ -110,9 +106,10 @@ public class PDFGraphics2D extends AbstractGraphics2D { * existing document. */ public PDFGraphics2D(boolean textAsShapes, FontState fs, PDFDocument doc, - String font, int size, int xpos, int ypos) { + PDFPage page, String font, int size, int xpos, int ypos) { super(textAsShapes); pdfDoc = doc; + currentPage = page; currentFontName = font; currentFontSize = size; currentYPosition = ypos; @@ -125,6 +122,10 @@ public class PDFGraphics2D extends AbstractGraphics2D { super(textAsShapes); } + public void setPDFState(PDFState state) { + graphicsState = state; + } + public String getString() { return currentStream.toString(); } @@ -158,32 +159,22 @@ public class PDFGraphics2D extends AbstractGraphics2D { * This is a pdf specific method used to add a link to the * pdf document. */ - public void addLink(Shape bounds, AffineTransform trans, String dest, int linkType) { - if(currentAnnotList == null) { - currentAnnotList = pdfDoc.makeAnnotList(); - } + public void addLink(Rectangle2D bounds, AffineTransform trans, String dest, int linkType) { AffineTransform at = getTransform(); Shape b = at.createTransformedShape(bounds); b = trans.createTransformedShape(b); Rectangle rect = b.getBounds(); - // this handles the / 1000 in PDFLink - rect.x = rect.x * 1000; - rect.y = rect.y * 1000; - rect.height = -rect.height * 1000; - rect.width = rect.width * 1000; + rect.height = -rect.height; + if(linkType != LinkSet.EXTERNAL) { - String pdfdest = "/XYZ " + dest; - currentAnnotList.addLink(pdfDoc.makeLinkCurrentPage(rect, pdfdest)); + String pdfdest = "/FitR " + dest; + currentPage.addAnnotation(pdfDoc.makeLinkCurrentPage(rect, pdfdest)); } else { - currentAnnotList.addLink(pdfDoc.makeLink(rect, + currentPage.addAnnotation(pdfDoc.makeLink(rect, dest, linkType)); } } - public PDFAnnotList getAnnotList() { - return currentAnnotList; - } - public void addJpegImage(JpegImage jpeg, float x, float y, float width, float height) { int xObjectNum = this.pdfDoc.addImage(jpeg); @@ -545,7 +536,7 @@ public class PDFGraphics2D extends AbstractGraphics2D { Shape imclip = getClip(); boolean newClip = graphicsState.checkClip(imclip); - boolean newTransform = graphicsState.checkTransform(tranvals); + boolean newTransform = graphicsState.checkTransform(trans); if(newClip || newTransform) { currentStream.write("q\n"); diff --git a/src/org/apache/fop/svg/PDFTextElementBridge.java b/src/org/apache/fop/svg/PDFTextElementBridge.java index f00ac0061..e0992bea0 100644 --- a/src/org/apache/fop/svg/PDFTextElementBridge.java +++ b/src/org/apache/fop/svg/PDFTextElementBridge.java @@ -91,9 +91,9 @@ public class PDFTextElementBridge extends SVGTextElementBridge { } } - if(CSSUtilities.convertFilter(element, node, ctx) != null) { + /*if(CSSUtilities.convertFilter(element, node, ctx) != null) { return false; - } + }*/ return true; } diff --git a/src/org/apache/fop/svg/PDFTranscoder.java b/src/org/apache/fop/svg/PDFTranscoder.java index 733f854da..4c4feaa57 100644 --- a/src/org/apache/fop/svg/PDFTranscoder.java +++ b/src/org/apache/fop/svg/PDFTranscoder.java @@ -124,9 +124,10 @@ import org.w3c.dom.svg.SVGSVGElement; * @version $Id$ */ public class PDFTranscoder extends XMLAbstractTranscoder { - + /* public static final TranscodingHints.Key KEY_STROKE_TEXT = - new StringKey(); + new BooleanKey(); + */ /** * The user agent dedicated to an <tt>ImageTranscoder</tt>. |