ASF Bugzilla – Attachment 22576 Details for
Bug 45759
[PATCH] Internal PDF links from included SVG graphics
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Counter-proposal (incomplete)
bugzilla45759-svg-linkback-counterproposal.patch (text/plain), 10.38 KB, created by
Jeremias Maerki
on 2008-09-15 10:23:36 UTC
(
hide
)
Description:
Counter-proposal (incomplete)
Filename:
MIME Type:
Creator:
Jeremias Maerki
Created:
2008-09-15 10:23:36 UTC
Size:
10.38 KB
patch
obsolete
>Index: src/java/org/apache/fop/render/pdf/PDFRenderer.java >=================================================================== >--- src/java/org/apache/fop/render/pdf/PDFRenderer.java (revision 695454) >+++ src/java/org/apache/fop/render/pdf/PDFRenderer.java (working copy) >@@ -1401,6 +1401,26 @@ > } > } > >+ /** >+ * Render an internal link explicitly. >+ * For normal PDF text, this is handled by >+ * renderInlineParent. This is used when rendering SVG's to >+ * explicitly add internal links. >+ * @param rect Area to add link to >+ * @param idRef The target id to link to >+ */ >+ public void renderInternalLink(Rectangle2D rect, String idRef) { >+ boolean annotsAllowed = pdfDoc.getProfile().isAnnotationAllowed(); >+ boolean idRefOK = idRef != null && idRef.length() > 0; >+ if (idRefOK && annotsAllowed) { >+ PDFFactory factory = pdfDoc.getFactory(); >+ PDFAction action = getPDFGoToForID(idRef, null); >+ /* using null as pvKey will delay the link resolution */ >+ PDFLink pdfLink = factory.makeLink(rect, action); >+ currentPage.addAnnotation(pdfLink); >+ } >+ } >+ > private Typeface getTypeface(String fontName) { > Typeface tf = (Typeface) fontInfo.getFonts().get(fontName); > if (tf instanceof LazyFont) { >Index: src/java/org/apache/fop/render/pdf/PDFSVGHandler.java >=================================================================== >--- src/java/org/apache/fop/render/pdf/PDFSVGHandler.java (revision 695454) >+++ src/java/org/apache/fop/render/pdf/PDFSVGHandler.java (working copy) >@@ -20,7 +20,9 @@ > package org.apache.fop.render.pdf; > > import java.awt.Color; >+import java.awt.Shape; > import java.awt.geom.AffineTransform; >+import java.awt.geom.Rectangle2D; > import java.io.IOException; > import java.io.OutputStream; > import java.util.Map; >@@ -51,6 +53,7 @@ > import org.apache.fop.render.RendererContext; > import org.apache.fop.render.RendererContextConstants; > import org.apache.fop.svg.PDFAElementBridge; >+import org.apache.fop.svg.PDFANode; > import org.apache.fop.svg.PDFBridgeContext; > import org.apache.fop.svg.PDFGraphics2D; > import org.apache.fop.svg.SVGEventProducer; >@@ -140,7 +143,7 @@ > */ > protected void renderSVGDocument(RendererContext context, > Document doc) { >- PDFRenderer renderer = (PDFRenderer)context.getRenderer(); >+ final PDFRenderer renderer = (PDFRenderer)context.getRenderer(); > PDFInfo pdfInfo = getPDFInfo(context); > if (pdfInfo.paintAsBitmap) { > try { >@@ -182,8 +185,16 @@ > (strokeText ? null : pdfInfo.fi), > userAgent.getFactory().getImageManager(), > userAgent.getImageSessionContext(), >- new AffineTransform()); >+ new AffineTransform()) { > >+ /** {@inheritDoc} */ >+ protected PDFAElementBridge createPDFAElementBridge() { >+ //return super.createPDFAElementBridge(); >+ return new LinkBackAElementBridge(renderer); >+ } >+ >+ }; >+ > GraphicsNode root; > try { > root = builder.build(ctx, doc); >@@ -276,4 +287,45 @@ > public boolean supportsRenderer(Renderer renderer) { > return (renderer instanceof PDFRenderer); > } >+ >+ private class LinkBackAElementBridge extends PDFAElementBridge { >+ >+ private PDFRenderer renderer; >+ >+ public LinkBackAElementBridge(PDFRenderer renderer) { >+ this.renderer = renderer; >+ } >+ >+ /** {@inheritDoc} */ >+ protected GraphicsNode instantiateGraphicsNode() { >+ return new LinkBackPDFANode(this.renderer); >+ } >+ >+ } >+ >+ private class LinkBackPDFANode extends PDFANode { >+ >+ private PDFRenderer renderer; >+ >+ public LinkBackPDFANode(PDFRenderer renderer) { >+ this.renderer = renderer; >+ } >+ >+ /** {@inheritDoc} */ >+ protected boolean generateFragmentLink(Rectangle2D bounds, PDFGraphics2D pdfg) { >+ assert getDestination().charAt(0) == '#'; >+ boolean annotsAllowed = renderer.pdfDoc.getProfile().isAnnotationAllowed(); >+ if (!annotsAllowed) { >+ return false; >+ } >+ >+ String target = getDestination().substring(1); >+ Shape b = pdfg.getTransform().createTransformedShape(bounds); >+ b = this.getOnPageTransform().createTransformedShape(b); >+ >+ renderer.renderInternalLink(b.getBounds2D(), target); >+ return true; >+ } >+ >+ } > } >Index: src/java/org/apache/fop/svg/PDFAElementBridge.java >=================================================================== >--- src/java/org/apache/fop/svg/PDFAElementBridge.java (revision 695454) >+++ src/java/org/apache/fop/svg/PDFAElementBridge.java (working copy) >@@ -21,14 +21,13 @@ > > import java.awt.geom.AffineTransform; > >+import org.w3c.dom.Element; >+import org.w3c.dom.svg.SVGAElement; >+ > import org.apache.batik.bridge.AbstractGraphicsNodeBridge; > import org.apache.batik.bridge.BridgeContext; >- > import org.apache.batik.gvt.GraphicsNode; > >-import org.w3c.dom.Element; >-import org.w3c.dom.svg.SVGAElement; >- > /** > * Bridge class for the <a> element. > * >@@ -83,7 +82,7 @@ > public GraphicsNode createGraphicsNode(BridgeContext ctx, Element e) { > PDFANode aNode = (PDFANode)super.createGraphicsNode(ctx, e); > aNode.setDestination(((SVGAElement)e).getHref().getBaseVal()); >- aNode.setTransform(transform); >+ aNode.setOnPageTransform(transform); > return aNode; > } > >Index: src/java/org/apache/fop/svg/PDFANode.java >=================================================================== >--- src/java/org/apache/fop/svg/PDFANode.java (revision 695454) >+++ src/java/org/apache/fop/svg/PDFANode.java (working copy) >@@ -19,15 +19,14 @@ > > package org.apache.fop.svg; > >-import org.apache.batik.gvt.CompositeGraphicsNode; >- > import java.awt.Graphics2D; > import java.awt.Shape; >+import java.awt.geom.AffineTransform; > import java.awt.geom.Rectangle2D; >-import java.awt.geom.AffineTransform; >- > import java.util.StringTokenizer; > >+import org.apache.batik.gvt.CompositeGraphicsNode; >+ > /** > * A graphics node that represents an image described as a graphics node. > * >@@ -35,7 +34,7 @@ > */ > public class PDFANode extends CompositeGraphicsNode { > private String destination; >- private AffineTransform transform; >+ private AffineTransform onPageTransform; > > /** > * Constructs a new empty <tt>PDFANode</tt>. >@@ -52,14 +51,32 @@ > } > > /** >- * Set the current transform of this node. >+ * Returns the destination value for the node. >+ * @return the destination >+ */ >+ public String getDestination() { >+ return this.destination; >+ } >+ >+ /** >+ * Set the "on-page" transform of this node. This corrects the placement of the link hot-zones >+ * with respect of the SVG graphic on the page. > * @param tf the transform > */ >- public void setTransform(AffineTransform tf) { >- transform = tf; >+ public void setOnPageTransform(AffineTransform tf) { >+ this.onPageTransform = tf; > } > > /** >+ * Returns the "on-page" transform of this node. >+ * See {@code #setOnPageTransform(AffineTransform)} for details. >+ * @return the "on-page" transform >+ */ >+ public AffineTransform getOnPageTransform() { >+ return this.onPageTransform; >+ } >+ >+ /** > * Paints this node if visible. > * > * @param g2d the Graphics2D to use >@@ -104,9 +121,10 @@ > } catch (Exception e) { > //TODO Move this to setDestination() and throw an IllegalArgumentException > e.printStackTrace(); >+ return; > } > Rectangle2D destRect = new Rectangle2D.Float(x, y, width, height); >- destRect = transform.createTransformedShape(destRect).getBounds(); >+ destRect = getOnPageTransform().createTransformedShape(destRect).getBounds(); > // these numbers need conversion to current > // svg position and scaled for the page > x = (float)destRect.getX(); >@@ -116,11 +134,27 @@ > > destination = "" + x + " " + y + " " > + (x + width) + " " + (y + height); >+ } else if (destination.startsWith("#")) { >+ if (generateFragmentLink(getBounds(), pdfg)) { >+ return; //Returns early if the method indicated that it has generated a link >+ } > } >- pdfg.addLink(getBounds(), transform, destination, type); >+ pdfg.addLink(getBounds(), getOnPageTransform(), destination, type); > } > } > } > >+ /** >+ * Generates a link for a fragment reference. By default, it does nothing. Subclasses can >+ * generate links to objects (ex. in XSL-FO) identified by the fragment reference. >+ * @param bounds the boundaries of the hot zone >+ * @param pdfg the PDFGraphics2D object >+ * @return true if it has generated a link for the fragment reference >+ */ >+ protected boolean generateFragmentLink(Rectangle2D bounds, PDFGraphics2D pdfg) { >+ //nop >+ return false; >+ } >+ > } > >Index: src/java/org/apache/fop/svg/PDFBridgeContext.java >=================================================================== >--- src/java/org/apache/fop/svg/PDFBridgeContext.java (revision 695454) >+++ src/java/org/apache/fop/svg/PDFBridgeContext.java (working copy) >@@ -155,7 +155,7 @@ > "org.apache.batik.bridge.svg12.SVGFlowRootElementBridge"); > } > >- PDFAElementBridge pdfAElementBridge = new PDFAElementBridge(); >+ PDFAElementBridge pdfAElementBridge = createPDFAElementBridge(); > if (linkTransform != null) { > pdfAElementBridge.setCurrentTransform(linkTransform); > } else { >@@ -166,6 +166,14 @@ > putBridge(new PDFImageElementBridge()); > } > >+ /** >+ * Creates the "a" element bridge for the bridge context. >+ * @return the element bridge >+ */ >+ protected PDFAElementBridge createPDFAElementBridge() { >+ return new PDFAElementBridge(); >+ } >+ > // Make sure any 'sub bridge contexts' also have our bridges. > //TODO There's no matching method in the super-class here > public BridgeContext createBridgeContext() {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 45759
:
22538
| 22576 |
22577
|
22676