You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pdfbox.apache.org by ms...@apache.org on 2016/05/25 10:55:43 UTC

svn commit: r1745470 - in /pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation: ./ handlers/

Author: msahyoun
Date: Wed May 25 10:55:43 2016
New Revision: 1745470

URL: http://svn.apache.org/viewvc?rev=1745470&view=rev
Log:
PDFBOX-3353: support opacity setting

Added:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDAbstractAppearanceHandler.java
      - copied, changed from r1745466, pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDAppearanceHandler.java
Modified:
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/PDAppearanceContentStream.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDAppearanceHandler.java
    pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDSquareAppearanceHandler.java

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/PDAppearanceContentStream.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/PDAppearanceContentStream.java?rev=1745470&r1=1745469&r2=1745470&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/PDAppearanceContentStream.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/PDAppearanceContentStream.java Wed May 25 10:55:43 2016
@@ -212,8 +212,7 @@ public final class PDAppearanceContentSt
 
     public void setBorderLine(float lineWidth, PDBorderStyleDictionary bs) throws IOException
     {
-        // Important:
-        // can't use PDBorderStyleDictionary.getDashStyle() as
+        // Can't use PDBorderStyleDictionary.getDashStyle() as
         // this will return a default dash style if non is existing
         if (bs != null && (bs.getCOSObject().containsKey(COSName.D)))
         {

Copied: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDAbstractAppearanceHandler.java (from r1745466, pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDAppearanceHandler.java)
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDAbstractAppearanceHandler.java?p2=pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDAbstractAppearanceHandler.java&p1=pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDAppearanceHandler.java&r1=1745466&r2=1745470&rev=1745470&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDAppearanceHandler.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDAbstractAppearanceHandler.java Wed May 25 10:55:43 2016
@@ -17,13 +17,20 @@
 
 package org.apache.pdfbox.pdmodel.interactive.annotation.handlers;
 
+import java.awt.geom.AffineTransform;
+import java.io.IOException;
+
 import org.apache.pdfbox.cos.COSStream;
+import org.apache.pdfbox.pdmodel.PDResources;
 import org.apache.pdfbox.pdmodel.common.PDRectangle;
 import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
+import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
 import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
 import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationSquareCircle;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceContentStream;
 import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceDictionary;
 import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceEntry;
+import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream;
 
 /**
  * Generic handler to generate the fields appearance.
@@ -32,25 +39,15 @@ import org.apache.pdfbox.pdmodel.interac
  * types.
  * 
  */
-public abstract class PDAppearanceHandler
+public abstract class PDAbstractAppearanceHandler implements PDAppearanceHandler
 {
-
     private PDAnnotation annotation;
-
-    public PDAppearanceHandler(PDAnnotation annotation)
+    private PDAppearanceEntry appearanceEntry;
+    private PDAppearanceContentStream contentStream;
+    
+    public PDAbstractAppearanceHandler(PDAnnotation annotation)
     {
         this.annotation = annotation;
-
-    }
-
-    public void generateAppearanceStreams()
-    {
-        if (annotation.getRectangle() != null)
-        {
-            generateNormalAppearance();
-            generateRolloverAppearance();
-            generateDownAppearance();
-        }
     }
 
     public abstract void generateNormalAppearance();
@@ -65,7 +62,7 @@ public abstract class PDAppearanceHandle
     }
 
     /**
-     * Get the line with of the border.
+     * Get the line width of the border.
      * 
      * Get the width of the line used to draw a border around the annotation.
      * This may either be specified by the annotation dictionaries Border
@@ -112,28 +109,22 @@ public abstract class PDAppearanceHandle
     }
 
     /**
-     * Get the annotations normal appearance.
+     * Get the annotations normal appearance content stream.
      * 
      * <p>
-     * This will get the annotations normal appearance. If this is not existent
-     * an empty appearance entry will be created.
+     * This will get the annotations normal appearance content stream,
+     * to 'draw' to.
      * 
      * @return the appearance entry representing the normal appearance.
+     * @throws IOException 
      */
-    PDAppearanceEntry getNormalAppearance()
+    PDAppearanceContentStream getNormalAppearanceAsContentStream() throws IOException
     {
-        PDAppearanceDictionary appearanceDictionary = getAppearance();
-        PDAppearanceEntry appearanceEntry = appearanceDictionary.getNormalAppearance();
-
-        if (appearanceEntry.isSubDictionary())
-        {
-            appearanceEntry = new PDAppearanceEntry(new COSStream());
-            appearanceDictionary.setNormalAppearance(appearanceEntry);
-        }
-
-        return appearanceEntry;
+        appearanceEntry = getNormalAppearance();
+        contentStream = getAppearanceEntryAsContentStream(appearanceEntry);
+        return contentStream;
     }
-
+    
     /**
      * Get the annotations down appearance.
      * 
@@ -206,4 +197,65 @@ public abstract class PDAppearanceHandle
         return new PDRectangle(rectangle.getLowerLeftX() + padding, rectangle.getLowerLeftY() + padding,
                 rectangle.getWidth() - 2 * padding, rectangle.getHeight() - 2 * padding);
     }
+
+    void handleOpacity(float opacity) throws IOException
+    {
+        if (opacity < 1)
+        {
+            PDExtendedGraphicsState gs = new PDExtendedGraphicsState();
+            gs.setStrokingAlphaConstant(opacity);
+            gs.setNonStrokingAlphaConstant(opacity);
+            
+            PDAppearanceStream appearanceStream = appearanceEntry.getAppearanceStream();
+            
+            PDResources resources = appearanceStream.getResources();
+            if (resources == null)
+            {
+                resources = new PDResources();
+                appearanceStream.setResources(resources);
+                contentStream.setResources(resources);
+            }
+            contentStream.setGraphicsStateParameters(gs);
+        }
+    }
+    
+    /**
+     * Get the annotations normal appearance.
+     * 
+     * <p>
+     * This will get the annotations normal appearance. If this is not existent
+     * an empty appearance entry will be created.
+     * 
+     * @return the appearance entry representing the normal appearance.
+     */
+    private PDAppearanceEntry getNormalAppearance()
+    {
+        PDAppearanceDictionary appearanceDictionary = getAppearance();
+        PDAppearanceEntry appearanceEntry = appearanceDictionary.getNormalAppearance();
+
+        if (appearanceEntry.isSubDictionary())
+        {
+            appearanceEntry = new PDAppearanceEntry(new COSStream());
+            appearanceDictionary.setNormalAppearance(appearanceEntry);
+        }
+
+        return appearanceEntry;
+    }
+    
+    
+    private PDAppearanceContentStream getAppearanceEntryAsContentStream(PDAppearanceEntry appearanceEntry) throws IOException
+    {
+        PDAppearanceStream appearanceStream = appearanceEntry.getAppearanceStream();
+        setTransformationMatrix(appearanceStream);
+        return new PDAppearanceContentStream(appearanceStream);
+    }
+    
+    private void setTransformationMatrix(PDAppearanceStream appearanceStream)
+    {
+        PDRectangle bbox = getRectangle();
+        appearanceStream.setBBox(bbox);
+        AffineTransform transform = AffineTransform.getTranslateInstance(-bbox.getLowerLeftX(),
+                -bbox.getLowerLeftY());
+        appearanceStream.setMatrix(transform);
+    }
 }

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDAppearanceHandler.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDAppearanceHandler.java?rev=1745470&r1=1745469&r2=1745470&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDAppearanceHandler.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDAppearanceHandler.java Wed May 25 10:55:43 2016
@@ -17,193 +17,13 @@
 
 package org.apache.pdfbox.pdmodel.interactive.annotation.handlers;
 
-import org.apache.pdfbox.cos.COSStream;
-import org.apache.pdfbox.pdmodel.common.PDRectangle;
-import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
-import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
-import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationSquareCircle;
-import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceDictionary;
-import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceEntry;
-
-/**
- * Generic handler to generate the fields appearance.
- * 
- * Individual handler will provide specific implementations for different field
- * types.
- * 
- */
-public abstract class PDAppearanceHandler
+public interface PDAppearanceHandler
 {
-
-    private PDAnnotation annotation;
-
-    public PDAppearanceHandler(PDAnnotation annotation)
-    {
-        this.annotation = annotation;
-
-    }
-
-    public void generateAppearanceStreams()
-    {
-        if (annotation.getRectangle() != null)
-        {
-            generateNormalAppearance();
-            generateRolloverAppearance();
-            generateDownAppearance();
-        }
-    }
-
-    public abstract void generateNormalAppearance();
-
-    public abstract void generateRolloverAppearance();
-
-    public abstract void generateDownAppearance();
-
-    PDAnnotation getAnnotation()
-    {
-        return annotation;
-    }
-
-    /**
-     * Get the line with of the border.
-     * 
-     * Get the width of the line used to draw a border around the annotation.
-     * This may either be specified by the annotation dictionaries Border
-     * setting or by the W entry in the BS border style dictionary. If both are
-     * missing the default width is 1.
-     * 
-     * @return the line width
-     */
-    // TODO: according to the PDF spec the use of the BS entry is annotation
-    // specific
-    // so we will leave that to be implemented by individual handlers.
-    // If at the end all annotations support the BS entry this can be handled
-    // here and removed from the individual handlers.
-    abstract float getLineWidth();
-
-    PDColor getColor()
-    {
-        return annotation.getColor();
-    }
-
-    PDRectangle getRectangle()
-    {
-        return annotation.getRectangle();
-    }
-
-    /**
-     * Get the annotations appearance dictionary.
-     * 
-     * <p>
-     * This will get the annotations appearance dictionary. If this is not
-     * existent an empty appearance dictionary will be created.
-     * 
-     * @return the annotations appearance dictionary
-     */
-    PDAppearanceDictionary getAppearance()
-    {
-        PDAppearanceDictionary appearanceDictionary = annotation.getAppearance();
-        if (appearanceDictionary == null)
-        {
-            appearanceDictionary = new PDAppearanceDictionary();
-            annotation.setAppearance(appearanceDictionary);
-        }
-        return appearanceDictionary;
-    }
-
-    /**
-     * Get the annotations normal appearance.
-     * 
-     * <p>
-     * This will get the annotations normal appearance. If this is not existent
-     * an empty appearance entry will be created.
-     * 
-     * @return the appearance entry representing the normal appearance.
-     */
-    PDAppearanceEntry getNormalAppearance()
-    {
-        PDAppearanceDictionary appearanceDictionary = getAppearance();
-        PDAppearanceEntry appearanceEntry = appearanceDictionary.getNormalAppearance();
-
-        if (appearanceEntry.isSubDictionary())
-        {
-            appearanceEntry = new PDAppearanceEntry(new COSStream());
-            appearanceDictionary.setNormalAppearance(appearanceEntry);
-        }
-
-        return appearanceEntry;
-    }
-
-    /**
-     * Get the annotations down appearance.
-     * 
-     * <p>
-     * This will get the annotations down appearance. If this is not existent an
-     * empty appearance entry will be created.
-     * 
-     * @return the appearance entry representing the down appearance.
-     */
-    PDAppearanceEntry getDownAppearance()
-    {
-        PDAppearanceDictionary appearanceDictionary = getAppearance();
-        PDAppearanceEntry appearanceEntry = appearanceDictionary.getDownAppearance();
-
-        if (appearanceEntry.isSubDictionary())
-        {
-            appearanceEntry = new PDAppearanceEntry(new COSStream());
-            appearanceDictionary.setDownAppearance(appearanceEntry);
-        }
-
-        return appearanceEntry;
-    }
-
-    /**
-     * Get the annotations rollover appearance.
-     * 
-     * <p>
-     * This will get the annotations rollover appearance. If this is not
-     * existent an empty appearance entry will be created.
-     * 
-     * @return the appearance entry representing the rollover appearance.
-     */
-    PDAppearanceEntry getRolloverAppearance()
-    {
-        PDAppearanceDictionary appearanceDictionary = getAppearance();
-        PDAppearanceEntry appearanceEntry = appearanceDictionary.getRolloverAppearance();
-
-        if (appearanceEntry.isSubDictionary())
-        {
-            appearanceEntry = new PDAppearanceEntry(new COSStream());
-            appearanceDictionary.setRolloverAppearance(appearanceEntry);
-        }
-
-        return appearanceEntry;
-    }
+    void generateAppearanceStreams();
     
-    /**
-     * Set the differences rectangle.
-     */
-    void setRectDifference(float lineWidth)
-    {
-        if (annotation instanceof PDAnnotationSquareCircle && lineWidth > 0)
-        {
-            PDRectangle differences = new PDRectangle(lineWidth/2, lineWidth/2,0,0);
-            ((PDAnnotationSquareCircle) annotation).setRectDifference(differences);
-        }
-    }
+    void generateNormalAppearance();
+
+    void generateRolloverAppearance();
 
-    /**
-     * Get a padded rectangle.
-     * 
-     * <p>Creates a new rectangle with padding applied to each side.
-     * .
-     * @param rectangle the rectangle.
-     * @param padding the padding to apply.
-     * @return the padded rectangle.
-     */
-    PDRectangle getPaddedRectangle(PDRectangle rectangle, float padding)
-    {
-        return new PDRectangle(rectangle.getLowerLeftX() + padding, rectangle.getLowerLeftY() + padding,
-                rectangle.getWidth() - 2 * padding, rectangle.getHeight() - 2 * padding);
-    }
+    void generateDownAppearance();
 }

Modified: pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDSquareAppearanceHandler.java
URL: http://svn.apache.org/viewvc/pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDSquareAppearanceHandler.java?rev=1745470&r1=1745469&r2=1745470&view=diff
==============================================================================
--- pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDSquareAppearanceHandler.java (original)
+++ pdfbox/trunk/pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/annotation/handlers/PDSquareAppearanceHandler.java Wed May 25 10:55:43 2016
@@ -17,7 +17,6 @@
 
 package org.apache.pdfbox.pdmodel.interactive.annotation.handlers;
 
-import java.awt.geom.AffineTransform;
 import java.io.IOException;
 
 import org.apache.pdfbox.cos.COSArray;
@@ -25,40 +24,41 @@ import org.apache.pdfbox.pdmodel.common.
 import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
 import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationSquareCircle;
 import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceContentStream;
-import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceEntry;
-import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream;
 import org.apache.pdfbox.pdmodel.interactive.annotation.PDBorderStyleDictionary;
 
 /**
  * Handler to generate the square annotations appearance.
  *
  */
-public class PDSquareAppearanceHandler extends PDAppearanceHandler
+public class PDSquareAppearanceHandler extends PDAbstractAppearanceHandler
 {
+    
     public PDSquareAppearanceHandler(PDAnnotation annotation)
     {
         super(annotation);
     }
+    
+    @Override
+    public void generateAppearanceStreams()
+    {
+        generateNormalAppearance();
+        generateRolloverAppearance();
+        generateDownAppearance();
+    }
 
     @Override
     public void generateNormalAppearance()
     {
-        PDAppearanceEntry appearanceEntry = getNormalAppearance();
-        PDAppearanceStream appearanceStream = appearanceEntry.getAppearanceStream();
         float lineWidth = getLineWidth();
         try
         {
-            PDAppearanceContentStream contentStream = new PDAppearanceContentStream(appearanceStream);
-            PDRectangle bbox = getRectangle();
-            appearanceStream.setBBox(bbox);
-            AffineTransform transform = AffineTransform.getTranslateInstance(-bbox.getLowerLeftX(),
-                    -bbox.getLowerLeftY());
-            appearanceStream.setMatrix(transform);
-
+            PDAppearanceContentStream contentStream = getNormalAppearanceAsContentStream();;
             contentStream.setStrokingColorOnDemand(getColor());
             boolean hasBackground = contentStream
                     .setNonStrokingColorOnDemand(((PDAnnotationSquareCircle) getAnnotation()).getInteriorColor());
 
+            handleOpacity(((PDAnnotationSquareCircle) getAnnotation()).getConstantOpacity());
+            
             contentStream.setBorderLine(lineWidth, ((PDAnnotationSquareCircle) getAnnotation()).getBorderStyle());
             
             // the differences rectangle
@@ -67,12 +67,12 @@ public class PDSquareAppearanceHandler e
             
             // Acrobat applies a padding to each side of the bbox so the line is completely within
             // the bbox.
-            PDRectangle borderEdge = getPaddedRectangle(bbox,lineWidth/2);
+            PDRectangle borderEdge = getPaddedRectangle(getRectangle(),lineWidth/2);
             contentStream.addRect(borderEdge.getLowerLeftX() , borderEdge.getLowerLeftY(),
                     borderEdge.getWidth(), borderEdge.getHeight());
-
+            
             contentStream.closePath(lineWidth, hasBackground);
-
+            
             contentStream.close();
         } catch (IOException e)
         {