]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
Merged revisions 674245,674267,674269,674272-674273,674276,674325,674468,674470-67447...
authorAdrian Cumiskey <acumiskey@apache.org>
Mon, 7 Jul 2008 12:48:50 +0000 (12:48 +0000)
committerAdrian Cumiskey <acumiskey@apache.org>
Mon, 7 Jul 2008 12:48:50 +0000 (12:48 +0000)
https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk

........
  r674245 | adelmelle | 2008-07-05 23:53:58 +0100 (Sat, 05 Jul 2008) | 1 line

  Fixed ClassCastException when specifying column-number on something other than a fo:table-column or fo:table-cell...
........
  r674267 | adelmelle | 2008-07-06 08:50:23 +0100 (Sun, 06 Jul 2008) | 1 line

  Switch AreaTreeParser to use a java.nio.CharBuffer, and ignore characters events for all elements other than <word>, <space> or <character>
........
  r674269 | adelmelle | 2008-07-06 09:15:50 +0100 (Sun, 06 Jul 2008) | 1 line

  Remove deprecated Character area class
........
  r674272 | adelmelle | 2008-07-06 09:44:54 +0100 (Sun, 06 Jul 2008) | 1 line

  Redo changes made in r674056...
........
  r674273 | adelmelle | 2008-07-06 09:46:50 +0100 (Sun, 06 Jul 2008) | 1 line

  Simplified implementation of Area.getTraitAsBoolean()
........
  r674276 | adelmelle | 2008-07-06 10:17:14 +0100 (Sun, 06 Jul 2008) | 3 lines

  Extracted conversion methods for String to int[] or double[] to a utility class.
  Made AreaTreeParser.getAttributeAsXXX() methods static to stress their utility character, and removed the private parseRect() in favor of getAttributeAsRectangle2D().
........
  r674325 | adelmelle | 2008-07-06 19:19:48 +0100 (Sun, 06 Jul 2008) | 1 line

  Fixed error; inadvertently switched the condition with r674272...
........
  r674468 | acumiskey | 2008-07-07 13:36:57 +0100 (Mon, 07 Jul 2008) | 1 line

  Possible NullPointerException avoided
........
  r674470 | acumiskey | 2008-07-07 13:38:04 +0100 (Mon, 07 Jul 2008) | 1 line

  Added new set accessor method for EncryptionParams.
........
  r674471 | acumiskey | 2008-07-07 13:42:12 +0100 (Mon, 07 Jul 2008) | 1 line

  Added PDF encryption parameter support in configuration.
........

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AFPGOCAResources@674476 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/trunk/configuration.xml
src/java/org/apache/fop/area/Area.java
src/java/org/apache/fop/area/AreaTreeParser.java
src/java/org/apache/fop/area/inline/Character.java [deleted file]
src/java/org/apache/fop/fo/flow/table/TableFObj.java
src/java/org/apache/fop/pdf/PDFDocument.java
src/java/org/apache/fop/render/AbstractRenderer.java
src/java/org/apache/fop/render/pdf/PDFRenderer.java
src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java
src/java/org/apache/fop/util/ConversionUtils.java [new file with mode: 0644]
status.xml

index e27ae94dfa5bbff540881b3ac6d267e00b195da0..81b4d40acd8849466649834ab7cc7d5f6ddf2ce8 100644 (file)
       
       <fonts....
       </renderer>]]></source>
+      
+      <p>FOP supports encryption of PDF output, thanks to Patrick C. Lankswert.
+      This feature is commonly used to prevent unauthorized viewing, printing, editing, copying text
+      from the document and doing annotations. It is also possible to ask the user for a password in
+      order to view the contents. Note that there already exist third party applications which can
+      decrypt an encrypted PDF without effort and allow the aforementioned operations, therefore the
+      degree of protection is limited.  For further information about features and restrictions
+      regarding PDF encryption, look at the documentation coming with Adobe Acrobat or the technical
+      documentation on the Adobe web site.</p>
+      <source><![CDATA[
+    <renderer mime="application/pdf">
+      <encryption-params>
+         <user-password>testuserpass</user-password>
+         <owner-password>testownerpass</owner-password>
+         <noprint/>
+         <nocopy/>
+         <noedit/>
+         <noannotations/>
+      </encryption-params>
+    </renderer>]]></source>
+      
     </section>
     <section id="ps-renderer">
       <title>Special Settings for the PostScript Renderer</title>
index 9c0fc8db629e54c410b3ad2fc0f13cad09946a62..ab9590685c436e6517b2787cec6560f1b26ed5b6 100644 (file)
@@ -417,17 +417,11 @@ public class Area extends AreaTreeObject implements Serializable {
     
     /**
      * Get a boolean trait from this area.
-     * 
      * @param oTraitCode the trait key
      * @return the trait value
      */
     public boolean getTraitAsBoolean(Object oTraitCode) {
-        final Object obj = getTrait(oTraitCode);
-        if (obj instanceof Boolean) {
-            return ((Boolean)obj).booleanValue();
-        } else {
-            return false;
-        }
+        return Boolean.TRUE.equals(getTrait(oTraitCode));
     }
 
     /**
index d48221c0a95d4edf0eda8854a0ba215a17f74927..6d9fd4f326500555aab9d8795843a4946fd8fbc1 100644 (file)
@@ -26,6 +26,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.Stack;
 import java.util.StringTokenizer;
+import java.nio.CharBuffer;
 
 import javax.xml.transform.Source;
 import javax.xml.transform.Transformer;
@@ -56,7 +57,6 @@ import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.area.Trait.Background;
 import org.apache.fop.area.Trait.InternalLink;
 import org.apache.fop.area.inline.AbstractTextArea;
-import org.apache.fop.area.inline.Character;
 import org.apache.fop.area.inline.ForeignObject;
 import org.apache.fop.area.inline.Image;
 import org.apache.fop.area.inline.InlineArea;
@@ -78,6 +78,7 @@ import org.apache.fop.traits.BorderProps;
 import org.apache.fop.util.ColorUtil;
 import org.apache.fop.util.ContentHandlerFactory;
 import org.apache.fop.util.ContentHandlerFactoryRegistry;
+import org.apache.fop.util.ConversionUtils;
 import org.apache.fop.util.DefaultErrorListener;
 
 /**
@@ -132,8 +133,10 @@ public class AreaTreeParser {
         private ElementMappingRegistry elementMappingRegistry;
 
         private Attributes lastAttributes;
-        private StringBuffer content = new StringBuffer();
 
+        private CharBuffer content = CharBuffer.allocate(64);
+        private boolean ignoreCharacters = true;
+        
         private PageViewport currentPageViewport;
         private Map pageViewportsByKey = new java.util.HashMap();
         // set of "ID firsts" that have already been assigned to a PV:
@@ -176,7 +179,6 @@ public class AreaTreeParser {
             makers.put("text", new TextMaker());
             makers.put("word", new WordMaker());
             makers.put("space", new SpaceMaker());
-            makers.put("char", new CharMaker());
             makers.put("leader", new LeaderMaker());
             makers.put("viewport", new ViewportMaker());
             makers.put("image", new ImageMaker());
@@ -186,15 +188,6 @@ public class AreaTreeParser {
             makers.put("destination", new DestinationMaker());
         }
 
-        private static Rectangle2D parseRect(String rect) {
-            StringTokenizer tokenizer = new StringTokenizer(rect, " ");
-            return new Rectangle2D.Double(
-                    Double.parseDouble(tokenizer.nextToken()),
-                    Double.parseDouble(tokenizer.nextToken()),
-                    Double.parseDouble(tokenizer.nextToken()),
-                    Double.parseDouble(tokenizer.nextToken()));
-        }
-
         private Area findAreaType(Class clazz) {
             if (areaStack.size() > 0) {
                 int pos = areaStack.size() - 1;
@@ -261,7 +254,10 @@ public class AreaTreeParser {
                 boolean handled = true;
                 if ("".equals(uri)) {
                     Maker maker = (Maker)makers.get(localName);
+                    content.clear();
+                    ignoreCharacters = true;
                     if (maker != null) {
+                        ignoreCharacters = maker.ignoreCharacters();
                         maker.startElement(attributes);
                     } else if ("extension-attachments".equals(localName)) {
                         //TODO implement me
@@ -311,11 +307,12 @@ public class AreaTreeParser {
                     Maker maker = (Maker)makers.get(localName);
                     if (maker != null) {
                         maker.endElement();
+                        content.clear();
                     }
+                    ignoreCharacters = true;
                 } else {
                     //log.debug("Ignoring " + localName + " in namespace: " + uri);
                 }
-                content.setLength(0); //Reset text buffer (see characters())
             }
         }
 
@@ -324,6 +321,7 @@ public class AreaTreeParser {
         private static interface Maker {
             void startElement(Attributes attributes) throws SAXException;
             void endElement();
+            boolean ignoreCharacters();
         }
 
         private abstract class AbstractMaker implements Maker {
@@ -335,6 +333,10 @@ public class AreaTreeParser {
             public void endElement() {
                 //nop
             }
+            
+            public boolean ignoreCharacters() {
+                return true;
+            }
         }
 
         private class AreaTreeMaker extends AbstractMaker {
@@ -384,7 +386,7 @@ public class AreaTreeParser {
                 if (currentPageViewport != null) {
                     throw new IllegalStateException("currentPageViewport must be null");
                 }
-                Rectangle2D viewArea = parseRect(attributes.getValue("bounds"));
+                Rectangle2D viewArea = getAttributeAsRectangle2D(attributes, "bounds");
                 int pageNumber = getAttributeAsInteger(attributes, "nr", -1);
                 String key = attributes.getValue("key");
                 String pageNumberString = attributes.getValue("formatted-nr");
@@ -420,7 +422,7 @@ public class AreaTreeParser {
                 if (rv != null) {
                     throw new IllegalStateException("Current RegionViewport must be null");
                 }
-                Rectangle2D viewArea = parseRect(attributes.getValue("rect"));
+                Rectangle2D viewArea = getAttributeAsRectangle2D(attributes, "rect");
                 rv = new RegionViewport(viewArea);
                 transferForeignObjects(attributes, rv);
                 rv.setClip(getAttributeAsBoolean(attributes, "clipped", false));
@@ -444,7 +446,7 @@ public class AreaTreeParser {
             
             public void endElement() {
                 assertObjectOfClass(areaStack.pop(), RegionReference.class);
-            }            
+            }
         }
 
         private class RegionAfterMaker extends AbstractMaker {
@@ -455,7 +457,7 @@ public class AreaTreeParser {
 
             public void endElement() {
                 assertObjectOfClass(areaStack.pop(), RegionReference.class);
-            }            
+            }
         }
 
         private class RegionStartMaker extends AbstractMaker {
@@ -466,7 +468,7 @@ public class AreaTreeParser {
 
             public void endElement() {
                 assertObjectOfClass(areaStack.pop(), RegionReference.class);
-            }            
+            }
         }
         
         private class RegionEndMaker extends AbstractMaker {
@@ -477,7 +479,7 @@ public class AreaTreeParser {
 
             public void endElement() {
                 assertObjectOfClass(areaStack.pop(), RegionReference.class);
-            }            
+            }
         }
 
         private class RegionBodyMaker extends AbstractMaker {
@@ -575,7 +577,7 @@ public class AreaTreeParser {
             
             public void endElement() {
                 assertObjectOfClass(areaStack.pop(), BeforeFloat.class);
-            }            
+            }
         }
 
         private class BlockMaker extends AbstractMaker {
@@ -627,7 +629,7 @@ public class AreaTreeParser {
             
             public void endElement() {
                 assertObjectOfClass(areaStack.pop(), Block.class);
-            }            
+            }
         }
 
         private class LineAreaMaker extends AbstractMaker {
@@ -735,47 +737,37 @@ public class AreaTreeParser {
             
             public void endElement() {
                 assertObjectOfClass(areaStack.pop(), TextArea.class);
-            }            
+            }
         }
 
         private class WordMaker extends AbstractMaker {
 
-            private int[] toIntArray(String s) {
-                if (s == null || s.length() == 0) {
-                    return null;
-                }
-                StringTokenizer tokenizer = new StringTokenizer(s, " ");
-                List values = new java.util.ArrayList();
-                while (tokenizer.hasMoreTokens()) {
-                    values.add(new Integer(tokenizer.nextToken()));
-                }
-                int[] res = new int[values.size()];
-                for (int i = 0, c = res.length; i < c; i++) {
-                    res[i] = ((Integer)values.get(i)).intValue();
-                }
-                return res;
-            }
-            
             public void endElement() {
                 int offset = getAttributeAsInteger(lastAttributes, "offset", 0);
-                int[] letterAdjust = toIntArray(lastAttributes.getValue("letter-adjust"));
-                String txt = content.toString();
-                WordArea word = new WordArea(txt, offset, letterAdjust);
+                int[] letterAdjust 
+                        = ConversionUtils.toIntArray(
+                            lastAttributes.getValue("letter-adjust"), "\\s");
+                content.flip();
+                WordArea word = new WordArea(content.toString().trim(), offset, letterAdjust);
                 AbstractTextArea text = getCurrentText();
                 word.setParentArea(text);
                 text.addChildArea(word);
-            }            
+            }
+            
+            public boolean ignoreCharacters() {
+                return false;
+            }
         }
 
         private class SpaceMaker extends AbstractMaker {
-
+            
             public void endElement() {
                 int offset = getAttributeAsInteger(lastAttributes, "offset", 0);
-                String txt = content.toString();
                 //TODO the isAdjustable parameter is currently not used/implemented
-                if (txt.length() > 0) {
+                if (content.position() > 0) {
+                    content.flip();
                     boolean adjustable = getAttributeAsBoolean(lastAttributes, "adj", true);
-                    SpaceArea space = new SpaceArea(txt.charAt(0), offset, adjustable);
+                    SpaceArea space = new SpaceArea(content.charAt(0), offset, adjustable);
                     AbstractTextArea text = getCurrentText();
                     space.setParentArea(text);
                     text.addChildArea(space);
@@ -789,25 +781,11 @@ public class AreaTreeParser {
                     Area parent = (Area)areaStack.peek();
                     parent.addChildArea(space);
                 }
-            }            
-        }
-
-        private class CharMaker extends AbstractMaker {
-
-            public void endElement() {
-                String txt = content.toString();
-                Character ch = new Character(txt.charAt(0));
-                transferForeignObjects(lastAttributes, ch);
-                setAreaAttributes(lastAttributes, ch);
-                setTraits(lastAttributes, ch, SUBSET_COMMON);
-                setTraits(lastAttributes, ch, SUBSET_BOX);
-                setTraits(lastAttributes, ch, SUBSET_COLOR);
-                setTraits(lastAttributes, ch, SUBSET_FONT);
-                ch.setOffset(getAttributeAsInteger(lastAttributes, "offset", 0));
-                ch.setBaselineOffset(getAttributeAsInteger(lastAttributes, "baseline", 0));
-                Area parent = (Area)areaStack.peek();
-                parent.addChildArea(ch);
-            }            
+            }
+            
+            public boolean ignoreCharacters() {
+                return false;
+            }
         }
 
         private class LeaderMaker extends AbstractMaker {
@@ -830,9 +808,6 @@ public class AreaTreeParser {
                 Area parent = (Area)areaStack.peek();
                 parent.addChildArea(leader);
             }
-            
-            public void endElement() {
-            }            
         }
 
         private class ViewportMaker extends AbstractMaker {
@@ -854,7 +829,7 @@ public class AreaTreeParser {
             
             public void endElement() {
                 assertObjectOfClass(areaStack.pop(), Viewport.class);
-            }            
+            }
         }
         
         private class ImageMaker extends AbstractMaker {
@@ -1097,7 +1072,7 @@ public class AreaTreeParser {
             }
         }
 
-        private boolean getAttributeAsBoolean(Attributes attributes, String name,
+        private static boolean getAttributeAsBoolean(Attributes attributes, String name,
                 boolean defaultValue) {
             String s = attributes.getValue(name);
             if (s == null) {
@@ -1107,7 +1082,7 @@ public class AreaTreeParser {
             }
         }
 
-        private int getAttributeAsInteger(Attributes attributes, String name, 
+        private static int getAttributeAsInteger(Attributes attributes, String name, 
                 int defaultValue) {
             String s = attributes.getValue(name);
             if (s == null) {
@@ -1117,36 +1092,30 @@ public class AreaTreeParser {
             }
         }
 
-        private CTM getAttributeAsCTM(Attributes attributes, String name) {
+        private static CTM getAttributeAsCTM(Attributes attributes, String name) {
             String s = attributes.getValue(name).trim();
             if (s.startsWith("[") && s.endsWith("]")) {
                 s = s.substring(1, s.length() - 1);
-                StringTokenizer tokenizer = new StringTokenizer(s, " ");
-                double[] values = new double[] {
-                        Double.parseDouble(tokenizer.nextToken()),
-                        Double.parseDouble(tokenizer.nextToken()),
-                        Double.parseDouble(tokenizer.nextToken()),
-                        Double.parseDouble(tokenizer.nextToken()),
-                        Double.parseDouble(tokenizer.nextToken()),
-                        Double.parseDouble(tokenizer.nextToken())};
+                double[] values = ConversionUtils.toDoubleArray(s, "\\s");
+                if (values.length != 6) {
+                    throw new IllegalArgumentException("CTM must consist of 6 double values!");
+                }
                 return new CTM(values[0], values[1], values[2], values[3], values[4], values[5]);
             } else {
-                throw new IllegalArgumentException("CTM must be surrounded by square brackets");
+                throw new IllegalArgumentException("CTM must be surrounded by square brackets!");
             }
         }
 
-        private Rectangle2D getAttributeAsRectangle2D(Attributes attributes, String name) {
+        private static Rectangle2D getAttributeAsRectangle2D(Attributes attributes, String name) {
             String s = attributes.getValue(name).trim();
-            StringTokenizer tokenizer = new StringTokenizer(s, " ");
-            double[] values = new double[] {
-                    Double.parseDouble(tokenizer.nextToken()),
-                    Double.parseDouble(tokenizer.nextToken()),
-                    Double.parseDouble(tokenizer.nextToken()),
-                    Double.parseDouble(tokenizer.nextToken())};
+            double[] values = ConversionUtils.toDoubleArray(s, "\\s");
+            if (values.length != 4) {
+                throw new IllegalArgumentException("Rectangle must consist of 4 double values!");
+            }
             return new Rectangle2D.Double(values[0], values[1], values[2], values[3]);
         }
 
-        private void transferForeignObjects(Attributes atts, AreaTreeObject ato) {
+        private static void transferForeignObjects(Attributes atts, AreaTreeObject ato) {
             for (int i = 0, c = atts.getLength(); i < c; i++) {
                 String ns = atts.getURI(i);
                 if (ns.length() > 0) {
@@ -1163,11 +1132,25 @@ public class AreaTreeParser {
         public void characters(char[] ch, int start, int length) throws SAXException {
             if (delegate != null) {
                 delegate.characters(ch, start, length);
-            } else {
-                content.append(ch, start, length);
+            } else if (!ignoreCharacters) {
+                int maxLength = this.content.capacity() - this.content.position();
+                if (maxLength < length) {
+                    // allocate a larger buffer and transfer content
+                    CharBuffer newContent 
+                            = CharBuffer.allocate(this.content.position() + length);
+                    this.content.flip();
+                    newContent.put(this.content);
+                    this.content = newContent;
+                }
+                // make sure the full capacity is used
+                this.content.limit(this.content.capacity());
+                // add characters to the buffer
+                this.content.put(ch, start, length);
+                // decrease the limit, if necessary
+                if (this.content.position() < this.content.limit()) {
+                    this.content.limit(this.content.position());
+                }
             }
         }
-
     }
-
 }
diff --git a/src/java/org/apache/fop/area/inline/Character.java b/src/java/org/apache/fop/area/inline/Character.java
deleted file mode 100644 (file)
index 6b6f974..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
- *      http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.area.inline;
-
-/**
- * Single character inline area.
- * This inline area holds a single character.
- * @deprecated A TextArea with a single WordArea as its child should be used instead.
- */
-public class Character extends AbstractTextArea {
-    // use a String instead of a character because if this character
-    // ends a syllable the hyphenation character must be added
-    private String character;
-
-    /**
-     * Create a new character inline area with the given character.
-     *
-     * @param ch the character for this inline area
-     */
-    public Character(char ch) {
-        character = new String() + ch;
-    }
-
-    /**
-     * Get the character for this inline character area.
-     *
-     * @return the character
-     */
-    public String getChar() {
-        return character;
-    }
-
-    /**
-     * Add the hyphenation character and its length.
-     *
-     * @param hyphChar the hyphenation character
-     * @param hyphSize the size of the hyphenation character
-     */
-    public void addHyphen(char hyphChar, int hyphSize) {
-        character += hyphChar;
-        this.setIPD(this.getIPD() + hyphSize);
-    }
-
-}
-
index 370bb9de49c26116de9311af5a35e10f16103032..faf1f7aba5d877f0595aa34fdb11910adc9b53c1 100644 (file)
@@ -55,9 +55,10 @@ public abstract class TableFObj extends FObj {
     CollapsingBorderModel collapsingBorderModel;
 
     /**
-     * Main constructor
+     * Create a TableFObj instance that is a child
+     * of the given {@link FONode}
      *
-     * @param parent    the parent node
+     * @param parent the parent {@link FONode}
      */
     public TableFObj(FONode parent) {
         super(parent);
@@ -81,6 +82,8 @@ public abstract class TableFObj extends FObj {
     }
 
     /**
+     * Return the value for the "border-precedence" property
+     * for the given side.
      *
      * @param side  the side for which to return the border precedence
      * @return the "border-precedence" value for the given side
@@ -102,13 +105,13 @@ public abstract class TableFObj extends FObj {
 
     /**
      * Convenience method to returns a reference
-     * to the base Table instance
+     * to the base {@link Table} instance.
      *
      * @return  the base table instance
      *
      */
     public Table getTable() {
-        // Will be overridden in Table; for any other Table-node, recursive call to
+        // Overridden in Table; for any other Table-node, recursive call to
         // parent.getTable()
         return ((TableFObj) parent).getTable();
     }
@@ -119,13 +122,13 @@ public abstract class TableFObj extends FObj {
     public abstract CommonBorderPaddingBackground getCommonBorderPaddingBackground();
 
     /**
-     * PropertyMaker subclass for the column-number property
-     *
+     * {@link PropertyMaker} subclass for the column-number property
      */
     public static class ColumnNumberPropertyMaker extends PropertyMaker {
 
         /**
          * Constructor
+         *
          * @param propId    the id of the property for which the maker should
          *                  be created
          */
@@ -144,46 +147,50 @@ public abstract class TableFObj extends FObj {
 
 
         /**
+         * {@inheritDoc}
          * Check the value of the column-number property.
-         * Return the parent's column index (initial value) in case
-         * of a negative or zero value
-         *
-         * @see org.apache.fop.fo.properties.PropertyMaker#make(PropertyList, String, FObj)
          */
         public Property make(PropertyList propertyList, String value, FObj fo)
                     throws PropertyException {
+
             Property p = super.make(propertyList, value, fo);
 
-            ColumnNumberManagerHolder parent
-                    = (ColumnNumberManagerHolder) propertyList.getParentFObj();
-            ColumnNumberManager columnIndexManager =  parent.getColumnNumberManager();
             int columnIndex = p.getNumeric().getValue();
             int colSpan = propertyList.get(Constants.PR_NUMBER_COLUMNS_SPANNED)
                                 .getNumeric().getValue();
-            
-            int lastIndex = columnIndex - 1 + colSpan;
-            for (int i = columnIndex; i <= lastIndex; ++i) {
-                if (columnIndexManager.isColumnNumberUsed(i)) {
-                    /* if column-number is already in use by another
-                     * cell/column => error!
-                     */
-                    TableEventProducer eventProducer = TableEventProducer.Provider.get(
-                            fo.getUserAgent().getEventBroadcaster());
-                    eventProducer.cellOverlap(this, propertyList.getFObj().getName(),
-                                                i, fo.getLocator());
+
+            // only check whether the column-number is occupied in case it was
+            // specified on a fo:table-cell or fo:table-column
+            int foId = propertyList.getFObj().getNameId();
+            if (foId == FO_TABLE_COLUMN || foId == FO_TABLE_CELL) {
+                ColumnNumberManagerHolder parent
+                        = (ColumnNumberManagerHolder) propertyList.getParentFObj();
+                ColumnNumberManager columnIndexManager = parent.getColumnNumberManager();
+                int lastIndex = columnIndex - 1 + colSpan;
+                for (int i = columnIndex; i <= lastIndex; ++i) {
+                    if (columnIndexManager.isColumnNumberUsed(i)) {
+                        /* if column-number is already in use by another
+                         * cell/column => error!
+                         */
+                        TableEventProducer eventProducer
+                                = TableEventProducer.Provider.get(
+                                    fo.getUserAgent().getEventBroadcaster());
+                        eventProducer.cellOverlap(
+                                this, propertyList.getFObj().getName(),
+                                i, propertyList.getFObj().getLocator());
+                    }
                 }
             }
-
             return p;
         }
-        
+
         /**
-         * If the value is not positive, return a property whose value is the next column number
-         * 
          * {@inheritDoc}
+         * If the value is not positive, return a property whose value
+         * is the next column number.
          */
-        public Property convertProperty(Property p, 
-                                        PropertyList propertyList, FObj fo) 
+        public Property convertProperty(Property p,
+                                        PropertyList propertyList, FObj fo)
                     throws PropertyException {
             if (p instanceof EnumProperty) {
                 return EnumNumber.getInstance(p);
@@ -191,15 +198,24 @@ public abstract class TableFObj extends FObj {
             Number val = p.getNumber();
             if (val != null) {
                 int i = Math.round(val.floatValue());
+                int foId = propertyList.getFObj().getNameId();
                 if (i <= 0) {
-                    ColumnNumberManagerHolder parent =
-                        (ColumnNumberManagerHolder) propertyList.getParentFObj();
-                    ColumnNumberManager columnIndexManager =  parent.getColumnNumberManager();
-                    i = columnIndexManager.getCurrentColumnNumber();
+                    if (foId == FO_TABLE_CELL || foId == FO_TABLE_COLUMN) {
+                        ColumnNumberManagerHolder parent =
+                            (ColumnNumberManagerHolder) propertyList.getParentFObj();
+                        ColumnNumberManager columnIndexManager = parent.getColumnNumberManager();
+                        i = columnIndexManager.getCurrentColumnNumber();
+                    } else {
+                        /* very exceptional case:
+                         * negative column-number specified on
+                         * a FO that is not a fo:table-cell or fo:table-column
+                         */
+                        i = 1;
+                    }
                     TableEventProducer eventProducer =
                         TableEventProducer.Provider.get(fo.getUserAgent().getEventBroadcaster());
                     eventProducer.forceNextColumnNumber(this, propertyList.getFObj().getName(),
-                                                        val, i, fo.getLocator());
+                                                        val, i, propertyList.getFObj().getLocator());
                 }
                 return NumberProperty.getInstance(i);
             }
@@ -233,26 +249,26 @@ public abstract class TableFObj extends FObj {
     /**
      * Creates a BorderSpecification from the border set on the given side. If no border
      * is set, a BorderSpecification with border-style none is created.
-     * 
+     *
      * @param side one of CommonBorderPaddingBackground.BEFORE|AFTER|START|END
      */
     private void createBorder(int side) {
         BorderSpecification borderSpec = new BorderSpecification(
                 getCommonBorderPaddingBackground().getBorderInfo(side), getNameId());
         switch (side) {
-        case CommonBorderPaddingBackground.BEFORE:
-            borderBefore = new ConditionalBorder(borderSpec, collapsingBorderModel);
-            break;
-        case CommonBorderPaddingBackground.AFTER:
-            borderAfter = new ConditionalBorder(borderSpec, collapsingBorderModel);
-            break;
-        case CommonBorderPaddingBackground.START:
-            borderStart = borderSpec;
-            break;
-        case CommonBorderPaddingBackground.END:
-            borderEnd = borderSpec;
-            break;
-        default: assert false;
+            case CommonBorderPaddingBackground.BEFORE:
+                borderBefore = new ConditionalBorder(borderSpec, collapsingBorderModel);
+                break;
+            case CommonBorderPaddingBackground.AFTER:
+                borderAfter = new ConditionalBorder(borderSpec, collapsingBorderModel);
+                break;
+            case CommonBorderPaddingBackground.START:
+                borderStart = borderSpec;
+                break;
+            case CommonBorderPaddingBackground.END:
+                borderEnd = borderSpec;
+                break;
+            default: assert false;
         }
     }
 }
index bd44595fba5cd420580ac58adfe0d1db37453c09..020a594b48e9f7241907f4fa2f9c537623deb9be 100644 (file)
@@ -528,10 +528,10 @@ public class PDFDocument {
     public void setEncryption(PDFEncryptionParams params) {
         getProfile().verifyEncryptionAllowed();
         this.encryption = PDFEncryptionManager.newInstance(++this.objectcount, params);
-        ((PDFObject)this.encryption).setDocument(this);
         if (encryption != null) {
-            /**@todo this cast is ugly. PDFObject should be transformed to an interface. */
-            addTrailerObject((PDFObject)this.encryption);
+            PDFObject pdfObject = (PDFObject)encryption;
+            pdfObject.setDocument(this);
+            addTrailerObject(pdfObject);
         } else {
             log.warn(
                 "PDF encryption is unavailable. PDF will be "
index 5c3e73ee0ec39589219fd8c57774d93ba04ce9c0..ebff5323bb805b1209d53e24432c4d4e5eed2353 100644 (file)
@@ -54,7 +54,6 @@ import org.apache.fop.area.RegionReference;
 import org.apache.fop.area.RegionViewport;
 import org.apache.fop.area.Span;
 import org.apache.fop.area.Trait;
-import org.apache.fop.area.inline.Character;
 import org.apache.fop.area.inline.Container;
 import org.apache.fop.area.inline.ForeignObject;
 import org.apache.fop.area.inline.Image;
@@ -405,7 +404,7 @@ public abstract class AbstractRenderer
         for (int count = 0; count < spans.size(); count++) {
             span = (Span) spans.get(count);
             for (int c = 0; c < span.getColumnCount(); c++) {
-                NormalFlow flow = (NormalFlow) span.getNormalFlow(c);
+                NormalFlow flow = span.getNormalFlow(c);
 
                 if (flow != null) {
                     currentBPPosition = saveSpanBPPos;
@@ -638,15 +637,6 @@ public abstract class AbstractRenderer
         }
     }
 
-    /**
-     * Render the given Character.
-     * @param ch the character to render
-     * @deprecated Only TextArea should be used. This method will be removed eventually.
-     */
-    protected void renderCharacter(Character ch) {
-        currentIPPosition += ch.getAllocIPD();
-    }
-
     /** 
      * Common method to render the background and borders for any inline area.
      * The all borders and padding are drawn outside the specified area.
@@ -754,6 +744,8 @@ public abstract class AbstractRenderer
             renderContainer((Container) content);
         } else if (content instanceof ForeignObject) {
             renderForeignObject((ForeignObject) content, contpos);
+        } else if (content instanceof InlineBlockParent) {
+            renderInlineBlockParent((InlineBlockParent) content);
         }
         currentIPPosition += viewport.getAllocIPD();
         currentBPPosition = saveBP;
@@ -792,7 +784,7 @@ public abstract class AbstractRenderer
      * @param pos  The target position of the foreign object
      * (todo) Make renderForeignObject() protected
      */
-    public void renderForeignObject(ForeignObject fo, Rectangle2D pos) {
+    protected void renderForeignObject(ForeignObject fo, Rectangle2D pos) {
         // Default: do nothing.
         // Some renderers (ex. Text) don't support foreign objects.
     }
@@ -817,8 +809,9 @@ public abstract class AbstractRenderer
                 handler.handleXML(ctx, doc, namespace);
             } catch (Exception e) {
                 // could not handle document
-                ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
-                        ctx.getUserAgent().getEventBroadcaster());
+                ResourceEventProducer eventProducer 
+                        = ResourceEventProducer.Provider.get(
+                            ctx.getUserAgent().getEventBroadcaster());
                 eventProducer.foreignXMLProcessingError(this, doc, namespace, e);
             }
         } else {
@@ -871,5 +864,4 @@ public abstract class AbstractRenderer
         matrix[5] = matrix[5] * 1000;
         return new AffineTransform(matrix);
     }
-    
 }
index 0723d62f0057b262c1818050eee7d5ac11332e88..ff0e64806512f6c9a02a85f8fec7bf50f6b51bc5 100644 (file)
@@ -1842,5 +1842,13 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
     public void setFilterMap(Map filterMap) {
         this.filterMap = filterMap;
     }
+
+    /**
+     * Sets the encryption parameters used by the PDF renderer.
+     * @param encryptionParams the encryption parameters 
+     */
+    public void setEncryptionParams(PDFEncryptionParams encryptionParams) {
+        this.encryptionParams = encryptionParams;
+    }
 }
 
index 2fce8859a1f0b90b57ad40c0de9809db04d427bc..51e13dde14b7720f662c1e861688e7da391e6de6 100644 (file)
@@ -28,6 +28,7 @@ import org.apache.avalon.framework.configuration.ConfigurationException;
 import org.apache.fop.apps.FOPException;
 import org.apache.fop.apps.FOUserAgent;
 import org.apache.fop.pdf.PDFAMode;
+import org.apache.fop.pdf.PDFEncryptionParams;
 import org.apache.fop.pdf.PDFFilterList;
 import org.apache.fop.pdf.PDFXMode;
 import org.apache.fop.render.PrintRendererConfigurator;
@@ -78,13 +79,54 @@ public class PDFRendererConfigurator extends PrintRendererConfigurator {
             if (s != null) {
                 pdfRenderer.setXMode(PDFXMode.valueOf(s));
             }
+            Configuration encryptionParamsConfig = cfg.getChild(PDFRenderer.ENCRYPTION_PARAMS, false);
+            if (encryptionParamsConfig != null) {
+                PDFEncryptionParams encryptionParams = new PDFEncryptionParams();
+                Configuration ownerPasswordConfig = encryptionParamsConfig.getChild(
+                        PDFRenderer.OWNER_PASSWORD, false);
+                if (ownerPasswordConfig != null) {
+                    String ownerPassword = ownerPasswordConfig.getValue(null);
+                    if (ownerPassword != null) {
+                        encryptionParams.setOwnerPassword(ownerPassword);
+                    }
+                }
+                Configuration userPasswordConfig = encryptionParamsConfig.getChild(
+                        PDFRenderer.USER_PASSWORD, false);
+                if (userPasswordConfig != null) {
+                    String userPassword = userPasswordConfig.getValue(null);
+                    if (userPassword != null) {
+                        encryptionParams.setUserPassword(userPassword);
+                    }
+                }
+                Configuration noPrintConfig = encryptionParamsConfig.getChild(
+                        PDFRenderer.NO_PRINT, false);
+                if (noPrintConfig != null) {
+                    encryptionParams.setAllowPrint(false);
+                }
+                Configuration noCopyContentConfig = encryptionParamsConfig.getChild(
+                        PDFRenderer.NO_COPY_CONTENT, false);
+                if (noCopyContentConfig != null) {
+                    encryptionParams.setAllowCopyContent(false);
+                }
+                Configuration noEditContentConfig = encryptionParamsConfig.getChild(
+                        PDFRenderer.NO_EDIT_CONTENT, false);
+                if (noEditContentConfig != null) {
+                    encryptionParams.setAllowEditContent(false);
+                }
+                Configuration noAnnotationsConfig = encryptionParamsConfig.getChild(
+                        PDFRenderer.NO_ANNOTATIONS, false);
+                if (noAnnotationsConfig != null) {
+                    encryptionParams.setAllowEditAnnotations(false);
+                }
+                pdfRenderer.setEncryptionParams(encryptionParams);
+            }
             s = cfg.getChild(PDFRenderer.KEY_OUTPUT_PROFILE, true).getValue(null);
             if (s != null) {
                 pdfRenderer.setOutputProfileURI(s);
             }
-            Configuration child = cfg.getChild(PDFRenderer.KEY_DISABLE_SRGB_COLORSPACE, false);
-            if (child != null) {
-                pdfRenderer.disableSRGBColorSpace = child.getValueAsBoolean(false);
+            Configuration disableColorSpaceConfig = cfg.getChild(PDFRenderer.KEY_DISABLE_SRGB_COLORSPACE, false);
+            if (disableColorSpaceConfig != null) {
+                pdfRenderer.disableSRGBColorSpace = disableColorSpaceConfig.getValueAsBoolean(false);
             }
         }
     }
diff --git a/src/java/org/apache/fop/util/ConversionUtils.java b/src/java/org/apache/fop/util/ConversionUtils.java
new file mode 100644 (file)
index 0000000..e2d93fb
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* $Id$ */
+package org.apache.fop.util;
+
+/**
+ * This class contains utility methods for conversions, like
+ * a java.lang.String to an array of int or double.
+ */
+public final class ConversionUtils {
+
+    /**
+     * Converts the given base <code>String</code> into
+     * an array of <code>int</code>, splitting the base along the
+     * given separator pattern.
+     * <em>Note: this method assumes the input is a string containing 
+     * only decimal integers, signed or unsigned, that are parsable
+     * by <code>java.lang.Integer.parseInt(String)</code>. If this
+     * is not the case, the resulting <code>NumberFormatException</code>
+     * will have to be handled by the caller.</em>
+     * 
+     * @param baseString    the base string
+     * @param separatorPattern  the pattern separating the integer values
+     *        (if this is <code>null</code>, the baseString is parsed as one
+     *         integer value) 
+     * @return  an array of <code>int</code> whose size is equal to the number
+     *          values in the input string; <code>null</code> if this number
+     *          is equal to zero.
+     */
+    public static int[] toIntArray(String baseString, String separatorPattern) {
+        
+        if (baseString == null || "".equals(baseString)) {
+            return null;
+        }
+        
+        if (separatorPattern == null || "".equals(separatorPattern)) {
+            return new int[] { Integer.parseInt(baseString) };
+        }
+        
+        String[] values = baseString.split(separatorPattern);
+        int numValues = values.length;
+        if (numValues == 0) {
+            return null;
+        }
+        
+        int[] returnArray = new int[numValues];
+        for (int i = 0; i < numValues; ++i) {
+            returnArray[i] = Integer.parseInt(values[i]);
+        }
+        return returnArray;
+        
+    }
+
+    /**
+     * Converts the given base <code>String</code> into
+     * an array of <code>double</code>, splitting the base along the
+     * given separator pattern.
+     * <em>Note: this method assumes the input is a string containing 
+     * only decimal doubles, signed or unsigned, that are parsable
+     * by <code>java.lang.Double.parseDouble(String)</code>. If this
+     * is not the case, the resulting <code>NumberFormatException</code>
+     * will have to be handled by the caller.</em>
+     * 
+     * @param baseString    the base string
+     * @param separatorPattern  the pattern separating the integer values
+     *        (if this is <code>null</code>, the baseString is parsed as one
+     *         double value) 
+     * @return  an array of <code>double</code> whose size is equal to the number
+     *          values in the input string; <code>null</code> if this number
+     *          is equal to zero.
+     */
+    public static double[] toDoubleArray(String baseString, String separatorPattern) {
+        
+        if (baseString == null || "".equals(baseString)) {
+            return null;
+        }
+        
+        if (separatorPattern == null || "".equals(separatorPattern)) {
+            return new double[] { Double.parseDouble(baseString) };
+        }
+        
+        String[] values = baseString.split(separatorPattern);
+        int numValues = values.length;
+        if (numValues == 0) {
+            return null;
+        }
+        
+        double[] returnArray = new double[numValues];
+        for (int i = 0; i < numValues; ++i) {
+            returnArray[i] = Double.parseDouble(values[i]);
+        }
+        return returnArray;
+        
+    }
+    
+}
index 42996789e53c075e03172b830145a66c08676dd3..6f22165c5121d0707d0eaa603debdeac652868f9 100644 (file)
@@ -53,6 +53,9 @@
   
   <changes>
     <release version="FOP Trunk" date="TBD">
+      <action context="Renderers" dev="AC" type="add">
+        Added PDF encryption parameter support in configuration.
+      </action>
       <action context="Layout" dev="LF" type="add">
         Allowing non-zero borders and padding on page regions when
         relaxed validation is turned on.