aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/documentation/content/xdocs/trunk/configuration.xml21
-rw-r--r--src/java/org/apache/fop/area/Area.java8
-rw-r--r--src/java/org/apache/fop/area/AreaTreeParser.java169
-rw-r--r--src/java/org/apache/fop/area/inline/Character.java62
-rw-r--r--src/java/org/apache/fop/fo/flow/table/TableFObj.java114
-rw-r--r--src/java/org/apache/fop/pdf/PDFDocument.java6
-rw-r--r--src/java/org/apache/fop/render/AbstractRenderer.java22
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFRenderer.java8
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java48
-rw-r--r--src/java/org/apache/fop/util/ConversionUtils.java110
-rw-r--r--status.xml3
11 files changed, 339 insertions, 232 deletions
diff --git a/src/documentation/content/xdocs/trunk/configuration.xml b/src/documentation/content/xdocs/trunk/configuration.xml
index e27ae94df..81b4d40ac 100644
--- a/src/documentation/content/xdocs/trunk/configuration.xml
+++ b/src/documentation/content/xdocs/trunk/configuration.xml
@@ -294,6 +294,27 @@
<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>
diff --git a/src/java/org/apache/fop/area/Area.java b/src/java/org/apache/fop/area/Area.java
index 9c0fc8db6..ab9590685 100644
--- a/src/java/org/apache/fop/area/Area.java
+++ b/src/java/org/apache/fop/area/Area.java
@@ -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));
}
/**
diff --git a/src/java/org/apache/fop/area/AreaTreeParser.java b/src/java/org/apache/fop/area/AreaTreeParser.java
index d48221c0a..6d9fd4f32 100644
--- a/src/java/org/apache/fop/area/AreaTreeParser.java
+++ b/src/java/org/apache/fop/area/AreaTreeParser.java
@@ -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
index 6b6f9744f..000000000
--- a/src/java/org/apache/fop/area/inline/Character.java
+++ /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);
- }
-
-}
-
diff --git a/src/java/org/apache/fop/fo/flow/table/TableFObj.java b/src/java/org/apache/fop/fo/flow/table/TableFObj.java
index 370bb9de4..faf1f7aba 100644
--- a/src/java/org/apache/fop/fo/flow/table/TableFObj.java
+++ b/src/java/org/apache/fop/fo/flow/table/TableFObj.java
@@ -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;
}
}
}
diff --git a/src/java/org/apache/fop/pdf/PDFDocument.java b/src/java/org/apache/fop/pdf/PDFDocument.java
index bd44595fb..020a594b4 100644
--- a/src/java/org/apache/fop/pdf/PDFDocument.java
+++ b/src/java/org/apache/fop/pdf/PDFDocument.java
@@ -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 "
diff --git a/src/java/org/apache/fop/render/AbstractRenderer.java b/src/java/org/apache/fop/render/AbstractRenderer.java
index 5c3e73ee0..ebff5323b 100644
--- a/src/java/org/apache/fop/render/AbstractRenderer.java
+++ b/src/java/org/apache/fop/render/AbstractRenderer.java
@@ -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);
}
-
}
diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java
index 0723d62f0..ff0e64806 100644
--- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java
+++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java
@@ -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;
+ }
}
diff --git a/src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java b/src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java
index 2fce8859a..51e13dde1 100644
--- a/src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java
+++ b/src/java/org/apache/fop/render/pdf/PDFRendererConfigurator.java
@@ -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
index 000000000..e2d93fbd3
--- /dev/null
+++ b/src/java/org/apache/fop/util/ConversionUtils.java
@@ -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;
+
+ }
+
+}
diff --git a/status.xml b/status.xml
index 42996789e..6f22165c5 100644
--- a/status.xml
+++ b/status.xml
@@ -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.