From 6faeb0d39411199ab9db8cd94cd235aa63f8249a Mon Sep 17 00:00:00 2001 From: Vincent Hennebert Date: Thu, 2 Sep 2010 17:34:43 +0000 Subject: Implemented reset method for changing IPD git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@992029 13f79535-47bb-0310-9956-ffa450edef68 --- .../fop/layoutmgr/table/TableLayoutManager.java | 7 +++++++ .../flow_changing-ipd_table-after-break.xml | 23 ++++++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java index 2b432d0d4..7e343697a 100644 --- a/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/table/TableLayoutManager.java @@ -552,4 +552,11 @@ public class TableLayoutManager extends BlockStackingLayoutManager } } + /** {@inheritDoc} */ + public void reset() { + super.reset(); + curBlockArea = null; + tableUnit = 0.0; + } + } diff --git a/test/layoutengine/standard-testcases/flow_changing-ipd_table-after-break.xml b/test/layoutengine/standard-testcases/flow_changing-ipd_table-after-break.xml index 956563e20..1b10d722c 100644 --- a/test/layoutengine/standard-testcases/flow_changing-ipd_table-after-break.xml +++ b/test/layoutengine/standard-testcases/flow_changing-ipd_table-after-break.xml @@ -56,13 +56,19 @@ - - After the table 1 + + Cell 1.1 + + + Cell 1.2 - - After the table 2 + + Cell 2.1 + + + Cell 2.2 @@ -74,7 +80,12 @@ - - + + + + + + + -- cgit v1.2.3 From 41b4797e3a14ff13b1479e48e3d81c5086644142 Mon Sep 17 00:00:00 2001 From: Vincent Hennebert Date: Fri, 3 Sep 2010 17:26:28 +0000 Subject: Fixed typos and source code indentation issues. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@992386 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/afp/DataStream.java | 6 +-- .../org/apache/fop/afp/modca/ObjectContainer.java | 2 +- src/java/org/apache/fop/datatypes/Numeric.java | 12 ++--- src/java/org/apache/fop/fo/expr/NumericOp.java | 44 +++++++----------- .../org/apache/fop/fo/flow/table/TableFObj.java | 14 +++--- src/java/org/apache/fop/fo/pagination/Root.java | 2 +- .../fo/properties/BackgroundPositionShorthand.java | 2 +- .../fo/properties/BorderWidthPropertyMaker.java | 5 +- .../apache/fop/fo/properties/ColorProperty.java | 2 +- .../fop/fo/properties/CommonHyphenation.java | 2 +- .../fop/fo/properties/CompoundPropertyMaker.java | 7 ++- .../fop/fo/properties/FontFamilyProperty.java | 2 +- .../fop/fo/properties/FontSizePropertyMaker.java | 2 +- .../org/apache/fop/fo/properties/KeepProperty.java | 2 +- .../fop/fo/properties/PageDimensionMaker.java | 2 +- .../fop/fo/properties/ToBeImplementedProperty.java | 2 +- src/java/org/apache/fop/layoutmgr/PageBreaker.java | 2 +- src/java/org/apache/fop/tools/anttasks/Fop.java | 34 +++++++------- src/java/org/apache/fop/traits/MinOptMax.java | 53 ++++++++++------------ 19 files changed, 87 insertions(+), 110 deletions(-) diff --git a/src/java/org/apache/fop/afp/DataStream.java b/src/java/org/apache/fop/afp/DataStream.java index 843e3fa65..a437c3004 100644 --- a/src/java/org/apache/fop/afp/DataStream.java +++ b/src/java/org/apache/fop/afp/DataStream.java @@ -359,9 +359,9 @@ public class DataStream { * @param charSet is the AFP Character Set to use with the text * @throws UnsupportedEncodingException thrown if character encoding is not supported */ - public void createText - ( final AFPTextDataInfo textDataInfo, final int letterSpacing, final int wordSpacing, - final Font font, final CharacterSet charSet) throws UnsupportedEncodingException { + public void createText(final AFPTextDataInfo textDataInfo, final int letterSpacing, + final int wordSpacing, final Font font, final CharacterSet charSet) + throws UnsupportedEncodingException { int rotation = paintingState.getRotation(); if (rotation != 0) { textDataInfo.setRotation(rotation); diff --git a/src/java/org/apache/fop/afp/modca/ObjectContainer.java b/src/java/org/apache/fop/afp/modca/ObjectContainer.java index 515425906..9bc8dc594 100644 --- a/src/java/org/apache/fop/afp/modca/ObjectContainer.java +++ b/src/java/org/apache/fop/afp/modca/ObjectContainer.java @@ -113,7 +113,7 @@ public class ObjectContainer extends AbstractDataObject { } /** - * Sets the data for the the object container + * Sets the data for the object container * * @param data a byte array */ diff --git a/src/java/org/apache/fop/datatypes/Numeric.java b/src/java/org/apache/fop/datatypes/Numeric.java index c26cacd7c..2004c6721 100644 --- a/src/java/org/apache/fop/datatypes/Numeric.java +++ b/src/java/org/apache/fop/datatypes/Numeric.java @@ -29,15 +29,15 @@ import org.apache.fop.fo.expr.PropertyException; * Numerics can be either absolute or relative. Relative numerics * must be resolved against base value before the value can be used. *

- * To support relative numerics internally in the expresion parser and - * during evaulation one additional methods exists: isAbsolute() which + * To support relative numerics internally in the expression parser and + * during evaluation one additional methods exists: isAbsolute() which * return true for absolute numerics and false for relative numerics. */ public interface Numeric { /** * Return the value of this Numeric * @return the computed value. - * @throws PropertyException if a propert exception occurs + * @throws PropertyException if a property exception occurs */ double getNumericValue() throws PropertyException; @@ -45,7 +45,7 @@ public interface Numeric { * Return the value of this Numeric * @param context The context for the length calculation (for percentage based lengths) * @return the computed value. - * @throws PropertyException if a propert exception occurs + * @throws PropertyException if a property exception occurs */ double getNumericValue(PercentBaseContext context) throws PropertyException; @@ -78,9 +78,9 @@ public interface Numeric { int getValue(PercentBaseContext context); /** - * Return the resolved value. This method will becalled during evaluation + * Return the resolved value. This method will be called during evaluation * of the expression tree and relative numerics can then return a - * resolved absolute Numeric. Absolute numerics can just return themself. + * resolved absolute Numeric. Absolute numerics can just return themselves. * * @return A resolved value. * @throws PropertyException diff --git a/src/java/org/apache/fop/fo/expr/NumericOp.java b/src/java/org/apache/fop/fo/expr/NumericOp.java index d1f91d509..a2b203330 100644 --- a/src/java/org/apache/fop/fo/expr/NumericOp.java +++ b/src/java/org/apache/fop/fo/expr/NumericOp.java @@ -19,8 +19,8 @@ package org.apache.fop.fo.expr; -import org.apache.fop.datatypes.PercentBaseContext; import org.apache.fop.datatypes.Numeric; +import org.apache.fop.datatypes.PercentBaseContext; /** * This class contains static methods to evaluate operations on Numeric @@ -43,8 +43,7 @@ public final class NumericOp { * @throws PropertyException If the dimension of the operand is different * from the dimension of this Numeric. */ - public static Numeric addition(Numeric op1, Numeric op2) - throws PropertyException { + public static Numeric addition(Numeric op1, Numeric op2) throws PropertyException { if (op1.isAbsolute() && op2.isAbsolute()) { return addition2(op1, op2, null); } else { @@ -80,8 +79,7 @@ public final class NumericOp { * @throws PropertyException If the dimension of the operand is different * from the dimension of this Numeric. */ - public static Numeric subtraction(Numeric op1, Numeric op2) - throws PropertyException { + public static Numeric subtraction(Numeric op1, Numeric op2) throws PropertyException { if (op1.isAbsolute() && op2.isAbsolute()) { return subtraction2(op1, op2, null); } else { @@ -100,7 +98,7 @@ public final class NumericOp { * from the dimension of this Numeric. */ public static Numeric subtraction2(Numeric op1, Numeric op2, PercentBaseContext context) - throws PropertyException { + throws PropertyException { if (op1.getDimension() != op2.getDimension()) { throw new PropertyException("Can't subtract Numerics of different dimensions"); } @@ -117,8 +115,7 @@ public final class NumericOp { * @throws PropertyException If the dimension of the operand is different * from the dimension of this Numeric. */ - public static Numeric multiply(Numeric op1, Numeric op2) - throws PropertyException { + public static Numeric multiply(Numeric op1, Numeric op2) throws PropertyException { if (op1.isAbsolute() && op2.isAbsolute()) { return multiply2(op1, op2, null); } else { @@ -137,7 +134,7 @@ public final class NumericOp { * from the dimension of this Numeric. */ public static Numeric multiply2(Numeric op1, Numeric op2, PercentBaseContext context) - throws PropertyException { + throws PropertyException { return numeric(op1.getNumericValue(context) * op2.getNumericValue(context), op1.getDimension() + op2.getDimension()); } @@ -171,7 +168,7 @@ public final class NumericOp { * from the dimension of this Numeric. */ public static Numeric divide2(Numeric op1, Numeric op2, PercentBaseContext context) - throws PropertyException { + throws PropertyException { return numeric(op1.getNumericValue(context) / op2.getNumericValue(context), op1.getDimension() - op2.getDimension()); } @@ -183,8 +180,7 @@ public final class NumericOp { * @return A new Numeric object representing the absolute value. * @throws PropertyException if a property exception occurs */ - public static Numeric modulo(Numeric op1, Numeric op2) - throws PropertyException { + public static Numeric modulo(Numeric op1, Numeric op2) throws PropertyException { if (op1.isAbsolute() && op2.isAbsolute()) { return modulo2(op1, op2, null); } else { @@ -202,7 +198,7 @@ public final class NumericOp { * from the dimension of this Numeric. */ public static Numeric modulo2(Numeric op1, Numeric op2, PercentBaseContext context) - throws PropertyException { + throws PropertyException { return numeric(op1.getNumericValue(context) % op2.getNumericValue(context), op1.getDimension()); } @@ -213,8 +209,7 @@ public final class NumericOp { * @return a new Numeric object representing the absolute value of the operand. * @throws PropertyException if a property exception occurs */ - public static Numeric abs(Numeric op) - throws PropertyException { + public static Numeric abs(Numeric op) throws PropertyException { if (op.isAbsolute()) { return abs2(op, null); } else { @@ -230,8 +225,7 @@ public final class NumericOp { * @throws PropertyException If the dimension of the operand is different * from the dimension of this Numeric. */ - public static Numeric abs2(Numeric op, PercentBaseContext context) - throws PropertyException { + public static Numeric abs2(Numeric op, PercentBaseContext context) throws PropertyException { return numeric(Math.abs(op.getNumericValue(context)), op.getDimension()); } @@ -241,8 +235,7 @@ public final class NumericOp { * @return a new Numeric object representing the negation of the operand. * @throws PropertyException if a property exception occurs */ - public static Numeric negate(Numeric op) - throws PropertyException { + public static Numeric negate(Numeric op) throws PropertyException { if (op.isAbsolute()) { return negate2(op, null); } else { @@ -259,8 +252,7 @@ public final class NumericOp { * @throws PropertyException If the dimension of the operand is different * from the dimension of this Numeric. */ - public static Numeric negate2(Numeric op, PercentBaseContext context) - throws PropertyException { + public static Numeric negate2(Numeric op, PercentBaseContext context) throws PropertyException { return numeric(-op.getNumericValue(context), op.getDimension()); } @@ -271,8 +263,7 @@ public final class NumericOp { * @return a Numeric which is the maximum of the two operands. * @throws PropertyException if the dimensions or value types of the operands are different. */ - public static Numeric max(Numeric op1, Numeric op2) - throws PropertyException { + public static Numeric max(Numeric op1, Numeric op2) throws PropertyException { if (op1.isAbsolute() && op2.isAbsolute()) { return max2(op1, op2, null); } else { @@ -290,7 +281,7 @@ public final class NumericOp { * from the dimension of this Numeric. */ public static Numeric max2(Numeric op1, Numeric op2, PercentBaseContext context) - throws PropertyException { + throws PropertyException { if (op1.getDimension() != op2.getDimension()) { throw new PropertyException("Arguments to max() must have same dimensions"); } @@ -304,8 +295,7 @@ public final class NumericOp { * @return a Numeric which is the minimum of the two operands. * @throws PropertyException if the dimensions or value types of the operands are different. */ - public static Numeric min(Numeric op1, Numeric op2) - throws PropertyException { + public static Numeric min(Numeric op1, Numeric op2) throws PropertyException { if (op1.isAbsolute() && op2.isAbsolute()) { return min2(op1, op2, null); } else { @@ -323,7 +313,7 @@ public final class NumericOp { * from the dimension of this Numeric. */ public static Numeric min2(Numeric op1, Numeric op2, PercentBaseContext context) - throws PropertyException { + throws PropertyException { if (op1.getDimension() != op2.getDimension()) { throw new PropertyException("Arguments to min() must have same dimensions"); } 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 6ba763933..fce82dcff 100644 --- a/src/java/org/apache/fop/fo/flow/table/TableFObj.java +++ b/src/java/org/apache/fop/fo/flow/table/TableFObj.java @@ -217,11 +217,10 @@ public abstract class TableFObj extends FObj implements StructurePointerProperty */ i = 1; } - TableEventProducer eventProducer - = TableEventProducer.Provider.get(fo.getUserAgent().getEventBroadcaster()); - eventProducer.forceNextColumnNumber - (this, propertyList.getFObj().getName(), - val, i, propertyList.getFObj().getLocator()); + TableEventProducer eventProducer = TableEventProducer.Provider.get( + fo.getUserAgent().getEventBroadcaster()); + eventProducer.forceNextColumnNumber(this, propertyList.getFObj().getName(), + val, i, propertyList.getFObj().getLocator()); } return NumberProperty.getInstance(i); } @@ -231,9 +230,8 @@ public abstract class TableFObj extends FObj implements StructurePointerProperty } /** {@inheritDoc} */ - public void processNode - (String elementName, Locator locator, Attributes attlist, PropertyList pList) - throws FOPException { + public void processNode(String elementName, Locator locator, Attributes attlist, + PropertyList pList) throws FOPException { super.processNode(elementName, locator, attlist, pList); Table table = getTable(); if (!inMarker() && !table.isSeparateBorderModel()) { diff --git a/src/java/org/apache/fop/fo/pagination/Root.java b/src/java/org/apache/fop/fo/pagination/Root.java index 2a634c24a..8f8e0a509 100644 --- a/src/java/org/apache/fop/fo/pagination/Root.java +++ b/src/java/org/apache/fop/fo/pagination/Root.java @@ -212,7 +212,7 @@ public class Root extends FObj { * @throws IllegalArgumentException for negative additional page counts */ public void notifyPageSequenceFinished(int lastPageNumber, int additionalPages) - throws IllegalArgumentException { + throws IllegalArgumentException { if (additionalPages >= 0) { totalPagesGenerated += additionalPages; diff --git a/src/java/org/apache/fop/fo/properties/BackgroundPositionShorthand.java b/src/java/org/apache/fop/fo/properties/BackgroundPositionShorthand.java index 58f1ac210..3c0118181 100644 --- a/src/java/org/apache/fop/fo/properties/BackgroundPositionShorthand.java +++ b/src/java/org/apache/fop/fo/properties/BackgroundPositionShorthand.java @@ -58,7 +58,7 @@ public class BackgroundPositionShorthand extends ListProperty { * to "50%". */ public Property make(PropertyList propertyList, String value, FObj fo) - throws PropertyException { + throws PropertyException { Property p = super.make(propertyList, value, fo); if (p.getList().size() == 1) { /* only background-position-horizontal specified diff --git a/src/java/org/apache/fop/fo/properties/BorderWidthPropertyMaker.java b/src/java/org/apache/fop/fo/properties/BorderWidthPropertyMaker.java index 467682878..d2bab22ab 100644 --- a/src/java/org/apache/fop/fo/properties/BorderWidthPropertyMaker.java +++ b/src/java/org/apache/fop/fo/properties/BorderWidthPropertyMaker.java @@ -54,9 +54,8 @@ public class BorderWidthPropertyMaker extends LengthProperty.Maker { * {@inheritDoc} */ - public Property get(int subpropId, PropertyList propertyList, - boolean bTryInherit, boolean bTryDefault) - throws PropertyException { + public Property get(int subpropId, PropertyList propertyList, boolean bTryInherit, + boolean bTryDefault) throws PropertyException { Property p = super.get(subpropId, propertyList, bTryInherit, bTryDefault); diff --git a/src/java/org/apache/fop/fo/properties/ColorProperty.java b/src/java/org/apache/fop/fo/properties/ColorProperty.java index e7b8d5931..293f31577 100644 --- a/src/java/org/apache/fop/fo/properties/ColorProperty.java +++ b/src/java/org/apache/fop/fo/properties/ColorProperty.java @@ -99,7 +99,7 @@ public final class ColorProperty extends Property { * @see ColorUtil#parseColorString(FOUserAgent, String) */ public static ColorProperty getInstance(FOUserAgent foUserAgent, String value) - throws PropertyException { + throws PropertyException { ColorProperty instance = new ColorProperty( ColorUtil.parseColorString( foUserAgent, value)); diff --git a/src/java/org/apache/fop/fo/properties/CommonHyphenation.java b/src/java/org/apache/fop/fo/properties/CommonHyphenation.java index 65b2cebbd..7b9b5bc82 100644 --- a/src/java/org/apache/fop/fo/properties/CommonHyphenation.java +++ b/src/java/org/apache/fop/fo/properties/CommonHyphenation.java @@ -92,7 +92,7 @@ public final class CommonHyphenation { * @throws PropertyException if a a property exception occurs */ public static CommonHyphenation getInstance(PropertyList propertyList) - throws PropertyException { + throws PropertyException { StringProperty language = (StringProperty) propertyList.get(Constants.PR_LANGUAGE); StringProperty country diff --git a/src/java/org/apache/fop/fo/properties/CompoundPropertyMaker.java b/src/java/org/apache/fop/fo/properties/CompoundPropertyMaker.java index 3edb84009..cbd34c9b3 100644 --- a/src/java/org/apache/fop/fo/properties/CompoundPropertyMaker.java +++ b/src/java/org/apache/fop/fo/properties/CompoundPropertyMaker.java @@ -139,9 +139,8 @@ public class CompoundPropertyMaker extends PropertyMaker { * @return the property * @throws PropertyException if a property exception occurs */ - public Property get(int subpropertyId, PropertyList propertyList, - boolean tryInherit, boolean tryDefault) - throws PropertyException { + public Property get(int subpropertyId, PropertyList propertyList, boolean tryInherit, + boolean tryDefault) throws PropertyException { Property p = super.get(subpropertyId, propertyList, tryInherit, tryDefault); if (subpropertyId != 0 && p != null) { p = getSubprop(p, subpropertyId); @@ -254,7 +253,7 @@ public class CompoundPropertyMaker extends PropertyMaker { * @throws PropertyException ... */ protected Property makeCompound(PropertyList propertyList, FObj parentFO) - throws PropertyException { + throws PropertyException { Property p = makeNewProperty(); CompoundDatatype data = (CompoundDatatype) p.getObject(); for (int i = 0; i < Constants.COMPOUND_COUNT; i++) { diff --git a/src/java/org/apache/fop/fo/properties/FontFamilyProperty.java b/src/java/org/apache/fop/fo/properties/FontFamilyProperty.java index 330101ee7..f6fa806c9 100644 --- a/src/java/org/apache/fop/fo/properties/FontFamilyProperty.java +++ b/src/java/org/apache/fop/fo/properties/FontFamilyProperty.java @@ -52,7 +52,7 @@ public final class FontFamilyProperty extends ListProperty { * {@inheritDoc} */ public Property make(PropertyList propertyList, String value, FObj fo) - throws PropertyException { + throws PropertyException { if ("inherit".equals(value)) { return super.make(propertyList, value, fo); } else { diff --git a/src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java b/src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java index 60ef955ba..72884a177 100644 --- a/src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java +++ b/src/java/org/apache/fop/fo/properties/FontSizePropertyMaker.java @@ -51,7 +51,7 @@ public class FontSizePropertyMaker * it is immediately replaced by the resolved {@link FixedLength}. */ public Property make(PropertyList propertyList, String value, FObj fo) - throws PropertyException { + throws PropertyException { Property p = super.make(propertyList, value, fo); if (p instanceof PercentLength) { Property pp = propertyList.getFromParent(this.propId); diff --git a/src/java/org/apache/fop/fo/properties/KeepProperty.java b/src/java/org/apache/fop/fo/properties/KeepProperty.java index 0bc44e459..9d04ce780 100644 --- a/src/java/org/apache/fop/fo/properties/KeepProperty.java +++ b/src/java/org/apache/fop/fo/properties/KeepProperty.java @@ -62,7 +62,7 @@ public final class KeepProperty extends Property implements CompoundDatatype { * {@inheritDoc} */ public Property convertProperty(Property p, PropertyList propertyList, FObj fo) - throws PropertyException { + throws PropertyException { if (p instanceof KeepProperty) { return p; } diff --git a/src/java/org/apache/fop/fo/properties/PageDimensionMaker.java b/src/java/org/apache/fop/fo/properties/PageDimensionMaker.java index 919dd84d0..c0c6a2ed7 100644 --- a/src/java/org/apache/fop/fo/properties/PageDimensionMaker.java +++ b/src/java/org/apache/fop/fo/properties/PageDimensionMaker.java @@ -44,7 +44,7 @@ public class PageDimensionMaker extends LengthProperty.Maker { * Return the default or user-defined fallback in case the value * was specified as "auto" * @param subpropId The subproperty id of the property being retrieved. - * Is 0 when retriving a base property. + * Is 0 when retrieving a base property. * @param propertyList The PropertyList object being built for this FO. * @param tryInherit true if inherited properties should be examined. * @param tryDefault true if the default value should be returned. diff --git a/src/java/org/apache/fop/fo/properties/ToBeImplementedProperty.java b/src/java/org/apache/fop/fo/properties/ToBeImplementedProperty.java index 387355623..59a6cafef 100644 --- a/src/java/org/apache/fop/fo/properties/ToBeImplementedProperty.java +++ b/src/java/org/apache/fop/fo/properties/ToBeImplementedProperty.java @@ -23,7 +23,7 @@ import org.apache.fop.fo.FObj; import org.apache.fop.fo.PropertyList; /** - * A special property for representing an as yet implemented implemented property. + * A special property for representing an as yet unimplemented property. */ public class ToBeImplementedProperty extends Property { diff --git a/src/java/org/apache/fop/layoutmgr/PageBreaker.java b/src/java/org/apache/fop/layoutmgr/PageBreaker.java index 171b3fd4f..b65433bd7 100644 --- a/src/java/org/apache/fop/layoutmgr/PageBreaker.java +++ b/src/java/org/apache/fop/layoutmgr/PageBreaker.java @@ -554,7 +554,7 @@ public class PageBreaker extends AbstractBreaker { */ private boolean needBlankPageBeforeNew(int breakVal) { if (breakVal == Constants.EN_PAGE - || (pslm.getCurrentPage().getPageViewport().getPage().isEmpty())) { + || (pslm.getCurrentPage().getPageViewport().getPage().isEmpty())) { // any page is OK or we already have an empty page return false; } else { diff --git a/src/java/org/apache/fop/tools/anttasks/Fop.java b/src/java/org/apache/fop/tools/anttasks/Fop.java index c0a1ba9f7..58dd1fb5b 100644 --- a/src/java/org/apache/fop/tools/anttasks/Fop.java +++ b/src/java/org/apache/fop/tools/anttasks/Fop.java @@ -20,14 +20,6 @@ package org.apache.fop.tools.anttasks; // Ant -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.DirectoryScanner; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.Task; -import org.apache.tools.ant.types.FileSet; -import org.apache.tools.ant.util.GlobPatternMapper; - -// Java import java.io.BufferedOutputStream; import java.io.File; import java.io.IOException; @@ -36,17 +28,23 @@ import java.net.MalformedURLException; import java.util.List; import java.util.Vector; -// FOP +import org.xml.sax.SAXException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.impl.SimpleLog; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.DirectoryScanner; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.FileSet; +import org.apache.tools.ant.util.GlobPatternMapper; + import org.apache.fop.apps.FOPException; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.apps.FopFactory; import org.apache.fop.apps.MimeConstants; import org.apache.fop.cli.InputHandler; -import org.apache.commons.logging.impl.SimpleLog; -import org.apache.commons.logging.Log; -import org.xml.sax.SAXException; - /** * Wrapper for FOP which allows it to be accessed from within an Ant task. * Accepts the inputs: @@ -156,7 +154,7 @@ public class Fop extends Task { } /** - * Sets the XSLT parameters + * Sets the XSLT parameters * @param xsltParams the XSLT parameters */ public void setXsltParams(String xsltParams) { @@ -267,7 +265,7 @@ public class Fop extends Task { /** * Set whether exceptions are thrown. * default is false. - * @param throwExceptions true if should be thrown + * @param throwExceptions true if exceptions should be thrown */ public void setThrowexceptions(boolean throwExceptions) { this.throwExceptions = throwExceptions; @@ -553,7 +551,7 @@ class FOPTaskStarter { // OR output file doesn't exist OR // output file is older than input file if (task.getForce() || !outf.exists() - || (task.getXmlFile().lastModified() > outf.lastModified() + || (task.getXmlFile().lastModified() > outf.lastModified() || task.getXsltFile().lastModified() > outf.lastModified())) { render(task.getXmlFile(), task.getXsltFile(), outf, outputFormat); actioncount++; @@ -639,8 +637,8 @@ class FOPTaskStarter { } } - private void renderInputHandler - (InputHandler inputHandler, File outFile, String outputFormat) throws Exception { + private void renderInputHandler(InputHandler inputHandler, File outFile, String outputFormat) + throws Exception { OutputStream out = null; try { out = new java.io.FileOutputStream(outFile); diff --git a/src/java/org/apache/fop/traits/MinOptMax.java b/src/java/org/apache/fop/traits/MinOptMax.java index 99fab1adf..45b55695f 100644 --- a/src/java/org/apache/fop/traits/MinOptMax.java +++ b/src/java/org/apache/fop/traits/MinOptMax.java @@ -56,8 +56,7 @@ public final class MinOptMax implements Serializable { * @return the corresponding instance * @throws IllegalArgumentException if min > opt || max < opt. */ - public static MinOptMax getInstance(int min, int opt, int max) - throws IllegalArgumentException { + public static MinOptMax getInstance(int min, int opt, int max) throws IllegalArgumentException { if (min > opt) { throw new IllegalArgumentException("min (" + min + ") > opt (" + opt + ")"); } @@ -168,8 +167,7 @@ public final class MinOptMax implements Serializable { * @throws ArithmeticException if this instance has strictly less shrink or stretch * than the operand */ - public MinOptMax minus(MinOptMax operand) - throws ArithmeticException { + public MinOptMax minus(MinOptMax operand) throws ArithmeticException { checkCompatibility(getShrink(), operand.getShrink(), "shrink"); checkCompatibility(getStretch(), operand.getStretch(), "stretch"); return new MinOptMax(min - operand.min, opt - operand.opt, max - operand.max); @@ -194,58 +192,54 @@ public final class MinOptMax implements Serializable { } /** - * Returns an instance with the given value added to the minimal value. + * Do not use, backwards compatibility only. Returns an instance with the + * given value added to the minimal value. * * @param minOperand the minimal value to be added. * @return an instance with the given value added to the minimal value. - * @throws IllegalArgumentException if min + minOperand > opt || max < opt. + * @throws IllegalArgumentException if + * min + minOperand > opt || max < opt. */ - // [GA] remove deprecation - no alternative specified - // @deprecated Do not use! It's only for backwards compatibility. - public MinOptMax plusMin(int minOperand) - throws IllegalArgumentException { + public MinOptMax plusMin(int minOperand) throws IllegalArgumentException { return getInstance(min + minOperand, opt, max); } /** - * Returns an instance with the given value subtracted to the minimal value. + * Do not use, backwards compatibility only. Returns an instance with the + * given value subtracted to the minimal value. * * @param minOperand the minimal value to be subtracted. * @return an instance with the given value subtracted to the minimal value. - * @throws IllegalArgumentException if min - minOperand > opt || max < opt. + * @throws IllegalArgumentException if + * min - minOperand > opt || max < opt. */ - // [GA] remove deprecation - no alternative specified - // @deprecated Do not use! It's only for backwards compatibility. - public MinOptMax minusMin(int minOperand) - throws IllegalArgumentException { + public MinOptMax minusMin(int minOperand) throws IllegalArgumentException { return getInstance(min - minOperand, opt, max); } /** - * Returns an instance with the given value added to the maximal value. + * Do not use, backwards compatibility only. Returns an instance with the + * given value added to the maximal value. * * @param maxOperand the maximal value to be added. * @return an instance with the given value added to the maximal value. - * @throws IllegalArgumentException if min > opt || max < opt + maxOperand. + * @throws IllegalArgumentException if + * min > opt || max < opt + maxOperand. */ - // [GA] remove deprecation - no alternative specified - // @deprecated Do not use! It's only for backwards compatibility. - public MinOptMax plusMax(int maxOperand) - throws IllegalArgumentException { + public MinOptMax plusMax(int maxOperand) throws IllegalArgumentException { return getInstance(min, opt, max + maxOperand); } /** - * Returns an instance with the given value subtracted to the maximal value. + * Do not use, backwards compatibility only. Returns an instance with the + * given value subtracted to the maximal value. * * @param maxOperand the maximal value to be subtracted. * @return an instance with the given value subtracted to the maximal value. - * @throws IllegalArgumentException if min > opt || max < opt - maxOperand. + * @throws IllegalArgumentException if + * min > opt || max < opt - maxOperand. */ - // [GA] remove deprecation - no alternative specified - // @deprecated Do not use! It's only for backwards compatibility. - public MinOptMax minusMax(int maxOperand) - throws IllegalArgumentException { + public MinOptMax minusMax(int maxOperand) throws IllegalArgumentException { return getInstance(min, opt, max - maxOperand); } @@ -256,8 +250,7 @@ public final class MinOptMax implements Serializable { * @return the product of this MinOptMax and the given factor * @throws IllegalArgumentException if the factor is negative */ - public MinOptMax mult(int factor) - throws IllegalArgumentException { + public MinOptMax mult(int factor) throws IllegalArgumentException { if (factor < 0) { throw new IllegalArgumentException("factor < 0; was: " + factor); } else if (factor == 1) { -- cgit v1.2.3 From df2ce762e05d5ad83b18bd1f720a7fde2171e7d5 Mon Sep 17 00:00:00 2001 From: Simon Pepping Date: Tue, 7 Sep 2010 12:28:31 +0000 Subject: Add parent block, update XGC version in pom template git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@993328 13f79535-47bb-0310-9956-ffa450edef68 --- xmlgraphics-fop-pom-template.pom | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/xmlgraphics-fop-pom-template.pom b/xmlgraphics-fop-pom-template.pom index f4389cb96..1dbc35b0f 100644 --- a/xmlgraphics-fop-pom-template.pom +++ b/xmlgraphics-fop-pom-template.pom @@ -59,18 +59,23 @@ http://maven.apache.org/maven-v4_0_0.xsd"> scm:svn:http://svn.apache.org/repos/asf/xmlgraphics/fop/trunk scm:svn:https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk - http://svn.apache.org/viewcvs.cgi/xmlgraphics/fop/trunk/?root=Apache-SVN + http://svn.apache.org/viewvc/xmlgraphics/fop/trunk/?root=Apache-SVN Apache Software Foundation http://www.apache.org/ + + org.apache + apache + 7 + org.apache.xmlgraphics xmlgraphics-commons - 1.3 + 1.4 org.apache.xmlgraphics -- cgit v1.2.3 From 144138a6473966a619277390719122ad35b7f097 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Tue, 7 Sep 2010 13:45:39 +0000 Subject: Bugzilla #49885: Fixed retrieval of available BPD for cases spanning columns and multiple pages with differing page masters. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@993357 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/area/PageViewport.java | 17 ++++- src/java/org/apache/fop/layoutmgr/Page.java | 6 +- src/java/org/apache/fop/layoutmgr/PageBreaker.java | 14 ++-- .../org/apache/fop/layoutmgr/PageProvider.java | 20 ++++-- status.xml | 3 + .../region-body_column-count_span_4.xml | 84 ++++++++++++++++++++++ 6 files changed, 129 insertions(+), 15 deletions(-) create mode 100644 test/layoutengine/standard-testcases/region-body_column-count_span_4.xml diff --git a/src/java/org/apache/fop/area/PageViewport.java b/src/java/org/apache/fop/area/PageViewport.java index 63740386e..bccae8754 100644 --- a/src/java/org/apache/fop/area/PageViewport.java +++ b/src/java/org/apache/fop/area/PageViewport.java @@ -95,8 +95,10 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl * @param pageNumber the page number * @param pageStr String representation of the page number * @param blank true if this is a blank page + * @param spanAll true if the first span area spans all columns */ - public PageViewport(SimplePageMaster spm, int pageNumber, String pageStr, boolean blank) { + public PageViewport(SimplePageMaster spm, int pageNumber, String pageStr, + boolean blank, boolean spanAll) { this.simplePageMasterName = spm.getMasterName(); setExtensionAttachments(spm.getExtensionAttachments()); setForeignAttributes(spm.getForeignAttributes()); @@ -107,7 +109,18 @@ public class PageViewport extends AreaTreeObject implements Resolvable, Cloneabl this.pageNumberString = pageStr; this.viewArea = new Rectangle(0, 0, pageWidth, pageHeight); this.page = new Page(spm); - createSpan(false); + createSpan(spanAll); + } + + /** + * Create a page viewport. + * @param spm SimplePageMaster indicating the page and region dimensions + * @param pageNumber the page number + * @param pageStr String representation of the page number + * @param blank true if this is a blank page + */ + public PageViewport(SimplePageMaster spm, int pageNumber, String pageStr, boolean blank) { + this(spm, pageNumber, pageStr, blank, false); } /** diff --git a/src/java/org/apache/fop/layoutmgr/Page.java b/src/java/org/apache/fop/layoutmgr/Page.java index b183efa01..d8ec66e82 100644 --- a/src/java/org/apache/fop/layoutmgr/Page.java +++ b/src/java/org/apache/fop/layoutmgr/Page.java @@ -41,10 +41,12 @@ public class Page { * @param pageNumber the page number (as an int) * @param pageNumberStr the page number (as a String) * @param blank true if this is a blank page + * @param spanAll true if the first span area spans all columns */ - public Page(SimplePageMaster spm, int pageNumber, String pageNumberStr, boolean blank) { + public Page(SimplePageMaster spm, int pageNumber, String pageNumberStr, + boolean blank, boolean spanAll) { this.spm = spm; - this.pageViewport = new PageViewport(spm, pageNumber, pageNumberStr, blank); + this.pageViewport = new PageViewport(spm, pageNumber, pageNumberStr, blank, spanAll); } /** diff --git a/src/java/org/apache/fop/layoutmgr/PageBreaker.java b/src/java/org/apache/fop/layoutmgr/PageBreaker.java index b65433bd7..3a41eb191 100644 --- a/src/java/org/apache/fop/layoutmgr/PageBreaker.java +++ b/src/java/org/apache/fop/layoutmgr/PageBreaker.java @@ -45,6 +45,7 @@ public class PageBreaker extends AbstractBreaker { private boolean needColumnBalancing; private PageProvider pageProvider; private Block separatorArea; + private boolean spanAllActive; /** * The FlowLayoutManager object, which processes @@ -148,8 +149,9 @@ public class PageBreaker extends AbstractBreaker { } firstPart = false; pageBreakHandled = true; + pageProvider.setStartOfNextElementList(pslm.getCurrentPageNum(), - pslm.getCurrentPV().getCurrentSpan().getCurrentFlowIndex()); + pslm.getCurrentPV().getCurrentSpan().getCurrentFlowIndex(), this.spanAllActive); return super.getNextBlockList(childLC, nextSequenceStartsOn, positionAtIPDChange, restartLM, firstElements); } @@ -342,8 +344,9 @@ public class PageBreaker extends AbstractBreaker { pageBreakHandled = true; //Update so the available BPD is reported correctly int currentPageNum = pslm.getCurrentPageNum(); + pageProvider.setStartOfNextElementList(currentPageNum, - pslm.getCurrentPV().getCurrentSpan().getCurrentFlowIndex()); + pslm.getCurrentPV().getCurrentSpan().getCurrentFlowIndex(), this.spanAllActive); //Make sure we only add the areas we haven't added already effectiveList.ignoreAtStart = newStartPos; @@ -387,7 +390,7 @@ public class PageBreaker extends AbstractBreaker { boolean fitsOnePage = optimalPageCount <= pslm.getCurrentPV() - .getBodyRegion().getMainReference().getCurrentSpan().getColumnCount(); + .getBodyRegion().getMainReference().getCurrentSpan().getColumnCount(); if (needColumnBalancing) { if (!fitsOnePage) { @@ -435,7 +438,8 @@ public class PageBreaker extends AbstractBreaker { handleBreakTrait(breakClass); } pageProvider.setStartOfNextElementList(pslm.getCurrentPageNum(), - pslm.getCurrentPV().getCurrentSpan().getCurrentFlowIndex()); + pslm.getCurrentPV().getCurrentSpan().getCurrentFlowIndex(), + this.spanAllActive); } pageBreakHandled = false; // add static areas and resolve any new id areas @@ -503,9 +507,11 @@ public class PageBreaker extends AbstractBreaker { case Constants.EN_ALL: //break due to span change in multi-column layout curPage.getPageViewport().createSpan(true); + this.spanAllActive = true; return; case Constants.EN_NONE: curPage.getPageViewport().createSpan(false); + this.spanAllActive = false; return; case Constants.EN_COLUMN: case Constants.EN_AUTO: diff --git a/src/java/org/apache/fop/layoutmgr/PageProvider.java b/src/java/org/apache/fop/layoutmgr/PageProvider.java index 2e531a8d8..8caafa72b 100644 --- a/src/java/org/apache/fop/layoutmgr/PageProvider.java +++ b/src/java/org/apache/fop/layoutmgr/PageProvider.java @@ -51,6 +51,7 @@ public class PageProvider implements Constants { private int startPageOfPageSequence; private int startPageOfCurrentElementList; private int startColumnOfCurrentElementList; + private boolean spanAllForCurrentElementList; private List cachedPages = new java.util.ArrayList(); private int lastPageIndex = -1; @@ -88,12 +89,17 @@ public class PageProvider implements Constants { * on so it can later retrieve PageViewports relative to this first page. * @param startPage the number of the first page for the element list. * @param startColumn the starting column number for the element list. + * @param spanAll true if the current element list is for a column-spanning section */ - public void setStartOfNextElementList(int startPage, int startColumn) { - log.debug("start of the next element list is:" - + " page=" + startPage + " col=" + startColumn); + public void setStartOfNextElementList(int startPage, int startColumn, boolean spanAll) { + if (log.isDebugEnabled()) { + log.debug("start of the next element list is:" + + " page=" + startPage + " col=" + startColumn + + (spanAll ? ", column-spanning" : "")); + } this.startPageOfCurrentElementList = startPage - startPageOfPageSequence + 1; this.startColumnOfCurrentElementList = startColumn; + this.spanAllForCurrentElementList = spanAll; //Reset Cache this.lastRequestedIndex = -1; this.lastReportedBPD = -1; @@ -290,7 +296,7 @@ public class PageProvider implements Constants { if (log.isTraceEnabled()) { log.trace("Caching " + index); } - cacheNextPage(index, isBlank, isLastPage); + cacheNextPage(index, isBlank, isLastPage, this.spanAllForCurrentElementList); } Page page = (Page)cachedPages.get(intIndex); boolean replace = false; @@ -306,7 +312,7 @@ public class PageProvider implements Constants { } if (replace) { discardCacheStartingWith(intIndex); - page = cacheNextPage(index, isBlank, isLastPage); + page = cacheNextPage(index, isBlank, isLastPage, this.spanAllForCurrentElementList); } return page; } @@ -320,7 +326,7 @@ public class PageProvider implements Constants { } } - private Page cacheNextPage(int index, boolean isBlank, boolean isLastPage) { + private Page cacheNextPage(int index, boolean isBlank, boolean isLastPage, boolean spanAll) { String pageNumberString = pageSeq.makeFormattedPageNumber(index); boolean isFirstPage = (startPageOfPageSequence == index); SimplePageMaster spm = pageSeq.getNextSimplePageMaster( @@ -335,7 +341,7 @@ public class PageProvider implements Constants { eventProducer.flowNotMappingToRegionBody(this, pageSeq.getMainFlow().getFlowName(), spm.getMasterName(), spm.getLocator()); } - Page page = new Page(spm, index, pageNumberString, isBlank); + Page page = new Page(spm, index, pageNumberString, isBlank, spanAll); //Set unique key obtained from the AreaTreeHandler page.getPageViewport().setKey(areaTreeHandler.generatePageViewportKey()); page.getPageViewport().setForeignAttributes(spm.getForeignAttributes()); diff --git a/status.xml b/status.xml index 1f0916753..57b7a94b3 100644 --- a/status.xml +++ b/status.xml @@ -58,6 +58,9 @@ documents. Example: the fix of marks layering will be such a case when it's done. --> + + Fixed retrieval of available BPD for cases spanning columns and multiple pages with differing page masters. + Removed old Renderer implementations for those output formats that have a version based on the new DocumentHandler architecture available (AFP, PCL, PDF, PS). diff --git a/test/layoutengine/standard-testcases/region-body_column-count_span_4.xml b/test/layoutengine/standard-testcases/region-body_column-count_span_4.xml new file mode 100644 index 000000000..8bc4652ce --- /dev/null +++ b/test/layoutengine/standard-testcases/region-body_column-count_span_4.xml @@ -0,0 +1,84 @@ + + + + + +

+ This test checks multi-column documents. Check that spanned section that are broken over + to multiple pages still respect the span setting. This particular test makes sure that pages with different region-body + height are handled properly. +

+ + + + + + + + + + + + + + + + + + + + + Line 1 + Line 2 + Line 3 + Line 4 + Line 5 + Line 6 + Line 7 + Line 8 + Line 9 + Line 10 + Line 11 + Line 12 + Line 13 + Line 14 + Line 15 + Line 16 + Line 17 + Line 18 + Line 19 + Line 20 + Line 21 + Line 22 + + + + + + + + + + + + + + + + + -- cgit v1.2.3 From f62155abf5536b893f6bd0d91176301ab5755c2d Mon Sep 17 00:00:00 2001 From: Vincent Hennebert Date: Wed, 8 Sep 2010 18:31:09 +0000 Subject: Fixed formatting of help message git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@995181 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/cli/CommandLineOptions.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java/org/apache/fop/cli/CommandLineOptions.java b/src/java/org/apache/fop/cli/CommandLineOptions.java index 6b4ec1a1d..2a5c0d272 100644 --- a/src/java/org/apache/fop/cli/CommandLineOptions.java +++ b/src/java/org/apache/fop/cli/CommandLineOptions.java @@ -1231,7 +1231,7 @@ public class CommandLineOptions { + " -out mime outfile input will be rendered using the given MIME type\n" + " (outfile req'd) Example: \"-out application/pdf D:\\out.pdf\"\n" + " (Tip: \"-out list\" prints the list of supported MIME types" - + " and exits)\n" + + " and exits)\n" //+ " -mif outfile input will be rendered as MIF (FrameMaker) (outfile req'd)\n" //+ " Experimental feature - requires additional fop-sandbox.jar.\n" + " -svg outfile input will be rendered as an SVG slides file (outfile req'd) \n" -- cgit v1.2.3 From 964dd91787738d3bd3f3a57bab9ffe24cdba17e6 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Fri, 10 Sep 2010 11:53:28 +0000 Subject: Moving the AFP parser from XGC to FOP for now. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@995762 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/fop/afp/apps/FontPatternExtractor.java | 157 ++++++++++++ .../org/apache/fop/afp/parser/MODCAParser.java | 73 ++++++ .../fop/afp/parser/UnparsedStructuredField.java | 284 +++++++++++++++++++++ 3 files changed, 514 insertions(+) create mode 100644 src/java/org/apache/fop/afp/apps/FontPatternExtractor.java create mode 100644 src/java/org/apache/fop/afp/parser/MODCAParser.java create mode 100644 src/java/org/apache/fop/afp/parser/UnparsedStructuredField.java diff --git a/src/java/org/apache/fop/afp/apps/FontPatternExtractor.java b/src/java/org/apache/fop/afp/apps/FontPatternExtractor.java new file mode 100644 index 000000000..0adffcd8b --- /dev/null +++ b/src/java/org/apache/fop/afp/apps/FontPatternExtractor.java @@ -0,0 +1,157 @@ +/* + * 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.afp.apps; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; + +import org.apache.commons.io.HexDump; +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.output.ByteArrayOutputStream; + +import org.apache.fop.afp.parser.MODCAParser; +import org.apache.fop.afp.parser.UnparsedStructuredField; + +/** + * This class represents a tool for extracting the Type 1 PFB file from an AFP outline font. + */ +public class FontPatternExtractor { + + private PrintStream printStream = System.out; + + /** + * Extracts the Type1 PFB file from the given AFP outline font. + * @param file the AFP file to read from + * @param targetDir the target directory where the PFB file is to be placed. + * @throws IOException if an I/O error occurs + */ + public void extract(File file, File targetDir) throws IOException { + InputStream in = new java.io.FileInputStream(file); + try { + MODCAParser parser = new MODCAParser(in); + ByteArrayOutputStream baout = new ByteArrayOutputStream(); + UnparsedStructuredField strucField; + while ((strucField = parser.readNextStructuredField()) != null) { + if (strucField.getSfTypeID() == 0xD3EE89) { + println(strucField.toString()); + HexDump.dump(strucField.getData(), 0, printStream, 0); + baout.write(strucField.getData()); + } + } + + ByteArrayInputStream bin = new ByteArrayInputStream(baout.toByteArray()); + DataInputStream din = new DataInputStream(bin); + long len = din.readInt() & 0xFFFFFFFFL; + println("Length: " + len); + din.skip(4); //checksum + int tidLen = din.readUnsignedShort() - 2; + byte[] tid = new byte[tidLen]; + din.readFully(tid); + String filename = new String(tid, "ISO-8859-1"); + int asciiCount1 = countUSAsciiCharacters(filename); + String filenameEBCDIC = new String(tid, "Cp1146"); + int asciiCount2 = countUSAsciiCharacters(filenameEBCDIC); + println("TID: " + filename + " " + filenameEBCDIC); + + if (asciiCount2 > asciiCount1) { + //Haven't found an indicator if the name is encoded in EBCDIC or not + //so we use a trick. + filename = filenameEBCDIC; + } + if (!filename.toLowerCase().endsWith(".pfb")) { + filename = filename + ".pfb"; + } + println("Output filename: " + filename); + File out = new File(targetDir, filename); + + OutputStream fout = new java.io.FileOutputStream(out); + try { + IOUtils.copyLarge(din, fout); + } finally { + IOUtils.closeQuietly(fout); + } + + + } finally { + IOUtils.closeQuietly(in); + } + } + + private void println(String s) { + printStream.println(s); + } + + private void println() { + printStream.println(); + } + + private int countUSAsciiCharacters(String filename) { + int count = 0; + for (int i = 0, c = filename.length(); i < c; i++) { + if (filename.charAt(i) < 128) { + count++; + } + } + return count; + } + + /** + * Main method + * @param args the command-line arguments + */ + public static void main(String[] args) { + try { + FontPatternExtractor app = new FontPatternExtractor(); + + app.println("Font Pattern Extractor"); + app.println(); + + if (args.length > 0) { + String filename = args[0]; + File file = new File(filename); + + File targetDir = file.getParentFile(); + if (args.length > 1) { + targetDir = new File(args[1]); + targetDir.mkdirs(); + } + + app.extract(file, targetDir); + } else { + app.println("This tool tries to extract the PFB file from an AFP outline font."); + app.println(); + app.println("Usage: Java -cp ... " + FontPatternExtractor.class.getName() + + " []"); + System.exit(-1); + } + + + } catch (Exception e) { + e.printStackTrace(); + System.exit(-1); + } + } + +} diff --git a/src/java/org/apache/fop/afp/parser/MODCAParser.java b/src/java/org/apache/fop/afp/parser/MODCAParser.java new file mode 100644 index 000000000..98058a38e --- /dev/null +++ b/src/java/org/apache/fop/afp/parser/MODCAParser.java @@ -0,0 +1,73 @@ +/* + * 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.afp.parser; + +import java.io.DataInputStream; +import java.io.EOFException; +import java.io.IOException; +import java.io.InputStream; + +/** + * An simple MO:DCA/AFP parser. + */ +public class MODCAParser { + + private DataInputStream din; + + /** + * Main constructor + * @param in the {@link InputStream} to read the AFP file from. + */ + public MODCAParser(InputStream in) { + if (!in.markSupported()) { + in = new java.io.BufferedInputStream(in); + } + this.din = new DataInputStream(in); + } + + /** + * Returns the {@link DataInputStream} used for parsing structured fields. + * @return the data input stream + */ + public DataInputStream getDataInputStream() { + return this.din; + } + + /** + * Reads the next structured field from the input stream. + *

+ * No structure validation of the MO:DCA file is performed. + * @return a new unparsed structured field (or null when parsing is finished). + * @throws IOException if an I/O error occurs + */ + public UnparsedStructuredField readNextStructuredField() throws IOException { + din.mark(1); + try { + byte b = din.readByte(); //Skip 0x5A character if necessary (ex. AFP) + if (b != 0x5A) { + din.reset(); //Not necessary for MO:DCA files + } + } catch (EOFException eof) { + return null; + } + return UnparsedStructuredField.readStructuredField(getDataInputStream()); + } + +} diff --git a/src/java/org/apache/fop/afp/parser/UnparsedStructuredField.java b/src/java/org/apache/fop/afp/parser/UnparsedStructuredField.java new file mode 100644 index 000000000..c3dc726d4 --- /dev/null +++ b/src/java/org/apache/fop/afp/parser/UnparsedStructuredField.java @@ -0,0 +1,284 @@ +/* + * 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.afp.parser; + +import java.io.DataInputStream; +import java.io.EOFException; +import java.io.IOException; +import java.io.PrintStream; +import java.text.DecimalFormat; + +import org.apache.commons.io.HexDump; + +/** + * Represents an unparsed (generic) AFP structured field. + */ +public class UnparsedStructuredField { + + private short sfLength; + private byte sfClassCode; + private byte sfTypeCode; + private byte sfCategoryCode; + private boolean sfiExtensionPresent; + private boolean sfiSegmentedData; + private boolean sfiPaddingPresent; + private short extLength; + private byte[] extData; + private byte[] data; + + /** + * Default constructor. + */ + public UnparsedStructuredField() { + //nop + } + + /** + * Reads a structured field from a {@link DataInputStream}. The resulting object can be + * further interpreted be follow-up code. + * @param din the stream to read from + * @return the generic structured field + * @throws IOException if an I/O error occurs + */ + public static UnparsedStructuredField readStructuredField(DataInputStream din) + throws IOException { + short len; + try { + len = din.readShort(); + } catch (EOFException eof) { + return null; + } + UnparsedStructuredField sf = new UnparsedStructuredField(); + sf.sfLength = len; + sf.sfClassCode = din.readByte(); + sf.sfTypeCode = din.readByte(); + sf.sfCategoryCode = din.readByte(); + + byte f = din.readByte(); + sf.sfiExtensionPresent = (f & 0x01) != 0; + sf.sfiSegmentedData = (f & 0x04) != 0; + sf.sfiPaddingPresent = (f & 0x10) != 0; + din.skip(2); //Reserved + + int dataLength = sf.sfLength - 8; + if (sf.sfiExtensionPresent) { + sf.extLength = (short)(((short)din.readByte()) & 0xFF); + sf.extData = new byte[sf.extLength - 1]; + din.readFully(sf.extData); + dataLength -= sf.extLength; + } + sf.data = new byte[dataLength]; + din.readFully(sf.data); + return sf; + } + + /** {@inheritDoc} */ + public String toString() { + StringBuffer sb = new StringBuffer("Structured Field: "); + sb.append(Integer.toHexString(getSfTypeID()).toUpperCase()); + sb.append(", len="); + sb.append(new DecimalFormat("00000").format(getSfLength())); + sb.append(" ").append(getTypeCodeAsString()); + sb.append(" ").append(getCategoryCodeAsString()); + if (isSfiExtensionPresent()) { + sb.append(", SFI extension present"); + } + if (isSfiSegmentedData()) { + sb.append(", segmented data"); + } + if (isSfiPaddingPresent()) { + sb.append(", with padding"); + } + return sb.toString(); + } + + /** + * Dump the structured field as hex data to the given {@link PrintStream}. + * @param out the {@link PrintStream} to dump to + * @throws IOException if an I/O error occurs + */ + public void dump(PrintStream out) throws IOException { + out.println(toString()); + HexDump.dump(getData(), 0, out, 0); + } + + /** + * Dump the structured field as hex data to System.out. + * @throws IOException if an I/O error occurs + */ + public void dump() throws IOException { + dump(System.out); + } + + /** + * Returns type code function name for this field. + * @return the type code function name + */ + public String getTypeCodeAsString() { + switch ((int)getSfTypeCode() & 0xFF) { + case 0xA0: return "Attribute"; + case 0xA2: return "CopyCount"; + case 0xA6: return "Descriptor"; + case 0xA7: return "Control"; + case 0xA8: return "Begin"; + case 0xA9: return "End"; + case 0xAB: return "Map"; + case 0xAC: return "Position"; + case 0xAD: return "Process"; + case 0xAF: return "Include"; + case 0xB0: return "Table"; + case 0xB1: return "Migration"; + case 0xB2: return "Variable"; + case 0xB4: return "Link"; + case 0xEE: return "Data"; + default: return "Unknown:" + Integer.toHexString((int)getSfTypeCode()).toUpperCase(); + } + } + + /** + * Returns category code function name for this field. + * @return the category code function name + */ + public String getCategoryCodeAsString() { + switch ((int)getSfCategoryCode() & 0xFF) { + case 0x5F: return "Page Segment"; + case 0x6B: return "Object Area"; + case 0x77: return "Color Attribute Table"; + case 0x7B: return "IM Image"; + case 0x88: return "Medium"; + case 0x8A: return "Coded Font"; + case 0x90: return "Process Element"; + case 0x92: return "Object Container"; + case 0x9B: return "Presentation Text"; + case 0xA7: return "Index"; + case 0xA8: return "Document"; + case 0xAD: return "Page Group"; + case 0xAF: return "Page"; + case 0xBB: return "Graphics"; + case 0xC3: return "Data Resource"; + case 0xC4: return "Document Environment Group (DEG)"; + case 0xC6: return "Resource Group"; + case 0xC7: return "Object Environment Group (OEG)"; + case 0xC9: return "Active Environment Group (AEG)"; + case 0xCC: return "Medium Map"; + case 0xCD: return "Form Map"; + case 0xCE: return "Name Resource"; + case 0xD8: return "Page Overlay"; + case 0xD9: return "Resource Environment Group (REG)"; + case 0xDF: return "Overlay"; + case 0xEA: return "Data Supression"; + case 0xEB: return "Bar Code"; + case 0xEE: return "No Operation"; + case 0xFB: return "Image"; + default: return "Unknown:" + Integer.toHexString((int)getSfTypeCode()).toUpperCase(); + } + } + + /** + * Returns the structured field's length. + * @return the field length + */ + public short getSfLength() { + return sfLength; + } + + /** + * Returns the structured field's identifier. + * @return the field identifier + */ + public int getSfTypeID() { + return ((getSfClassCode() & 0xFF) << 16) + | ((getSfTypeCode() & 0xFF) << 8) + | (getSfCategoryCode() & 0xFF); + } + + /** + * Returns the structured field's class code. + * @return the field class code + */ + public byte getSfClassCode() { + return sfClassCode; + } + + /** + * Returns the structured field's type code. + * @return the type code + */ + public byte getSfTypeCode() { + return sfTypeCode; + } + + /** + * Returns the structured field's category code. + * @return the sfCategoryCode + */ + public byte getSfCategoryCode() { + return sfCategoryCode; + } + + /** + * Indicates whether an field introducer extension is present. + * @return true if an field introducer extension is present + */ + public boolean isSfiExtensionPresent() { + return sfiExtensionPresent; + } + + /** + * Indicates whether segmented data is present. + * @return true if the data is segmented + */ + public boolean isSfiSegmentedData() { + return sfiSegmentedData; + } + + /** + * Indicates whether the data is padded. + * @return true if the data is padded + */ + public boolean isSfiPaddingPresent() { + return sfiPaddingPresent; + } + + /** + * Returns the length of the extension if present. + * @return the length of the extension (or 0 if no extension is present) + */ + public short getExtLength() { + return extLength; + } + + /** + * Returns the extension data if present. + * @return the extension data (or null if no extension is present) + */ + public byte[] getExtData() { + return extData; + } + + /** + * Returns the structured field's payload. + * @return the field's data + */ + public byte[] getData() { + return data; + } + +} -- cgit v1.2.3 From 07c8abc5039f9696bc760da10d8fc78b54c3a4dc Mon Sep 17 00:00:00 2001 From: Simon Pepping Date: Mon, 13 Sep 2010 08:46:36 +0000 Subject: Created target nightly-build git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@996451 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/build.xml b/build.xml index 1d9aad8ed..0139414b6 100644 --- a/build.xml +++ b/build.xml @@ -193,8 +193,11 @@ list of possible build targets. + + + @@ -1356,6 +1359,50 @@ NOTE: + + + + + + + + + + +NOTE: +************************************************************************** +* One or more of the Junit tests had Failures or Errors or were skipped! * +* Please check the output above for relevant messages. * +* Or use the "junit-reports" target to generate HTML test reports. * +************************************************************************** + + All Junit tests passed! + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3 From 6784fe6d144dc993462a658e65237c4e37952521 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Thu, 16 Sep 2010 06:26:12 +0000 Subject: Bugzilla #46360: Fixed a multi-threading issue when rendering SVG. Submitted by: Alexis Giotis git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@997599 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java | 8 +++++++- status.xml | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java b/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java index 99233abb6..05726be22 100644 --- a/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java +++ b/src/java/org/apache/fop/render/pdf/PDFImageHandlerSVG.java @@ -38,6 +38,7 @@ import org.apache.xmlgraphics.image.loader.impl.ImageXMLDOM; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.image.loader.batik.BatikImageFlavors; +import org.apache.fop.image.loader.batik.BatikUtil; import org.apache.fop.render.ImageHandler; import org.apache.fop.render.RenderingContext; import org.apache.fop.render.pdf.PDFLogicalStructureHandler.MarkedContentInfo; @@ -46,6 +47,7 @@ import org.apache.fop.svg.PDFBridgeContext; import org.apache.fop.svg.PDFGraphics2D; import org.apache.fop.svg.SVGEventProducer; import org.apache.fop.svg.SVGUserAgent; +import org.w3c.dom.Document; /** * Image Handler implementation which handles SVG images. @@ -82,10 +84,14 @@ public class PDFImageHandlerSVG implements ImageHandler { userAgent.getFactory().getImageManager(), userAgent.getImageSessionContext(), new AffineTransform()); + + //Cloning SVG DOM as Batik attaches non-thread-safe facilities (like the CSS engine) + //to it. + Document clonedDoc = BatikUtil.cloneSVGDocument(imageSVG.getDocument()); GraphicsNode root; try { - root = builder.build(ctx, imageSVG.getDocument()); + root = builder.build(ctx, clonedDoc); builder = null; } catch (Exception e) { SVGEventProducer eventProducer = SVGEventProducer.Provider.get( diff --git a/status.xml b/status.xml index 57b7a94b3..42ab391cc 100644 --- a/status.xml +++ b/status.xml @@ -58,6 +58,9 @@ documents. Example: the fix of marks layering will be such a case when it's done. --> + + Fixed a multi-threading issue when rendering SVG. + Fixed retrieval of available BPD for cases spanning columns and multiple pages with differing page masters. -- cgit v1.2.3 From fbb42eee69f7e883606e0ea0e478b55119905f18 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Thu, 16 Sep 2010 06:29:08 +0000 Subject: Bugzilla #46360: Fixed a multi-threading issue when rendering SVG. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@997602 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/render/ps/PSImageHandlerSVG.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/java/org/apache/fop/render/ps/PSImageHandlerSVG.java b/src/java/org/apache/fop/render/ps/PSImageHandlerSVG.java index 41cba7563..839a0cab6 100644 --- a/src/java/org/apache/fop/render/ps/PSImageHandlerSVG.java +++ b/src/java/org/apache/fop/render/ps/PSImageHandlerSVG.java @@ -23,6 +23,8 @@ import java.awt.Rectangle; import java.awt.geom.AffineTransform; import java.io.IOException; +import org.w3c.dom.Document; + import org.apache.batik.bridge.BridgeContext; import org.apache.batik.bridge.GVTBuilder; import org.apache.batik.gvt.GraphicsNode; @@ -34,6 +36,7 @@ import org.apache.xmlgraphics.java2d.ps.PSGraphics2D; import org.apache.xmlgraphics.ps.PSGenerator; import org.apache.fop.image.loader.batik.BatikImageFlavors; +import org.apache.fop.image.loader.batik.BatikUtil; import org.apache.fop.render.ImageHandler; import org.apache.fop.render.RenderingContext; import org.apache.fop.svg.SVGEventProducer; @@ -70,10 +73,14 @@ public class PSImageHandlerSVG implements ImageHandler { context.getUserAgent().getFactory().getImageManager(), context.getUserAgent().getImageSessionContext()); + //Cloning SVG DOM as Batik attaches non-thread-safe facilities (like the CSS engine) + //to it. + Document clonedDoc = BatikUtil.cloneSVGDocument(imageSVG.getDocument()); + GraphicsNode root; try { GVTBuilder builder = new GVTBuilder(); - root = builder.build(ctx, imageSVG.getDocument()); + root = builder.build(ctx, clonedDoc); } catch (Exception e) { SVGEventProducer eventProducer = SVGEventProducer.Provider.get( context.getUserAgent().getEventBroadcaster()); -- cgit v1.2.3 From ae8287810b01fd2c54290c32f6d3c432bb53454c Mon Sep 17 00:00:00 2001 From: Simon Pepping Date: Tue, 21 Sep 2010 11:33:38 +0000 Subject: Update the location of the maven XML schema git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@999321 13f79535-47bb-0310-9956-ffa450edef68 --- xmlgraphics-fop-pom-template.pom | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xmlgraphics-fop-pom-template.pom b/xmlgraphics-fop-pom-template.pom index 1dbc35b0f..efa30f67f 100644 --- a/xmlgraphics-fop-pom-template.pom +++ b/xmlgraphics-fop-pom-template.pom @@ -19,7 +19,7 @@ +http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.apache.xmlgraphics fop -- cgit v1.2.3 From 5f6c218eacf0b8f370df13d7273de621256a055c Mon Sep 17 00:00:00 2001 From: Simon Pepping Date: Tue, 21 Sep 2010 11:34:21 +0000 Subject: Add the availability of nightly snapshots git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@999324 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/dev/release.xml | 1 + src/documentation/content/xdocs/download.xml | 17 ++++++++--------- src/documentation/content/xdocs/trunk/compiling.xml | 15 +++++++++++---- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/documentation/content/xdocs/dev/release.xml b/src/documentation/content/xdocs/dev/release.xml index 4e54df872..da614bee0 100644 --- a/src/documentation/content/xdocs/dev/release.xml +++ b/src/documentation/content/xdocs/dev/release.xml @@ -69,6 +69,7 @@ The purpose of documenting it here is to facilitate consistency, ensure that the

  • Update the tab names and directories in tabs.xml
  • Delete the previous version directory.
  • Update index.xml in the new version directory.
  • +
  • Update compiling.xml in the new version directory: change the intro for trunk to that for a release.
  • Build the dist files (build[.sh] dist) and upload them to your web directory on people.apache.org
  • diff --git a/src/documentation/content/xdocs/download.xml b/src/documentation/content/xdocs/download.xml index d8fbe9978..9d7988e61 100644 --- a/src/documentation/content/xdocs/download.xml +++ b/src/documentation/content/xdocs/download.xml @@ -51,8 +51,8 @@

    Binary distributions include "-bin" in their names, and can be downloaded from a FOP Distribution mirror. - Nightly builds of trunk source code can be downloaded here: - Snapshot Trunk Builds + Nightly builds of trunk code can be downloaded here: + Nightly Snapshots.

    @@ -67,13 +67,12 @@ FOP Distribution mirror. Source distributions include "-src" in their names. - +
  • + Download a Subversion snapshot + here. + These snapshots are checked out from Subversion approximately every six hours, and have the GMT of + their creation time embedded in their names. +
  • Download directly from the SVN repository. Anyone can do this using the diff --git a/src/documentation/content/xdocs/trunk/compiling.xml b/src/documentation/content/xdocs/trunk/compiling.xml index 98a6dfb6d..0a8bf3486 100644 --- a/src/documentation/content/xdocs/trunk/compiling.xml +++ b/src/documentation/content/xdocs/trunk/compiling.xml @@ -25,16 +25,23 @@
    Do You Need To Build? -

    + + + +

    - If you got the source code from a repository snapshot or via Subversion you will need to build FOP - in any case. + FOP snapshots are either pre-compiled binary or source. + If you are using a binary snapshot, it is already built and there is no need to build it again. + If you got the source code from a repository snapshot or via Subversion you will need to build FOP. + See the Download Instructions for information about where to obtain binary or repository snapshots, and whether a + binary or source snapshot is best for your needs.

    +
    Set Up Your Environment -- cgit v1.2.3 From 4b3802b450c5808451d7461bcc8e5643a5b49503 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Tue, 21 Sep 2010 16:32:08 +0000 Subject: Some fine-tuning for the font selection in SVG to better match AWT/GVT fonts to FOP's fonts. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@999488 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/svg/NativeTextPainter.java | 28 +++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/java/org/apache/fop/svg/NativeTextPainter.java b/src/java/org/apache/fop/svg/NativeTextPainter.java index 14fa6460d..94d426396 100644 --- a/src/java/org/apache/fop/svg/NativeTextPainter.java +++ b/src/java/org/apache/fop/svg/NativeTextPainter.java @@ -111,9 +111,9 @@ public abstract class NativeTextPainter extends StrokingTextPainter { String style = ((posture != null) && (posture.floatValue() > 0.0)) ? Font.STYLE_ITALIC : Font.STYLE_NORMAL; - int weight = ((taWeight != null) - && (taWeight.floatValue() > 1.0)) ? Font.WEIGHT_BOLD - : Font.WEIGHT_NORMAL; + int weight = toCSSWeight(taWeight != null + ? taWeight.floatValue() + : TextAttribute.WEIGHT_REGULAR.floatValue()); String firstFontFamily = null; @@ -176,6 +176,28 @@ public abstract class NativeTextPainter extends StrokingTextPainter { return (Font[])fonts.toArray(new Font[fonts.size()]); } + private int toCSSWeight(float weight) { + if (weight <= TextAttribute.WEIGHT_EXTRA_LIGHT.floatValue()) { + return 100; + } else if (weight <= TextAttribute.WEIGHT_LIGHT.floatValue()) { + return 200; + } else if (weight <= TextAttribute.WEIGHT_DEMILIGHT.floatValue()) { + return 300; + } else if (weight <= TextAttribute.WEIGHT_REGULAR.floatValue()) { + return 400; + } else if (weight <= TextAttribute.WEIGHT_SEMIBOLD.floatValue()) { + return 500; + } else if (weight <= TextAttribute.WEIGHT_BOLD.floatValue()) { + return 600; + } else if (weight <= TextAttribute.WEIGHT_HEAVY.floatValue()) { + return 700; + } else if (weight <= TextAttribute.WEIGHT_EXTRABOLD.floatValue()) { + return 800; + } else { + return 900; + } + } + /** * Collects all characters from an {@link AttributedCharacterIterator}. * @param runaci the character iterator -- cgit v1.2.3 From 8a2c2476e302cb9317af23b38c2e83840f3a3e79 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Wed, 29 Sep 2010 10:01:21 +0000 Subject: Added support for font substitutions on PDF/PSTranscoder by configuring the FontManager. Restored configuration support for the (E)PSTranscoder. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1002550 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/fop/svg/AbstractFOPTranscoder.java | 3 +- .../fop/svg/PDFDocumentGraphics2DConfigurator.java | 34 ++++++++++++---------- src/java/org/apache/fop/svg/PDFTranscoder.java | 4 +-- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/java/org/apache/fop/svg/AbstractFOPTranscoder.java b/src/java/org/apache/fop/svg/AbstractFOPTranscoder.java index fc007b90a..aa8c5238c 100644 --- a/src/java/org/apache/fop/svg/AbstractFOPTranscoder.java +++ b/src/java/org/apache/fop/svg/AbstractFOPTranscoder.java @@ -29,6 +29,7 @@ import org.w3c.dom.DOMImplementation; import org.xml.sax.EntityResolver; +import org.apache.avalon.framework.configuration.Configurable; import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; import org.apache.avalon.framework.configuration.DefaultConfiguration; @@ -55,7 +56,7 @@ import org.apache.xmlgraphics.image.loader.impl.AbstractImageSessionContext; /** * This is the common base class of all of FOP's transcoders. */ -public abstract class AbstractFOPTranscoder extends SVGAbstractTranscoder { +public abstract class AbstractFOPTranscoder extends SVGAbstractTranscoder implements Configurable { /** * The key is used to specify the resolution for on-the-fly images generated diff --git a/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java b/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java index b77518ab0..24974b01a 100644 --- a/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java +++ b/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java @@ -25,12 +25,15 @@ import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; import org.apache.fop.apps.FOPException; +import org.apache.fop.fonts.CustomFontCollection; +import org.apache.fop.fonts.FontCollection; import org.apache.fop.fonts.FontEventListener; import org.apache.fop.fonts.FontInfo; import org.apache.fop.fonts.FontInfoConfigurator; import org.apache.fop.fonts.FontManager; +import org.apache.fop.fonts.FontManagerConfigurator; import org.apache.fop.fonts.FontResolver; -import org.apache.fop.fonts.FontSetup; +import org.apache.fop.fonts.base14.Base14FontCollection; import org.apache.fop.pdf.PDFDocument; import org.apache.fop.render.pdf.PDFRendererConfigurator; @@ -70,29 +73,30 @@ public class PDFDocumentGraphics2DConfigurator { */ public static FontInfo createFontInfo(Configuration cfg) throws FOPException { FontInfo fontInfo = new FontInfo(); + final boolean strict = false; + FontResolver fontResolver = FontManager.createMinimalFontResolver(); + //TODO The following could be optimized by retaining the FontManager somewhere + FontManager fontManager = new FontManager(); if (cfg != null) { - FontResolver fontResolver = FontManager.createMinimalFontResolver(); - //TODO The following could be optimized by retaining the FontManager somewhere - FontManager fontManager = new FontManager(); + FontManagerConfigurator fmConfigurator = new FontManagerConfigurator(cfg); + fmConfigurator.configure(fontManager, strict); + } - //TODO Make use of fontBaseURL, font substitution and referencing configuration - //Requires a change to the expected configuration layout + List fontCollections = new java.util.ArrayList(); + fontCollections.add(new Base14FontCollection(fontManager.isBase14KerningEnabled())); + if (cfg != null) { //TODO Wire in the FontEventListener - final FontEventListener listener = null; - final boolean strict = false; + FontEventListener listener = null; //new FontEventAdapter(eventBroadcaster); FontInfoConfigurator fontInfoConfigurator = new FontInfoConfigurator(cfg, fontManager, fontResolver, listener, strict); List/**/ fontInfoList = new java.util.ArrayList/**/(); fontInfoConfigurator.configure(fontInfoList); - - if (fontManager.useCache()) { - fontManager.getFontCache().save(); - } - FontSetup.setup(fontInfo, fontInfoList, fontResolver); - } else { - FontSetup.setup(fontInfo); + fontCollections.add(new CustomFontCollection(fontResolver, fontInfoList)); } + fontManager.setup(fontInfo, + (FontCollection[])fontCollections.toArray( + new FontCollection[fontCollections.size()])); return fontInfo; } diff --git a/src/java/org/apache/fop/svg/PDFTranscoder.java b/src/java/org/apache/fop/svg/PDFTranscoder.java index fc27cb48a..bf08b2fcf 100644 --- a/src/java/org/apache/fop/svg/PDFTranscoder.java +++ b/src/java/org/apache/fop/svg/PDFTranscoder.java @@ -27,7 +27,6 @@ import java.io.OutputStream; import org.w3c.dom.Document; import org.w3c.dom.svg.SVGLength; -import org.apache.avalon.framework.configuration.Configurable; import org.apache.avalon.framework.configuration.Configuration; import org.apache.batik.bridge.BridgeContext; import org.apache.batik.bridge.UnitProcessor; @@ -73,8 +72,7 @@ import org.apache.fop.fonts.FontInfo; * @author Keiron Liddle * @version $Id$ */ -public class PDFTranscoder extends AbstractFOPTranscoder - implements Configurable { +public class PDFTranscoder extends AbstractFOPTranscoder { /** Graphics2D instance that is used to paint to */ protected PDFDocumentGraphics2D graphics = null; -- cgit v1.2.3 From da7bda6577522eb455bacf3b0e6703462eecd72b Mon Sep 17 00:00:00 2001 From: Vincent Hennebert Date: Wed, 29 Sep 2010 17:48:22 +0000 Subject: Removed custom asf.todo tag git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1002788 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/build.xml b/build.xml index 0139414b6..15e6d0ac4 100644 --- a/build.xml +++ b/build.xml @@ -1048,7 +1048,6 @@ NOTE: - -- cgit v1.2.3 From 9f74aeeef633b0f57fc590c6e985b5bd333e8ecc Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Thu, 30 Sep 2010 09:51:02 +0000 Subject: Metrics need to be added before the font properties to avoid NPEs on font replacement. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1002980 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/afp/fonts/AFPFontCollection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java/org/apache/fop/afp/fonts/AFPFontCollection.java b/src/java/org/apache/fop/afp/fonts/AFPFontCollection.java index 66b3f5564..b7db6a74e 100644 --- a/src/java/org/apache/fop/afp/fonts/AFPFontCollection.java +++ b/src/java/org/apache/fop/afp/fonts/AFPFontCollection.java @@ -61,9 +61,9 @@ public class AFPFontCollection implements FontCollection { List/**/ tripletList = afpFontInfo.getFontTriplets(); for (Iterator it2 = tripletList.iterator(); it2.hasNext();) { FontTriplet triplet = (FontTriplet)it2.next(); + fontInfo.addMetrics("F" + num, afpFont); fontInfo.addFontProperties("F" + num, triplet.getName(), triplet.getStyle(), triplet.getWeight()); - fontInfo.addMetrics("F" + num, afpFont); num++; } } -- cgit v1.2.3 From 6d4f48908482cc16e20f90cfb239433517dd2def Mon Sep 17 00:00:00 2001 From: Simon Pepping Date: Sat, 2 Oct 2010 11:09:13 +0000 Subject: Enable configuration of hyphenation pattern file names git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1003774 13f79535-47bb-0310-9956-ffa450edef68 --- .../content/xdocs/trunk/configuration.xml | 9 +++ src/java/org/apache/fop/apps/FopFactory.java | 24 ++++++++ .../apache/fop/apps/FopFactoryConfigurator.java | 66 ++++++++++++++++++++++ .../fop/hyphenation/HyphenationTreeCache.java | 23 +++++++- .../org/apache/fop/hyphenation/Hyphenator.java | 29 ++++++---- .../fop/layoutmgr/inline/LineLayoutManager.java | 1 + 6 files changed, 139 insertions(+), 13 deletions(-) diff --git a/src/documentation/content/xdocs/trunk/configuration.xml b/src/documentation/content/xdocs/trunk/configuration.xml index aae7de7f0..3ef8795b7 100644 --- a/src/documentation/content/xdocs/trunk/configuration.xml +++ b/src/documentation/content/xdocs/trunk/configuration.xml @@ -89,6 +89,12 @@ disabled + + hyphenation-pattern + String, attribute lang, attribute country (optional) + Register a file name for the hyphenation pattern for the mentioned language and country. Language ll and country CC must both consist of two letters. + ll_CC + source-resolution Integer, dpi @@ -215,6 +221,9 @@ + + + nl_Bel ]]> diff --git a/src/java/org/apache/fop/apps/FopFactory.java b/src/java/org/apache/fop/apps/FopFactory.java index 907895c99..7bcdd2703 100644 --- a/src/java/org/apache/fop/apps/FopFactory.java +++ b/src/java/org/apache/fop/apps/FopFactory.java @@ -26,6 +26,8 @@ import java.io.OutputStream; import java.net.MalformedURLException; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import java.util.Set; import javax.xml.transform.Source; @@ -108,6 +110,11 @@ public class FopFactory implements ImageContext { /** The base URL for all hyphen URL resolutions. */ private String hyphenBase = null; + /** + * Map of configured names of hyphenation pattern file names: ll_CC => name + */ + private Map/**/ hyphPatNames = null; + /** * FOP has the ability, for some FO's, to continue processing even if the * input XSL violates that FO's content model. This is the default @@ -406,6 +413,23 @@ public class FopFactory implements ImageContext { this.hyphenBase = foURIResolver.checkBaseURL(hyphenBase); } + /** + * @return the hyphPatNames + */ + public Map getHyphPatNames() { + return hyphPatNames; + } + + /** + * @param hyphPatNames the hyphPatNames to set + */ + public void setHyphPatNames(Map hyphPatNames) { + if (hyphPatNames == null) { + hyphPatNames = new HashMap(); + } + this.hyphPatNames = hyphPatNames; + } + /** * Sets the URI Resolver. It is used for resolving factory-level URIs like hyphenation * patterns and as backup for URI resolution performed during a rendering run. diff --git a/src/java/org/apache/fop/apps/FopFactoryConfigurator.java b/src/java/org/apache/fop/apps/FopFactoryConfigurator.java index e46530177..093b8fb53 100644 --- a/src/java/org/apache/fop/apps/FopFactoryConfigurator.java +++ b/src/java/org/apache/fop/apps/FopFactoryConfigurator.java @@ -22,6 +22,8 @@ package org.apache.fop.apps; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; +import java.util.HashMap; +import java.util.Map; import org.xml.sax.SAXException; @@ -35,6 +37,7 @@ import org.apache.xmlgraphics.image.loader.spi.ImageImplRegistry; import org.apache.xmlgraphics.image.loader.util.Penalty; import org.apache.fop.fonts.FontManagerConfigurator; +import org.apache.fop.hyphenation.HyphenationTreeCache; import org.apache.fop.util.LogUtil; /** @@ -142,6 +145,62 @@ public class FopFactoryConfigurator { } } + /** + * Read configuration elements hyphenation-pattern, + * construct a map ll_CC => filename, and set it on the factory + */ + Configuration[] hyphPatConfig = cfg.getChildren("hyphenation-pattern"); + if (hyphPatConfig.length != 0) { + Map/**/ hyphPatNames = new HashMap/**/(); + for (int i = 0; i < hyphPatConfig.length; ++i) { + String lang, country, filename; + StringBuffer error = new StringBuffer(); + String location = hyphPatConfig[i].getLocation(); + + lang = hyphPatConfig[i].getAttribute("lang", null); + if (lang == null) { + addError("The lang attribute of a hyphenation-pattern configuration" + + " element must exist (" + location + ")", error); + } else if (!lang.matches("[a-zA-Z]{2}")) { + addError("The lang attribute of a hyphenation-pattern configuration" + + " element must consist of exactly two letters (" + location + ")", error); + } + lang = lang.toLowerCase(); + + country = hyphPatConfig[i].getAttribute("country", null); + if ("".equals(country)) { + country = null; + } + if (country != null) { + if (!country.matches("[a-zA-Z]{2}")) { + addError("The country attribute of a hyphenation-pattern configuration" + + " element must consist of exactly two letters (" + location + ")", error); + } + country = country.toUpperCase(); + } + + filename = hyphPatConfig[i].getValue(null); + if (filename == null) { + addError("The value of a hyphenation-pattern configuration" + + " element may not be empty (" + location + ")", error); + } + + if (error.length() != 0) { + LogUtil.handleError(log, error.toString(), strict); + continue; + } + + String llccKey = HyphenationTreeCache.constructLlccKey(lang, country); + hyphPatNames.put(llccKey, filename); + if (log.isDebugEnabled()) { + log.debug("Using hyphenation pattern filename " + filename + + " for lang=\"" + lang + "\"" + + (country != null?", country=\"" + country + "\"":"")); + } + } + factory.setHyphPatNames(hyphPatNames); + } + // renderer options if (cfg.getChild("source-resolution", false) != null) { factory.setSourceResolution( @@ -203,6 +262,13 @@ public class FopFactoryConfigurator { configureImageLoading(cfg.getChild("image-loading", false), strict); } + private static void addError(String message, StringBuffer error) { + if (error.length() != 0) { + error.append(". "); + } + error.append(message); + } + private void configureImageLoading(Configuration parent, boolean strict) throws FOPException { if (parent == null) { return; diff --git a/src/java/org/apache/fop/hyphenation/HyphenationTreeCache.java b/src/java/org/apache/fop/hyphenation/HyphenationTreeCache.java index 5831e2b98..40a44a942 100644 --- a/src/java/org/apache/fop/hyphenation/HyphenationTreeCache.java +++ b/src/java/org/apache/fop/hyphenation/HyphenationTreeCache.java @@ -20,6 +20,7 @@ package org.apache.fop.hyphenation; import java.util.Hashtable; +import java.util.Map; import java.util.Set; /** @@ -39,7 +40,7 @@ public class HyphenationTreeCache { * @return the HyhenationTree instance or null if it's not in the cache */ public HyphenationTree getHyphenationTree(String lang, String country) { - String key = constructKey(lang, country); + String key = constructLlccKey(lang, country); // first try to find it in the cache if (hyphenTrees.containsKey(key)) { @@ -57,7 +58,7 @@ public class HyphenationTreeCache { * @param country the country (may be null or "none") * @return the resulting key */ - public static String constructKey(String lang, String country) { + public static String constructLlccKey(String lang, String country) { String key = lang; // check whether the country code has been used if (country != null && !country.equals("none")) { @@ -66,6 +67,24 @@ public class HyphenationTreeCache { return key; } + /** + * If the user configured a hyphenation pattern file name + * for this (lang,country) value, return it. If not, return null. + * @param lang the language + * @param country the country (may be null or "none") + * @param hyphPatNames the map of user-configured hyphenation pattern file names + * @return the hyphenation pattern file name or null + */ + public static String constructUserKey(String lang, String country, Map hyphPatNames) { + String userKey = null; + if (hyphPatNames != null) { + String key = constructLlccKey(lang, country); + key.replace('_', '-'); + userKey = (String) hyphPatNames.get(key); + } + return userKey; + } + /** * Cache a hyphenation tree under its key. * @param key the key (ex. "de_CH" or "en") diff --git a/src/java/org/apache/fop/hyphenation/Hyphenator.java b/src/java/org/apache/fop/hyphenation/Hyphenator.java index 230f2ae20..3c7c0a43c 100644 --- a/src/java/org/apache/fop/hyphenation/Hyphenator.java +++ b/src/java/org/apache/fop/hyphenation/Hyphenator.java @@ -24,6 +24,7 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; +import java.util.Map; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; @@ -83,7 +84,7 @@ public class Hyphenator { */ public static HyphenationTree getHyphenationTree(String lang, String country) { - return getHyphenationTree(lang, country, null); + return getHyphenationTree(lang, country, null, null); } /** @@ -95,12 +96,12 @@ public class Hyphenator { * @return the hyphenation tree */ public static HyphenationTree getHyphenationTree(String lang, - String country, HyphenationTreeResolver resolver) { - String key = HyphenationTreeCache.constructKey(lang, country); + String country, HyphenationTreeResolver resolver, Map hyphPatNames) { + String llccKey = HyphenationTreeCache.constructLlccKey(lang, country); HyphenationTreeCache cache = getHyphenationTreeCache(); // See if there was an error finding this hyphenation tree before - if (cache.isMissing(key)) { + if (cache.isMissing(llccKey)) { return null; } @@ -111,6 +112,10 @@ public class Hyphenator { return hTree; } + String key = HyphenationTreeCache.constructUserKey(lang, country, hyphPatNames); + if (key == null) { + key = llccKey; + } if (resolver != null) { hTree = getUserHyphenationTree(key, resolver); } @@ -120,10 +125,10 @@ public class Hyphenator { // put it into the pattern cache if (hTree != null) { - cache.cache(key, hTree); + cache.cache(llccKey, hTree); } else { - log.error("Couldn't find hyphenation pattern " + key); - cache.noteMissing(key); + log.error("Couldn't find hyphenation pattern " + llccKey); + cache.noteMissing(llccKey); } return hTree; } @@ -342,9 +347,10 @@ public class Hyphenator { */ public static Hyphenation hyphenate(String lang, String country, HyphenationTreeResolver resolver, + Map hyphPatNames, String word, int leftMin, int rightMin) { - HyphenationTree hTree = getHyphenationTree(lang, country, resolver); + HyphenationTree hTree = getHyphenationTree(lang, country, resolver, hyphPatNames); if (hTree == null) { return null; } @@ -363,7 +369,7 @@ public class Hyphenator { public static Hyphenation hyphenate(String lang, String country, String word, int leftMin, int rightMin) { - return hyphenate(lang, country, null, word, leftMin, rightMin); + return hyphenate(lang, country, null, null, word, leftMin, rightMin); } /** @@ -381,9 +387,10 @@ public class Hyphenator { public static Hyphenation hyphenate(String lang, // CSOK: ParameterNumber String country, HyphenationTreeResolver resolver, + Map hyphPatNames, char[] word, int offset, int len, int leftMin, int rightMin) { - HyphenationTree hTree = getHyphenationTree(lang, country, resolver); + HyphenationTree hTree = getHyphenationTree(lang, country, resolver, hyphPatNames); if (hTree == null) { return null; } @@ -404,7 +411,7 @@ public class Hyphenator { public static Hyphenation hyphenate(String lang, String country, char[] word, int offset, int len, int leftMin, int rightMin) { - return hyphenate(lang, country, null, word, offset, len, leftMin, rightMin); + return hyphenate(lang, country, null, null, word, offset, len, leftMin, rightMin); } /** diff --git a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java index 83d286c15..cbae691b1 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java @@ -1415,6 +1415,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager = Hyphenator.hyphenate(hyphenationProperties.language.getString(), hyphenationProperties.country.getString(), getFObj().getUserAgent().getFactory().getHyphenationTreeResolver(), + getFObj().getUserAgent().getFactory().getHyphPatNames(), sbChars.toString(), hyphenationProperties.hyphenationRemainCharacterCount.getValue(), hyphenationProperties.hyphenationPushCharacterCount.getValue()); -- cgit v1.2.3 From 3f407e611f060716f098a6136514ddbef2a2ca5a Mon Sep 17 00:00:00 2001 From: Simon Pepping Date: Sat, 2 Oct 2010 11:38:37 +0000 Subject: Make handling of configuration errors consistent git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1003775 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/fop/apps/FopFactoryConfigurator.java | 26 +++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/java/org/apache/fop/apps/FopFactoryConfigurator.java b/src/java/org/apache/fop/apps/FopFactoryConfigurator.java index 093b8fb53..3ccd8c518 100644 --- a/src/java/org/apache/fop/apps/FopFactoryConfigurator.java +++ b/src/java/org/apache/fop/apps/FopFactoryConfigurator.java @@ -93,19 +93,6 @@ public class FopFactoryConfigurator { * @throws FOPException fop exception */ public void configure(FopFactory factory) throws FOPException { - if (log.isDebugEnabled()) { - log.debug("Initializing FopFactory Configuration"); - } - - if (cfg.getChild("accessibility", false) != null) { - try { - this.factory.setAccessibility( - cfg.getChild("accessibility").getValueAsBoolean()); - } catch (ConfigurationException e) { - throw new FOPException(e); - } - } - // strict configuration if (cfg.getChild("strict-configuration", false) != null) { try { @@ -116,6 +103,19 @@ public class FopFactoryConfigurator { } } boolean strict = factory.validateUserConfigStrictly(); + if (log.isDebugEnabled()) { + log.debug("Initializing FopFactory Configuration" + + "with " + (strict?"strict":"permissive") + " validation"); + } + + if (cfg.getChild("accessibility", false) != null) { + try { + this.factory.setAccessibility( + cfg.getChild("accessibility").getValueAsBoolean()); + } catch (ConfigurationException e) { + LogUtil.handleException(log, e, strict); + } + } // strict fo validation if (cfg.getChild("strict-validation", false) != null) { -- cgit v1.2.3 From 9e823a1055ee983974ffdf8f43aa6d318025b69e Mon Sep 17 00:00:00 2001 From: Simon Pepping Date: Sat, 2 Oct 2010 17:48:07 +0000 Subject: Remove unused methods from Hyphenator; this leaves a utility class git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1003845 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/fop/hyphenation/Hyphenator.java | 66 +--------------------- 1 file changed, 1 insertion(+), 65 deletions(-) diff --git a/src/java/org/apache/fop/hyphenation/Hyphenator.java b/src/java/org/apache/fop/hyphenation/Hyphenator.java index 3c7c0a43c..7dab56c98 100644 --- a/src/java/org/apache/fop/hyphenation/Hyphenator.java +++ b/src/java/org/apache/fop/hyphenation/Hyphenator.java @@ -47,25 +47,13 @@ public class Hyphenator { private static HyphenationTreeCache hTreeCache = null; - private HyphenationTree hyphenTree = null; - private int remainCharCount = 2; - private int pushCharCount = 2; /** Enables a dump of statistics. Note: If activated content is sent to System.out! */ private static boolean statisticsDump = false; /** * Creates a new hyphenator. - * @param lang the language - * @param country the country (may be null or "none") - * @param leftMin the minimum number of characters before the hyphenation point - * @param rightMin the minimum number of characters after the hyphenation point */ - public Hyphenator(String lang, String country, int leftMin, - int rightMin) { - hyphenTree = getHyphenationTree(lang, country); - remainCharCount = leftMin; - pushCharCount = rightMin; - } + private Hyphenator() { } /** @return the default (static) hyphenation tree cache */ public static synchronized HyphenationTreeCache getHyphenationTreeCache() { @@ -414,56 +402,4 @@ public class Hyphenator { return hyphenate(lang, country, null, null, word, offset, len, leftMin, rightMin); } - /** - * Sets the minimum number of characters before the hyphenation point - * @param min the number of characters - */ - public void setMinRemainCharCount(int min) { - remainCharCount = min; - } - - /** - * Sets the minimum number of characters after the hyphenation point - * @param min the number of characters - */ - public void setMinPushCharCount(int min) { - pushCharCount = min; - } - - /** - * Sets the language and country for the hyphenation process. - * @param lang the language - * @param country the country (may be null or "none") - */ - public void setLanguage(String lang, String country) { - hyphenTree = getHyphenationTree(lang, country); - } - - /** - * Hyphenates a word. - * @param word the word to hyphenate - * @param offset the offset of the first character in the "word" character array - * @param len the length of the word - * @return the hyphenation result - */ - public Hyphenation hyphenate(char[] word, int offset, int len) { - if (hyphenTree == null) { - return null; - } - return hyphenTree.hyphenate(word, offset, len, remainCharCount, - pushCharCount); - } - - /** - * Hyphenates a word. - * @param word the word to hyphenate - * @return the hyphenation result - */ - public Hyphenation hyphenate(String word) { - if (hyphenTree == null) { - return null; - } - return hyphenTree.hyphenate(word, remainCharCount, pushCharCount); - } - } -- cgit v1.2.3 From a6e8eea8153df672e94a9e4e7d2398b45a29b0bc Mon Sep 17 00:00:00 2001 From: Simon Pepping Date: Sat, 2 Oct 2010 18:30:00 +0000 Subject: Fixing a few checkstyle warnings git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1003850 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/apps/FopFactoryConfigurator.java | 12 +++++++----- src/java/org/apache/fop/hyphenation/Hyphenator.java | 5 ++++- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/java/org/apache/fop/apps/FopFactoryConfigurator.java b/src/java/org/apache/fop/apps/FopFactoryConfigurator.java index 3ccd8c518..ad0869ea1 100644 --- a/src/java/org/apache/fop/apps/FopFactoryConfigurator.java +++ b/src/java/org/apache/fop/apps/FopFactoryConfigurator.java @@ -92,7 +92,7 @@ public class FopFactoryConfigurator { * @param factory fop factory * @throws FOPException fop exception */ - public void configure(FopFactory factory) throws FOPException { + public void configure(FopFactory factory) throws FOPException { // CSOK: MethodLength // strict configuration if (cfg.getChild("strict-configuration", false) != null) { try { @@ -105,7 +105,7 @@ public class FopFactoryConfigurator { boolean strict = factory.validateUserConfigStrictly(); if (log.isDebugEnabled()) { log.debug("Initializing FopFactory Configuration" - + "with " + (strict?"strict":"permissive") + " validation"); + + "with " + (strict ? "strict" : "permissive") + " validation"); } if (cfg.getChild("accessibility", false) != null) { @@ -163,7 +163,8 @@ public class FopFactoryConfigurator { + " element must exist (" + location + ")", error); } else if (!lang.matches("[a-zA-Z]{2}")) { addError("The lang attribute of a hyphenation-pattern configuration" - + " element must consist of exactly two letters (" + location + ")", error); + + " element must consist of exactly two letters (" + + location + ")", error); } lang = lang.toLowerCase(); @@ -174,7 +175,8 @@ public class FopFactoryConfigurator { if (country != null) { if (!country.matches("[a-zA-Z]{2}")) { addError("The country attribute of a hyphenation-pattern configuration" - + " element must consist of exactly two letters (" + location + ")", error); + + " element must consist of exactly two letters (" + + location + ")", error); } country = country.toUpperCase(); } @@ -195,7 +197,7 @@ public class FopFactoryConfigurator { if (log.isDebugEnabled()) { log.debug("Using hyphenation pattern filename " + filename + " for lang=\"" + lang + "\"" - + (country != null?", country=\"" + country + "\"":"")); + + (country != null ? ", country=\"" + country + "\"" : "")); } } factory.setHyphPatNames(hyphPatNames); diff --git a/src/java/org/apache/fop/hyphenation/Hyphenator.java b/src/java/org/apache/fop/hyphenation/Hyphenator.java index 7dab56c98..a556fd7fe 100644 --- a/src/java/org/apache/fop/hyphenation/Hyphenator.java +++ b/src/java/org/apache/fop/hyphenation/Hyphenator.java @@ -40,7 +40,7 @@ import org.xml.sax.InputSource; * * @author Carlos Villegas */ -public class Hyphenator { +public final class Hyphenator { /** logging instance */ protected static Log log = LogFactory.getLog(Hyphenator.class); @@ -81,6 +81,7 @@ public class Hyphenator { * @param lang the language * @param country the country (may be null or "none") * @param resolver resolver to find the hyphenation files + * @param hyphPatNames the map with user-configured hyphenation pattern file names * @return the hyphenation tree */ public static HyphenationTree getHyphenationTree(String lang, @@ -328,6 +329,7 @@ public class Hyphenator { * @param lang the language * @param country the optional country code (may be null or "none") * @param resolver resolver to find the hyphenation files + * @param hyphPatNames the map with user-configured hyphenation pattern file names * @param word the word to hyphenate * @param leftMin the minimum number of characters before the hyphenation point * @param rightMin the minimum number of characters after the hyphenation point @@ -365,6 +367,7 @@ public class Hyphenator { * @param lang the language * @param country the optional country code (may be null or "none") * @param resolver resolver to find the hyphenation files + * @param hyphPatNames the map with user-configured hyphenation pattern file names * @param word the word to hyphenate * @param offset the offset of the first character in the "word" character array * @param len the length of the word -- cgit v1.2.3 From 04701709af5735bf1ecf236efef93999c2ffe834 Mon Sep 17 00:00:00 2001 From: Simon Pepping Date: Wed, 6 Oct 2010 07:07:38 +0000 Subject: Making fallback from (lang,country) to (lang) consistent git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1004907 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/fop/hyphenation/Hyphenator.java | 91 +++++++++----- .../hyphenation-pattern_fallback.xml | 137 +++++++++++++++++++++ 2 files changed, 198 insertions(+), 30 deletions(-) create mode 100644 test/layoutengine/hyphenation-testcases/hyphenation-pattern_fallback.xml diff --git a/src/java/org/apache/fop/hyphenation/Hyphenator.java b/src/java/org/apache/fop/hyphenation/Hyphenator.java index a556fd7fe..7f37b5e28 100644 --- a/src/java/org/apache/fop/hyphenation/Hyphenator.java +++ b/src/java/org/apache/fop/hyphenation/Hyphenator.java @@ -76,8 +76,9 @@ public final class Hyphenator { } /** - * Returns a hyphenation tree for a given language and country. The hyphenation trees are - * cached. + * Returns a hyphenation tree for a given language and country, + * with fallback from (lang,country) to (lang). + * The hyphenation trees are cached. * @param lang the language * @param country the country (may be null or "none") * @param resolver resolver to find the hyphenation files @@ -89,11 +90,62 @@ public final class Hyphenator { String llccKey = HyphenationTreeCache.constructLlccKey(lang, country); HyphenationTreeCache cache = getHyphenationTreeCache(); - // See if there was an error finding this hyphenation tree before + // If this hyphenation tree has been registered as missing, return immediately if (cache.isMissing(llccKey)) { return null; } + HyphenationTree hTree = getHyphenationTree2(lang, country, resolver, hyphPatNames); + + // fallback to lang only + if (hTree == null && country != null && !country.equals("none")) { + String llKey = HyphenationTreeCache.constructLlccKey(lang, null); + if (!cache.isMissing(llKey)) { + hTree = getHyphenationTree2(lang, null, resolver, hyphPatNames); + if (hTree != null && log.isDebugEnabled()) { + log.debug("Couldn't find hyphenation pattern " + + "for lang=\"" + lang + "\",country=\"" + country + "\"." + + " Using general language pattern " + + "for lang=\"" + lang + "\" instead."); + } + if (hTree == null) { + // no fallback; register as missing + cache.noteMissing(llKey); + } else { + // also register for (lang,country) + cache.cache(llccKey, hTree); + } + } + } + + if (hTree == null) { + // (lang,country) and (lang) tried; register as missing + cache.noteMissing(llccKey); + log.error("Couldn't find hyphenation pattern " + + "for lang=\"" + lang + "\"" + + (country != null && !country.equals("none") + ? ",country=\"" + country + "\"" + : "") + + "."); + } + + return hTree; + } + + /** + * Returns a hyphenation tree for a given language and country + * The hyphenation trees are cached. + * @param lang the language + * @param country the country (may be null or "none") + * @param resolver resolver to find the hyphenation files + * @param hyphPatNames the map with user-configured hyphenation pattern file names + * @return the hyphenation tree + */ + private static HyphenationTree getHyphenationTree2(String lang, + String country, HyphenationTreeResolver resolver, Map hyphPatNames) { + String llccKey = HyphenationTreeCache.constructLlccKey(lang, country); + HyphenationTreeCache cache = getHyphenationTreeCache(); + HyphenationTree hTree; // first try to find it in the cache hTree = getHyphenationTreeCache().getHyphenationTree(lang, country); @@ -105,6 +157,7 @@ public final class Hyphenator { if (key == null) { key = llccKey; } + if (resolver != null) { hTree = getUserHyphenationTree(key, resolver); } @@ -115,10 +168,8 @@ public final class Hyphenator { // put it into the pattern cache if (hTree != null) { cache.cache(llccKey, hTree); - } else { - log.error("Couldn't find hyphenation pattern " + llccKey); - cache.noteMissing(llccKey); } + return hTree; } @@ -173,31 +224,11 @@ public final class Hyphenator { try { is = getResourceStream(key); if (is == null) { - if (key.length() == 5) { - String lang = key.substring(0, 2); - is = getResourceStream(lang); - if (is != null) { - if (log.isDebugEnabled()) { - log.debug("Couldn't find hyphenation pattern '" - + key - + "'. Using general language pattern '" - + lang - + "' instead."); - } - } else { - if (log.isDebugEnabled()) { - log.debug("Couldn't find precompiled hyphenation pattern " - + lang + " in resources."); - } - return null; - } - } else { - if (log.isDebugEnabled()) { - log.debug("Couldn't find precompiled hyphenation pattern " - + key + " in resources"); - } - return null; + if (log.isDebugEnabled()) { + log.debug("Couldn't find precompiled hyphenation pattern " + + key + " in resources"); } + return null; } hTree = readHyphenationTree(is); } finally { diff --git a/test/layoutengine/hyphenation-testcases/hyphenation-pattern_fallback.xml b/test/layoutengine/hyphenation-testcases/hyphenation-pattern_fallback.xml new file mode 100644 index 000000000..3af71a3ea --- /dev/null +++ b/test/layoutengine/hyphenation-testcases/hyphenation-pattern_fallback.xml @@ -0,0 +1,137 @@ + + + + + +

    + Checks fallback from hyphenation pattern for (lang,country) to hyphenation pattern for (lang) +

    +
    + + + + + + + + + + + + + + + + + language="en",country="IN" + + + This document has been reviewed by W3C Members and other interested parties and has been endorsed by the Director as a + W3C Recommendation. It is a stable document and may be used as reference material or cited as a normative reference from + another document. W3C's role in making the Recommendation is to draw attention to the specification and to promote its + widespread deployment. This enhances the functionality and interoperability of the Web. + + + + language="em" + + + This document has been reviewed by W3C Members and other interested parties and has been endorsed by the Director as a + W3C Recommendation. It is a stable document and may be used as reference material or cited as a normative reference from + another document. W3C's role in making the Recommendation is to draw attention to the specification and to promote its + widespread deployment. This enhances the functionality and interoperability of the Web. + + + + language="em",country="IN" + + + This document has been reviewed by W3C Members and other interested parties and has been endorsed by the Director as a + W3C Recommendation. It is a stable document and may be used as reference material or cited as a normative reference from + another document. W3C's role in making the Recommendation is to draw attention to the specification and to promote its + widespread deployment. This enhances the functionality and interoperability of the Web. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    -- cgit v1.2.3 From 18b6055d598d093daa5789cf290c779bf82a0a6b Mon Sep 17 00:00:00 2001 From: Simon Pepping Date: Wed, 6 Oct 2010 07:37:52 +0000 Subject: More cleanup of unused methods in Hyphenator git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1004917 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/fop/hyphenation/Hyphenator.java | 70 ---------------------- 1 file changed, 70 deletions(-) diff --git a/src/java/org/apache/fop/hyphenation/Hyphenator.java b/src/java/org/apache/fop/hyphenation/Hyphenator.java index 7f37b5e28..76e8b6327 100644 --- a/src/java/org/apache/fop/hyphenation/Hyphenator.java +++ b/src/java/org/apache/fop/hyphenation/Hyphenator.java @@ -63,18 +63,6 @@ public final class Hyphenator { return hTreeCache; } - /** - * Returns a hyphenation tree for a given language and country. The hyphenation trees are - * cached. - * @param lang the language - * @param country the country (may be null or "none") - * @return the hyphenation tree - */ - public static HyphenationTree getHyphenationTree(String lang, - String country) { - return getHyphenationTree(lang, country, null, null); - } - /** * Returns a hyphenation tree for a given language and country, * with fallback from (lang,country) to (lang). @@ -378,62 +366,4 @@ public final class Hyphenator { return hTree.hyphenate(word, leftMin, rightMin); } - /** - * Hyphenates a word. - * @param lang the language - * @param country the optional country code (may be null or "none") - * @param word the word to hyphenate - * @param leftMin the minimum number of characters before the hyphenation point - * @param rightMin the minimum number of characters after the hyphenation point - * @return the hyphenation result - */ - public static Hyphenation hyphenate(String lang, String country, - String word, - int leftMin, int rightMin) { - return hyphenate(lang, country, null, null, word, leftMin, rightMin); - } - - /** - * Hyphenates a word. - * @param lang the language - * @param country the optional country code (may be null or "none") - * @param resolver resolver to find the hyphenation files - * @param hyphPatNames the map with user-configured hyphenation pattern file names - * @param word the word to hyphenate - * @param offset the offset of the first character in the "word" character array - * @param len the length of the word - * @param leftMin the minimum number of characters before the hyphenation point - * @param rightMin the minimum number of characters after the hyphenation point - * @return the hyphenation result - */ - public static Hyphenation hyphenate(String lang, // CSOK: ParameterNumber - String country, - HyphenationTreeResolver resolver, - Map hyphPatNames, - char[] word, int offset, int len, - int leftMin, int rightMin) { - HyphenationTree hTree = getHyphenationTree(lang, country, resolver, hyphPatNames); - if (hTree == null) { - return null; - } - return hTree.hyphenate(word, offset, len, leftMin, rightMin); - } - - /** - * Hyphenates a word. - * @param lang the language - * @param country the optional country code (may be null or "none") - * @param word the word to hyphenate - * @param offset the offset of the first character in the "word" character array - * @param len the length of the word - * @param leftMin the minimum number of characters before the hyphenation point - * @param rightMin the minimum number of characters after the hyphenation point - * @return the hyphenation result - */ - public static Hyphenation hyphenate(String lang, String country, - char[] word, int offset, int len, - int leftMin, int rightMin) { - return hyphenate(lang, country, null, null, word, offset, len, leftMin, rightMin); - } - } -- cgit v1.2.3 From 8ca38ab9b6f78481b23d3740dc68c684c78aa539 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Wed, 6 Oct 2010 11:47:37 +0000 Subject: Handled optional CR and LF chars between structured fields. Extended the field class so it can write itself back to an OutputStream. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1004991 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/fop/afp/parser/MODCAParser.java | 11 ++- .../fop/afp/parser/UnparsedStructuredField.java | 101 ++++++++++++++++++--- 2 files changed, 93 insertions(+), 19 deletions(-) diff --git a/src/java/org/apache/fop/afp/parser/MODCAParser.java b/src/java/org/apache/fop/afp/parser/MODCAParser.java index 98058a38e..d95a164f7 100644 --- a/src/java/org/apache/fop/afp/parser/MODCAParser.java +++ b/src/java/org/apache/fop/afp/parser/MODCAParser.java @@ -58,11 +58,14 @@ public class MODCAParser { * @throws IOException if an I/O error occurs */ public UnparsedStructuredField readNextStructuredField() throws IOException { - din.mark(1); try { - byte b = din.readByte(); //Skip 0x5A character if necessary (ex. AFP) - if (b != 0x5A) { - din.reset(); //Not necessary for MO:DCA files + while (true) { + byte b = din.readByte(); //Skip 0x5A character if necessary (ex. AFP) + if (b == 0x0D || b == 0x0A) { //CR and LF may be used as field delimiters + continue; + } else if (b == 0x5A) { //Carriage Control Character + break; + } } } catch (EOFException eof) { return null; diff --git a/src/java/org/apache/fop/afp/parser/UnparsedStructuredField.java b/src/java/org/apache/fop/afp/parser/UnparsedStructuredField.java index c3dc726d4..f775c05ee 100644 --- a/src/java/org/apache/fop/afp/parser/UnparsedStructuredField.java +++ b/src/java/org/apache/fop/afp/parser/UnparsedStructuredField.java @@ -22,16 +22,23 @@ package org.apache.fop.afp.parser; import java.io.DataInputStream; import java.io.EOFException; import java.io.IOException; +import java.io.OutputStream; import java.io.PrintStream; import java.text.DecimalFormat; import org.apache.commons.io.HexDump; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; /** * Represents an unparsed (generic) AFP structured field. */ public class UnparsedStructuredField { + private static final Log LOG = LogFactory.getLog(UnparsedStructuredField.class); + + private static final int INTRODUCER_LENGTH = 8; + private short sfLength; private byte sfClassCode; private byte sfTypeCode; @@ -40,6 +47,7 @@ public class UnparsedStructuredField { private boolean sfiSegmentedData; private boolean sfiPaddingPresent; private short extLength; + private byte[] introducerData; private byte[] extData; private byte[] data; @@ -59,33 +67,53 @@ public class UnparsedStructuredField { */ public static UnparsedStructuredField readStructuredField(DataInputStream din) throws IOException { + UnparsedStructuredField sf = new UnparsedStructuredField(); + + //Read introducer as byte array to preserve any data not parsed below + din.mark(INTRODUCER_LENGTH); + sf.introducerData = new byte[INTRODUCER_LENGTH]; //Length of introducer + din.readFully(sf.introducerData); + din.reset(); + + //Parse the introducer short len; try { len = din.readShort(); } catch (EOFException eof) { return null; } - UnparsedStructuredField sf = new UnparsedStructuredField(); sf.sfLength = len; sf.sfClassCode = din.readByte(); sf.sfTypeCode = din.readByte(); sf.sfCategoryCode = din.readByte(); + //Flags byte f = din.readByte(); sf.sfiExtensionPresent = (f & 0x01) != 0; sf.sfiSegmentedData = (f & 0x04) != 0; sf.sfiPaddingPresent = (f & 0x10) != 0; din.skip(2); //Reserved - int dataLength = sf.sfLength - 8; + int dataLength = sf.sfLength - INTRODUCER_LENGTH; + + //Handle optional extension if (sf.sfiExtensionPresent) { sf.extLength = (short)(((short)din.readByte()) & 0xFF); - sf.extData = new byte[sf.extLength - 1]; - din.readFully(sf.extData); - dataLength -= sf.extLength; + if (sf.extLength > 0) { + sf.extData = new byte[sf.extLength - 1]; + din.readFully(sf.extData); + dataLength -= sf.extLength; + } } + + //Read payload sf.data = new byte[dataLength]; din.readFully(sf.data); + + if (LOG.isTraceEnabled()) { + LOG.trace(sf); + } + return sf; } @@ -163,6 +191,7 @@ public class UnparsedStructuredField { case 0x77: return "Color Attribute Table"; case 0x7B: return "IM Image"; case 0x88: return "Medium"; + case 0x89: return "Font"; case 0x8A: return "Coded Font"; case 0x90: return "Process Element"; case 0x92: return "Object Container"; @@ -196,7 +225,7 @@ public class UnparsedStructuredField { * @return the field length */ public short getSfLength() { - return sfLength; + return this.sfLength; } /** @@ -214,7 +243,7 @@ public class UnparsedStructuredField { * @return the field class code */ public byte getSfClassCode() { - return sfClassCode; + return this.sfClassCode; } /** @@ -222,7 +251,7 @@ public class UnparsedStructuredField { * @return the type code */ public byte getSfTypeCode() { - return sfTypeCode; + return this.sfTypeCode; } /** @@ -230,7 +259,7 @@ public class UnparsedStructuredField { * @return the sfCategoryCode */ public byte getSfCategoryCode() { - return sfCategoryCode; + return this.sfCategoryCode; } /** @@ -238,7 +267,7 @@ public class UnparsedStructuredField { * @return true if an field introducer extension is present */ public boolean isSfiExtensionPresent() { - return sfiExtensionPresent; + return this.sfiExtensionPresent && (this.extData != null); } /** @@ -246,7 +275,7 @@ public class UnparsedStructuredField { * @return true if the data is segmented */ public boolean isSfiSegmentedData() { - return sfiSegmentedData; + return this.sfiSegmentedData; } /** @@ -254,7 +283,7 @@ public class UnparsedStructuredField { * @return true if the data is padded */ public boolean isSfiPaddingPresent() { - return sfiPaddingPresent; + return this.sfiPaddingPresent; } /** @@ -262,7 +291,7 @@ public class UnparsedStructuredField { * @return the length of the extension (or 0 if no extension is present) */ public short getExtLength() { - return extLength; + return this.extLength; } /** @@ -270,7 +299,7 @@ public class UnparsedStructuredField { * @return the extension data (or null if no extension is present) */ public byte[] getExtData() { - return extData; + return this.extData; } /** @@ -278,7 +307,49 @@ public class UnparsedStructuredField { * @return the field's data */ public byte[] getData() { - return data; + return this.data; + } + + /** + * Returns the structured field's introducer data. + * @return the introducer data + */ + public byte[] getIntroducerData() { + return this.introducerData; } + /** + * Returns the complete structured field as a byte array. + * @return the complete field data + */ + public byte[] getCompleteFieldAsBytes() { + int len = INTRODUCER_LENGTH; + if (isSfiExtensionPresent()) { + len += getExtLength(); + } + len += getData().length; + byte[] bytes = new byte[len]; + int pos = 0; + System.arraycopy(getIntroducerData(), 0, bytes, pos, INTRODUCER_LENGTH); + pos += INTRODUCER_LENGTH; + if (isSfiExtensionPresent()) { + System.arraycopy(getExtData(), 0, bytes, pos, getExtLength()); + pos += getExtLength(); + } + System.arraycopy(getData(), 0, bytes, pos, getData().length); + return bytes; + } + + /** + * Writes this structured field to the given {@link OutputStream}. + * @param out the output stream + * @throws IOException if an I/O error occurs + */ + public void writeTo(OutputStream out) throws IOException { + out.write(this.introducerData); + if (isSfiExtensionPresent()) { + out.write(this.extData); + } + out.write(this.data); + } } -- cgit v1.2.3 From eff5b9fd40215ce4f4560feaecf37320a878e917 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Thu, 7 Oct 2010 07:41:48 +0000 Subject: Bugzilla #49379: Added ability to embed an external AFP page segment resource file (AFP output only). Submitted by: Peter Hancock Changes to patch: - Replaced AFP parsing code with a more universal MO:DCA parser (as discussed). - AFPDocumentHandler: addressed a TODO (clearing of the page segment map was not necessary for each page) - AFPDocumentHandler: merged pageSegmentMap and pageSegmentUriMap by creating a combined object: PageSegmentDescriptor git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1005350 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/trunk/output.xml | 7 + .../org/apache/fop/afp/AFPResourceManager.java | 55 ++++++ src/java/org/apache/fop/afp/AFPStreamer.java | 2 +- .../fop/afp/modca/IncludedResourceObject.java | 3 +- .../org/apache/fop/afp/parser/MODCAParser.java | 10 +- .../org/apache/fop/afp/util/AFPResourceUtil.java | 214 +++++++++++++++++++++ .../apache/fop/afp/util/StructuredFieldReader.java | 79 ++------ .../apache/fop/render/afp/AFPDocumentHandler.java | 23 ++- src/java/org/apache/fop/render/afp/AFPPainter.java | 30 ++- .../fop/render/afp/PageSegmentDescriptor.java | 57 ++++++ .../render/afp/extensions/AFPElementMapping.java | 2 +- .../render/afp/extensions/AFPExtensionHandler.java | 26 +++ .../afp/extensions/AFPPageSegmentElement.java | 149 ++++++++++++++ status.xml | 3 + 14 files changed, 575 insertions(+), 85 deletions(-) create mode 100644 src/java/org/apache/fop/afp/util/AFPResourceUtil.java create mode 100644 src/java/org/apache/fop/render/afp/PageSegmentDescriptor.java create mode 100644 src/java/org/apache/fop/render/afp/extensions/AFPPageSegmentElement.java diff --git a/src/documentation/content/xdocs/trunk/output.xml b/src/documentation/content/xdocs/trunk/output.xml index 1766cd493..226a2d96c 100644 --- a/src/documentation/content/xdocs/trunk/output.xml +++ b/src/documentation/content/xdocs/trunk/output.xml @@ -885,6 +885,13 @@ Note that the value of the encoding attribute in the example is the double-byte segment in the generated file. Please also note that page segments cannot be scaled. They are always rendered in their intrinsic size.

    +

    + The include-page-segment extension element has the optional attribute + resource-file. The value of this is a URI to a resource containing a page + segment with the declared name. In this case FOP embeds the page segment into the + generated document so that the external resource does not have to be supplied in the + print job. +

    Tag Logical Element (TLE) Extension diff --git a/src/java/org/apache/fop/afp/AFPResourceManager.java b/src/java/org/apache/fop/afp/AFPResourceManager.java index b7e1abc01..ae759e14a 100644 --- a/src/java/org/apache/fop/afp/AFPResourceManager.java +++ b/src/java/org/apache/fop/afp/AFPResourceManager.java @@ -19,12 +19,15 @@ package org.apache.fop.afp; +import java.io.BufferedInputStream; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; import java.net.URI; import java.net.URISyntaxException; import java.util.Map; +import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -38,6 +41,7 @@ import org.apache.fop.afp.modca.PageSegment; import org.apache.fop.afp.modca.Registry; import org.apache.fop.afp.modca.ResourceGroup; import org.apache.fop.afp.modca.ResourceObject; +import org.apache.fop.afp.util.AFPResourceUtil; import org.apache.fop.afp.util.ResourceAccessor; /** @@ -313,6 +317,57 @@ public class AFPResourceManager { } } + /** + * Creates an included resource extracting the named resource from an external source. + * @param resourceName the name of the resource + * @param uri the URI for the resource + * @param accessor resource accessor to access the resource with + * @throws IOException if an I/O error occurs while loading the resource + */ + public void createIncludedResourceFromExternal(final String resourceName, + final URI uri, final ResourceAccessor accessor) throws IOException { + + AFPResourceLevel resourceLevel = new AFPResourceLevel(AFPResourceLevel.PRINT_FILE); + + AFPResourceInfo resourceInfo = new AFPResourceInfo(); + resourceInfo.setLevel(resourceLevel); + resourceInfo.setName(resourceName); + resourceInfo.setUri(uri.toASCIIString()); + + String resource = (String)includeNameMap.get(resourceInfo); + if (resource == null) { + + ResourceGroup resourceGroup = streamer.getResourceGroup(resourceLevel); + + //resourceObject delegates write commands to copyNamedResource() + //The included resource may already be wrapped in a resource object + AbstractNamedAFPObject resourceObject = new AbstractNamedAFPObject(null) { + + protected void writeContent(OutputStream os) throws IOException { + InputStream inputStream = null; + try { + inputStream = accessor.createInputStream(uri); + BufferedInputStream bin = new BufferedInputStream(inputStream); + AFPResourceUtil.copyNamedResource(resourceName, bin, os); + } finally { + IOUtils.closeQuietly(inputStream); + } + } + + //bypass super.writeStart + protected void writeStart(OutputStream os) throws IOException { } + //bypass super.writeEnd + protected void writeEnd(OutputStream os) throws IOException { } + }; + + resourceGroup.addObject(resourceObject); + + includeNameMap.put(resourceInfo, resourceName); + + } + } + + /** * Sets resource level defaults. The existing defaults over merged with the ones passed in * as parameter. diff --git a/src/java/org/apache/fop/afp/AFPStreamer.java b/src/java/org/apache/fop/afp/AFPStreamer.java index 33d1dbf90..154ca4cc9 100644 --- a/src/java/org/apache/fop/afp/AFPStreamer.java +++ b/src/java/org/apache/fop/afp/AFPStreamer.java @@ -158,7 +158,7 @@ public class AFPStreamer implements Streamable { */ // write out any external resource groups public void close() throws IOException { - Iterator it = pathResourceGroupMap.entrySet().iterator(); + Iterator it = pathResourceGroupMap.values().iterator(); while (it.hasNext()) { StreamedResourceGroup resourceGroup = (StreamedResourceGroup)it.next(); resourceGroup.close(); diff --git a/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java b/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java index 296ab2d9d..dc841bd40 100644 --- a/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java +++ b/src/java/org/apache/fop/afp/modca/IncludedResourceObject.java @@ -26,6 +26,7 @@ import java.net.URI; import org.apache.commons.io.IOUtils; +import org.apache.fop.afp.util.AFPResourceUtil; import org.apache.fop.afp.util.ResourceAccessor; @@ -54,7 +55,7 @@ public class IncludedResourceObject extends AbstractNamedAFPObject { public void writeToStream(OutputStream os) throws IOException { InputStream in = resourceAccessor.createInputStream(this.uri); try { - IOUtils.copy(in, os); + AFPResourceUtil.copyResourceFile(in, os); } finally { IOUtils.closeQuietly(in); } diff --git a/src/java/org/apache/fop/afp/parser/MODCAParser.java b/src/java/org/apache/fop/afp/parser/MODCAParser.java index d95a164f7..356d4f169 100644 --- a/src/java/org/apache/fop/afp/parser/MODCAParser.java +++ b/src/java/org/apache/fop/afp/parser/MODCAParser.java @@ -29,6 +29,9 @@ import java.io.InputStream; */ public class MODCAParser { + /** The carriage control character (0x5A) used to indicate the start of a structured field. */ + public static final byte CARRIAGE_CONTROL_CHAR = (byte)(0x5A & 0xFF); + private DataInputStream din; /** @@ -61,10 +64,11 @@ public class MODCAParser { try { while (true) { byte b = din.readByte(); //Skip 0x5A character if necessary (ex. AFP) - if (b == 0x0D || b == 0x0A) { //CR and LF may be used as field delimiters + if (b == 0x0D || b == 0x0A) { + //CR and LF may be used as field delimiters continue; - } else if (b == 0x5A) { //Carriage Control Character - break; + } else if (b == CARRIAGE_CONTROL_CHAR) { + break; //Signals the start of a new structured field } } } catch (EOFException eof) { diff --git a/src/java/org/apache/fop/afp/util/AFPResourceUtil.java b/src/java/org/apache/fop/afp/util/AFPResourceUtil.java new file mode 100644 index 000000000..ebb318046 --- /dev/null +++ b/src/java/org/apache/fop/afp/util/AFPResourceUtil.java @@ -0,0 +1,214 @@ +/* + * 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.afp.util; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.util.Collection; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.apache.fop.afp.AFPConstants; +import org.apache.fop.afp.modca.ResourceObject; +import org.apache.fop.afp.modca.AbstractAFPObject.Category; +import org.apache.fop.afp.parser.MODCAParser; +import org.apache.fop.afp.parser.UnparsedStructuredField; + +/** + * TODO better docs + * Utility for AFP resource handling + * + * + * A utility class to read structured fields from a MO:DCA document. Each + * component of a mixed object document is explicitly defined and delimited + * in the data. This is accomplished through the use of MO:DCA data structures, + * called structured fields. Structured fields are used to envelop document + * components and to provide commands and information to applications using + * the data. Structured fields may contain one or more parameters. Each + * parameter provides one value from a set of values defined by the architecture. + *

    + * MO:DCA structured fields consist of two parts: an introducer that identifies + * the length and type of the structured field, and data that provides the + * structured field's effect. The data is contained in a set of parameters, + * which can consist of other data structures and data elements. The maximum + * length of a structured field is 32767 bytes. + *

    + */ +public final class AFPResourceUtil { + + private static final byte TYPE_CODE_BEGIN = (byte)(0xA8 & 0xFF); + private static final byte TYPE_CODE_END = (byte)(0xA9 & 0xFF); + + private static final Log LOG = LogFactory.getLog(AFPResourceUtil.class); + + private AFPResourceUtil() { + //nop + } + + /** + * Get the next structured field as identified by the identifier + * parameter (this must be a valid MO:DCA structured field). + * @param identifier the three byte identifier + * @param inputStream the inputStream + * @throws IOException if an I/O exception occurred + * @return the next structured field or null when there are no more + */ + public static byte[] getNext(byte[] identifier, InputStream inputStream) throws IOException { + MODCAParser parser = new MODCAParser(inputStream); + while (true) { + UnparsedStructuredField field = parser.readNextStructuredField(); + if (field == null) { + return null; + } + if (field.getSfClassCode() == identifier[0] + && field.getSfTypeCode() == identifier[1] + && field.getSfCategoryCode() == identifier[2]) { + return field.getCompleteFieldAsBytes(); + } + } + } + + private static String getResourceName(UnparsedStructuredField field) + throws UnsupportedEncodingException { + //The first 8 bytes of the field data represent the resource name + byte[] nameBytes = new byte[8]; + System.arraycopy(field.getData(), 0, nameBytes, 0, 8); + String asciiName; + asciiName = new String(nameBytes, AFPConstants.EBCIDIC_ENCODING); + return asciiName; + } + + /** + * Copy a complete resource file to a given {@link OutputStream}. + * @param in external resource input + * @param out output destination + * @throws IOException if an I/O error occurs + */ + public static void copyResourceFile(final InputStream in, OutputStream out) + throws IOException { + MODCAParser parser = new MODCAParser(in); + while (true) { + UnparsedStructuredField field = parser.readNextStructuredField(); + if (field == null) { + break; + } + out.write(MODCAParser.CARRIAGE_CONTROL_CHAR); + field.writeTo(out); + } + } + + /** + * Copy a named resource to a given {@link OutputStream}. The MO:DCA fields read from the + * {@link InputStream} are scanned for the resource with the given name. + * @param name name of structured field + * @param in external resource input + * @param out output destination + * @throws IOException if an I/O error occurs + */ + public static void copyNamedResource(String name, + final InputStream in, final OutputStream out) throws IOException { + final MODCAParser parser = new MODCAParser(in); + Collection resourceNames = new java.util.HashSet(); + + //Find matching "Begin" field + final UnparsedStructuredField fieldBegin; + while (true) { + UnparsedStructuredField field = parser.readNextStructuredField(); + if (field == null) { + throw new IOException("Requested resource '" + name + + "' not found. Encountered resource names: " + resourceNames); + } + + if (field.getSfTypeCode() != TYPE_CODE_BEGIN) { //0xA8=Begin + continue; //Not a "Begin" field + } + String resourceName = getResourceName(field); + resourceNames.add(resourceName); + if (resourceName.equals(name)) { + if (LOG.isDebugEnabled()) { + LOG.debug("Start of requested structured field found:\n" + + field); + } + fieldBegin = field; + break; //Name doesn't match + } + } + + //Decide whether the resource file has to be wrapped in a resource object + boolean wrapInResource; + if (fieldBegin.getSfCategoryCode() == Category.PAGE_SEGMENT) { + //A naked page segment must be wrapped in a resource object + wrapInResource = true; + } else if (fieldBegin.getSfCategoryCode() == Category.NAME_RESOURCE) { + //A resource object can be copied directly + wrapInResource = false; + } else { + throw new IOException("Cannot handle resource: " + fieldBegin); + } + + //Copy structured fields (wrapped or as is) + if (wrapInResource) { + ResourceObject resourceObject = new ResourceObject(name) { + protected void writeContent(OutputStream os) throws IOException { + copyStructuredFields(name, fieldBegin, parser, out); + } + }; + resourceObject.setType(ResourceObject.TYPE_PAGE_SEGMENT); + resourceObject.writeToStream(out); + } else { + copyStructuredFields(name, fieldBegin, parser, out); + } + } + + private static void copyStructuredFields(String name, UnparsedStructuredField fieldBegin, + MODCAParser parser, OutputStream out) throws IOException { + boolean inRequestedResource; + + //The "Begin" field first + out.write(MODCAParser.CARRIAGE_CONTROL_CHAR); + fieldBegin.writeTo(out); + UnparsedStructuredField field; + + //Then the rest of the fields until the corresponding "End" field + inRequestedResource = true; + do { + field = parser.readNextStructuredField(); + if (field == null) { + break; //Unexpected EOF + } + + if (field.getSfTypeCode() == TYPE_CODE_END) { + String resourceName = getResourceName(field); + if (resourceName.equals(name)) { + inRequestedResource = false; //Signal end of loop + } + } + out.write(MODCAParser.CARRIAGE_CONTROL_CHAR); + field.writeTo(out); + } while (inRequestedResource); + if (inRequestedResource) { + throw new IOException("Ending structured field not found for resource " + name); + } + } + +} diff --git a/src/java/org/apache/fop/afp/util/StructuredFieldReader.java b/src/java/org/apache/fop/afp/util/StructuredFieldReader.java index 34add3bbe..1fc6d8369 100644 --- a/src/java/org/apache/fop/afp/util/StructuredFieldReader.java +++ b/src/java/org/apache/fop/afp/util/StructuredFieldReader.java @@ -54,80 +54,27 @@ public class StructuredFieldReader { } /** - * Get the next structured field as identified by the identifer - * parameter (this must be a valid MO:DCA structured field. + * Get the next structured field as identified by the identifier + * parameter (this must be a valid MO:DCA structured field). + * Note: The returned data does not include the field length and identifier! * @param identifier the three byte identifier * @throws IOException if an I/O exception occurred * @return the next structured field or null when there are no more */ public byte[] getNext(byte[] identifier) throws IOException { - int bufferPointer = 0; - byte[] bufferData = new byte[identifier.length + 2]; - for (int x = 0; x < identifier.length; x++) { - bufferData[x] = 0x00; - } - - int c; - while ((c = inputStream.read()) > -1) { - - bufferData[bufferPointer] = (byte) c; - - // Check the last characters in the buffer - int index = 0; - boolean found = true; - - for (int i = identifier.length - 1; i > -1; i--) { - - int p = bufferPointer - index; - if (p < 0) { - p = bufferData.length + p; - } - - index++; - - if (identifier[i] != bufferData[p]) { - found = false; - break; - } - - } - - if (found) { - - byte[] length = new byte[2]; - - int a = bufferPointer - identifier.length; - if (a < 0) { - a = bufferData.length + a; - } - - int b = bufferPointer - identifier.length - 1; - if (b < 0) { - b = bufferData.length + b; - } - - length[0] = bufferData[b]; - length[1] = bufferData[a]; - - int reclength = ((length[0] & 0xFF) << 8) - + (length[1] & 0xFF) - identifier.length - 2; - - byte[] retval = new byte[reclength]; - - inputStream.read(retval, 0, reclength); - - return retval; - - } - - bufferPointer++; - if (bufferPointer >= bufferData.length) { - bufferPointer = 0; - } + byte[] bytes = AFPResourceUtil.getNext(identifier, this.inputStream); + if (bytes != null) { + //Users of this class expect the field data without length and identifier + int srcPos = 2 + identifier.length; + byte[] tmp = new byte[bytes.length - srcPos]; + System.arraycopy(bytes, srcPos, tmp, 0, tmp.length); + bytes = tmp; } - return null; + return bytes; + } + } diff --git a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java index 21d4faf56..c37e0c37c 100644 --- a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java +++ b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java @@ -47,6 +47,7 @@ import org.apache.fop.render.afp.extensions.AFPElementMapping; import org.apache.fop.render.afp.extensions.AFPIncludeFormMap; import org.apache.fop.render.afp.extensions.AFPInvokeMediumMap; import org.apache.fop.render.afp.extensions.AFPPageOverlay; +import org.apache.fop.render.afp.extensions.AFPPageSegmentElement; import org.apache.fop.render.afp.extensions.AFPPageSetup; import org.apache.fop.render.intermediate.AbstractBinaryWritingIFDocumentHandler; import org.apache.fop.render.intermediate.IFDocumentHandler; @@ -76,8 +77,8 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler private DataStream dataStream; /** the map of page segments */ - private Map/**/pageSegmentMap - = new java.util.HashMap/**/(); + private Map/**/pageSegmentMap + = new java.util.HashMap/**/(); /** Medium Map referenced on previous page **/ private String lastMediumMap; @@ -213,7 +214,6 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler throws IFException { this.location = LOC_ELSEWHERE; paintingState.clear(); - pageSegmentMap.clear(); AffineTransform baseTransform = getBaseTransform(); paintingState.concatenate(baseTransform); @@ -288,9 +288,12 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler null); } if (AFPElementMapping.INCLUDE_PAGE_SEGMENT.equals(element)) { - String name = aps.getName(); - String source = aps.getValue(); - pageSegmentMap.put(source, name); + AFPPageSegmentElement.AFPPageSegmentSetup apse + = (AFPPageSegmentElement.AFPPageSegmentSetup)aps; + String name = apse.getName(); + String source = apse.getValue(); + String uri = apse.getResourceSrc(); + pageSegmentMap.put(source, new PageSegmentDescriptor(name, uri)); } else if (AFPElementMapping.NO_OPERATION.equals(element)) { String content = aps.getContent(); if (content != null) { @@ -392,13 +395,13 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler } /** - * Returns the page segment name for a given URI if it actually represents a page segment. + * Returns the page segment descriptor for a given URI if it actually represents a page segment. * Otherwise, it just returns null. * @param uri the URI that identifies the page segment - * @return the page segment name or null if there's no page segment for the given URI + * @return the page segment descriptor or null if there's no page segment for the given URI */ - String getPageSegmentNameFor(String uri) { - return (String)pageSegmentMap.get(uri); + PageSegmentDescriptor getPageSegmentNameFor(String uri) { + return (PageSegmentDescriptor)pageSegmentMap.get(uri); } } diff --git a/src/java/org/apache/fop/render/afp/AFPPainter.java b/src/java/org/apache/fop/render/afp/AFPPainter.java index 0bbfef3e8..ed16a923b 100644 --- a/src/java/org/apache/fop/render/afp/AFPPainter.java +++ b/src/java/org/apache/fop/render/afp/AFPPainter.java @@ -26,6 +26,8 @@ import java.awt.Point; import java.awt.Rectangle; import java.awt.geom.AffineTransform; import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; import java.util.Map; import org.w3c.dom.Document; @@ -48,6 +50,8 @@ import org.apache.fop.afp.modca.AbstractPageObject; import org.apache.fop.afp.modca.PresentationTextObject; import org.apache.fop.afp.ptoca.PtocaBuilder; import org.apache.fop.afp.ptoca.PtocaProducer; +import org.apache.fop.afp.util.DefaultFOPResourceAccessor; +import org.apache.fop.afp.util.ResourceAccessor; import org.apache.fop.fonts.Font; import org.apache.fop.fonts.FontInfo; import org.apache.fop.fonts.FontTriplet; @@ -183,14 +187,34 @@ public class AFPPainter extends AbstractIFPainter { /** {@inheritDoc} */ public void drawImage(String uri, Rectangle rect) throws IFException { - String name = documentHandler.getPageSegmentNameFor(uri); - if (name != null) { + PageSegmentDescriptor pageSegment = documentHandler.getPageSegmentNameFor(uri); + + if (pageSegment != null) { float[] srcPts = {rect.x, rect.y}; int[] coords = unitConv.mpts2units(srcPts); int width = Math.round(unitConv.mpt2units(rect.width)); int height = Math.round(unitConv.mpt2units(rect.height)); - getDataStream().createIncludePageSegment(name, coords[X], coords[Y], width, height); + getDataStream().createIncludePageSegment(pageSegment.getName(), + coords[X], coords[Y], width, height); + + //Do we need to embed an external page segment? + if (pageSegment.getURI() != null) { + ResourceAccessor accessor = new DefaultFOPResourceAccessor ( + documentHandler.getUserAgent(), null, null); + try { + URI resourceUri = new URI(pageSegment.getURI()); + documentHandler.getResourceManager().createIncludedResourceFromExternal( + pageSegment.getName(), resourceUri, accessor); + + } catch (URISyntaxException urie) { + throw new IFException("Could not handle resource url" + + pageSegment.getURI(), urie); + } catch (IOException ioe) { + throw new IFException("Could not handle resource" + pageSegment.getURI(), ioe); + } + } + } else { drawImageUsingURI(uri, rect); } diff --git a/src/java/org/apache/fop/render/afp/PageSegmentDescriptor.java b/src/java/org/apache/fop/render/afp/PageSegmentDescriptor.java new file mode 100644 index 000000000..8915a7a59 --- /dev/null +++ b/src/java/org/apache/fop/render/afp/PageSegmentDescriptor.java @@ -0,0 +1,57 @@ +/* + * 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.render.afp; + +/** + * Class holding information on a page segment. + */ +class PageSegmentDescriptor { + + private String name; + private String uri; + + /** + * Creates a new page segment descriptor. + * @param name the page segment name + * @param uri the URI identifying the external resource file (may be null if the page segment + * shall be referenced rather than embedded) + */ + public PageSegmentDescriptor(String name, String uri) { + this.name = name; + this.uri = uri; + } + + /** + * Returns the name of the page segment (usually 8 upper case letters). + * @return the name of the page segment + */ + public String getName() { + return this.name; + } + + /** + * Returns the URI of the external resource containing the page segment. + * @return the URI of the external resource (or null if the resource is not to be embedded) + */ + public String getURI() { + return this.uri; + } + +} \ No newline at end of file diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPElementMapping.java b/src/java/org/apache/fop/render/afp/extensions/AFPElementMapping.java index d77e21db2..580e9f800 100644 --- a/src/java/org/apache/fop/render/afp/extensions/AFPElementMapping.java +++ b/src/java/org/apache/fop/render/afp/extensions/AFPElementMapping.java @@ -103,7 +103,7 @@ public class AFPElementMapping extends ElementMapping { static class AFPIncludePageSegmentMaker extends ElementMapping.Maker { public FONode make(FONode parent) { - return new AFPPageSetupElement(parent, INCLUDE_PAGE_SEGMENT); + return new AFPPageSegmentElement(parent, INCLUDE_PAGE_SEGMENT); } } diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java b/src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java index 254b68f1f..5652a49bf 100644 --- a/src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java +++ b/src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java @@ -29,6 +29,7 @@ import org.xml.sax.helpers.DefaultHandler; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.fop.render.afp.extensions.AFPPageSegmentElement.AFPPageSegmentSetup; import org.apache.fop.util.ContentHandlerFactory; import org.apache.fop.util.ContentHandlerFactory.ObjectBuiltListener; @@ -96,6 +97,30 @@ public class AFPExtensionHandler extends DefaultHandler if (name != null) { returnedObject.setName(name); } + } else if (AFPElementMapping.INCLUDE_PAGE_SEGMENT.equals(localName)) { + AFPPageSegmentSetup pageSetupExtn = null; + + pageSetupExtn = new AFPPageSegmentSetup(localName); + this.returnedObject = pageSetupExtn; + + String name = lastAttributes.getValue("name"); + if (name != null) { + returnedObject.setName(name); + } + String value = lastAttributes.getValue("value"); + if (value != null && pageSetupExtn != null) { + pageSetupExtn.setValue(value); + } + + String resourceSrc = lastAttributes.getValue("resource-file"); + if (resourceSrc != null && pageSetupExtn != null) { + pageSetupExtn.setResourceSrc(resourceSrc); + } + + if (content.length() > 0 && pageSetupExtn != null) { + pageSetupExtn.setContent(content.toString()); + content.setLength(0); //Reset text buffer (see characters()) + } } else { AFPPageSetup pageSetupExtn = null; if (AFPElementMapping.INVOKE_MEDIUM_MAP.equals(localName)) { @@ -117,6 +142,7 @@ public class AFPExtensionHandler extends DefaultHandler content.setLength(0); //Reset text buffer (see characters()) } } + } } diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPPageSegmentElement.java b/src/java/org/apache/fop/render/afp/extensions/AFPPageSegmentElement.java new file mode 100644 index 000000000..f7379e02c --- /dev/null +++ b/src/java/org/apache/fop/render/afp/extensions/AFPPageSegmentElement.java @@ -0,0 +1,149 @@ +/* + * 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.render.afp.extensions; + +import org.xml.sax.Attributes; +import org.xml.sax.ContentHandler; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; + +import org.apache.fop.apps.FOPException; +import org.apache.fop.fo.FONode; +import org.apache.fop.fo.PropertyList; +import org.apache.fop.fo.extensions.ExtensionAttachment; + +/** + * This class extends the org.apache.fop.extensions.ExtensionObj class. The + * object faciliates extraction of elements from formatted objects based on + * the static list as defined in the AFPElementMapping implementation. + *

    + */ +public class AFPPageSegmentElement extends AFPPageSetupElement { + + private static final String ATT_RESOURCE_SRC = "resource-file"; + + /** + * Constructs an AFP object (called by Maker). + * + * @param parent the parent formatting object + * @param name the name of the afp element + */ + public AFPPageSegmentElement(FONode parent, String name) { + super(parent, name); + } + + + private AFPPageSegmentSetup getPageSetupAttachment() { + return (AFPPageSegmentSetup)getExtensionAttachment(); + } + + + /** {@inheritDoc} */ + public void processNode(String elementName, Locator locator, + Attributes attlist, PropertyList propertyList) + throws FOPException { + + AFPPageSegmentSetup pageSetup = getPageSetupAttachment(); + super.processNode(elementName, locator, attlist, propertyList); + + + String attr = attlist.getValue(ATT_RESOURCE_SRC); + + if (attr != null && attr.length() > 0) { + pageSetup.setResourceSrc(attr); + } + + } + + /** {@inheritDoc} */ + protected ExtensionAttachment instantiateExtensionAttachment() { + return new AFPPageSegmentSetup(getLocalName()); + } + + /** + * This is the pass-through value object for the AFP extension. + */ + public static class AFPPageSegmentSetup extends AFPPageSetup { + + private static final long serialVersionUID = 1L; + + private String resourceSrc; + + /** + * Default constructor. + * + * @param elementName the name of the setup code object, may be null + */ + public AFPPageSegmentSetup(String elementName) { + super(elementName); + } + + /** + * Returns the source URI for the page segment. + * @return the source URI + */ + public String getResourceSrc() { + return resourceSrc; + } + + /** + * Sets the source URI for the page segment. + * @param resourceSrc the source URI + */ + public void setResourceSrc(String resourceSrc) { + this.resourceSrc = resourceSrc.trim(); + } + + + /** {@inheritDoc} */ + public void toSAX(ContentHandler handler) throws SAXException { + AttributesImpl atts = new AttributesImpl(); + if (name != null && name.length() > 0) { + atts.addAttribute(null, ATT_NAME, ATT_NAME, "CDATA", name); + } + if (value != null && value.length() > 0) { + atts.addAttribute(null, ATT_VALUE, ATT_VALUE, "CDATA", value); + } + + if (resourceSrc != null && resourceSrc.length() > 0) { + atts.addAttribute(null, ATT_RESOURCE_SRC, ATT_RESOURCE_SRC, "CDATA", resourceSrc); + } + + handler.startElement(CATEGORY, elementName, elementName, atts); + if (content != null && content.length() > 0) { + char[] chars = content.toCharArray(); + handler.characters(chars, 0, chars.length); + } + handler.endElement(CATEGORY, elementName, elementName); + } + + /** {@inheritDoc} */ + public String toString() { + return "AFPPageSegmentSetup(element-name=" + getElementName() + + " name=" + getName() + + " value=" + getValue() + + " resource=" + getResourceSrc() + ")"; + } + + } + + +} diff --git a/status.xml b/status.xml index 42ab391cc..131312589 100644 --- a/status.xml +++ b/status.xml @@ -58,6 +58,9 @@ documents. Example: the fix of marks layering will be such a case when it's done. --> + + Added ability to embed an external AFP page segment resource file (AFP output only). + Fixed a multi-threading issue when rendering SVG. -- cgit v1.2.3 From 96d303859b3bd045af84e7c44554eee3a9c0f8d0 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Mon, 11 Oct 2010 12:41:37 +0000 Subject: Bugfix for unescaped name characters which can cause trouble with PDF parsers. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1021325 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/pdf/PDFName.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/java/org/apache/fop/pdf/PDFName.java b/src/java/org/apache/fop/pdf/PDFName.java index 8214cda76..419907429 100644 --- a/src/java/org/apache/fop/pdf/PDFName.java +++ b/src/java/org/apache/fop/pdf/PDFName.java @@ -41,6 +41,7 @@ public class PDFName extends PDFObject { this.name = escapeName(name); } + private static final String ESCAPED_NAME_CHARS = "/()<>[]"; /** * Escapes a PDF name. It adds the leading slash and escapes characters as necessary. @@ -56,7 +57,8 @@ public class PDFName extends PDFObject { } for (int i = (skipFirst ? 1 : 0), c = name.length(); i < c; i++) { char ch = name.charAt(i); - if (ch < 33 || ch > 126 || ch == 0x2F) { + + if (ch < 33 || ch > 126 || ESCAPED_NAME_CHARS.indexOf(ch) >= 0) { sb.append('#'); toHex(ch, sb); } else { -- cgit v1.2.3 From c7f63f3f3a9d864e4da0940ad1d0dbf7a60f558a Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Thu, 21 Oct 2010 06:44:32 +0000 Subject: Wrap the whole page stream in a q..Q pair to avoid problems when the page streams are combined later with additional content. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1025850 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java b/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java index cf3053e19..409b8dd9f 100644 --- a/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java +++ b/src/java/org/apache/fop/svg/PDFDocumentGraphics2D.java @@ -256,6 +256,7 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D { if (!pdfContext.isPagePending()) { return; //ignore } + currentStream.write("Q\n"); //Finish page PDFStream pdfStream = this.pdfDoc.getFactory().makeStream( PDFFilterList.CONTENT_FILTER, false); @@ -321,6 +322,7 @@ public class PDFDocumentGraphics2D extends PDFGraphics2D { pdfContext.setCurrentPage(page); pageRef = page.referencePDF(); + currentStream.write("q\n"); AffineTransform at = new AffineTransform(1.0, 0.0, 0.0, -1.0, 0.0, height); currentStream.write("1 0 0 -1 0 " + height + " cm\n"); -- cgit v1.2.3 From e7e29079203c8f847be894289e9bc177fba06cd8 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Thu, 21 Oct 2010 14:01:59 +0000 Subject: Allow to pass through document-level extensions from the first document passed to the IFConcatenator. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1026003 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/fop/render/intermediate/util/IFConcatenator.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/java/org/apache/fop/render/intermediate/util/IFConcatenator.java b/src/java/org/apache/fop/render/intermediate/util/IFConcatenator.java index 4b0a3fe68..71ee7a0b0 100644 --- a/src/java/org/apache/fop/render/intermediate/util/IFConcatenator.java +++ b/src/java/org/apache/fop/render/intermediate/util/IFConcatenator.java @@ -19,7 +19,6 @@ package org.apache.fop.render.intermediate.util; - import java.awt.Dimension; import javax.xml.transform.Source; @@ -39,12 +38,17 @@ import org.apache.fop.render.intermediate.IFParser; *

    * Note: This class will filter/ignore any document navigation events. Support for this may be * added later. + *

    + * Note: document-level extensions will only be transferred from the first document passed in. + * If you need to merge extensions from all the concatenated documents, you may have to merge + * these manually on the XML level, for example using XSLT. */ public class IFConcatenator { private IFDocumentHandler targetHandler; private int nextPageIndex = 0; + private boolean inFirstDocument = true; /** * Creates a new IF concatenator. @@ -163,14 +167,17 @@ public class IFConcatenator { /** {@inheritDoc} */ public void endDocument() throws IFException { //ignore + inFirstDocument = false; } /** {@inheritDoc} */ public void handleExtensionObject(Object extension) throws IFException { - if (inPageSequence) { + if (inPageSequence || inFirstDocument) { //Only pass through when inside page-sequence + //or for the first document (for document-level extensions). super.handleExtensionObject(extension); } + //Note:Extensions from non-first documents are ignored! } /** {@inheritDoc} */ -- cgit v1.2.3 From 2089591b3d2595369e0d32fb9d2f783c87fa9499 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Thu, 21 Oct 2010 14:12:07 +0000 Subject: Copy attributes since some XML parsers might reuse the Attributes instance. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1026006 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java | 3 ++- src/java/org/apache/fop/render/pdf/extensions/PDFExtensionHandler.java | 3 ++- src/java/org/apache/fop/render/ps/extensions/PSExtensionHandler.java | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java b/src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java index 5652a49bf..f2e77ec33 100644 --- a/src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java +++ b/src/java/org/apache/fop/render/afp/extensions/AFPExtensionHandler.java @@ -24,6 +24,7 @@ import java.net.URISyntaxException; import org.xml.sax.Attributes; import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; import org.xml.sax.helpers.DefaultHandler; import org.apache.commons.logging.Log; @@ -53,7 +54,7 @@ public class AFPExtensionHandler extends DefaultHandler throws SAXException { boolean handled = false; if (AFPExtensionAttachment.CATEGORY.equals(uri)) { - lastAttributes = attributes; + lastAttributes = new AttributesImpl(attributes); handled = true; if (localName.equals(AFPElementMapping.NO_OPERATION) || localName.equals(AFPElementMapping.TAG_LOGICAL_ELEMENT) diff --git a/src/java/org/apache/fop/render/pdf/extensions/PDFExtensionHandler.java b/src/java/org/apache/fop/render/pdf/extensions/PDFExtensionHandler.java index d285904a8..04c95545c 100644 --- a/src/java/org/apache/fop/render/pdf/extensions/PDFExtensionHandler.java +++ b/src/java/org/apache/fop/render/pdf/extensions/PDFExtensionHandler.java @@ -21,6 +21,7 @@ package org.apache.fop.render.pdf.extensions; import org.xml.sax.Attributes; import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; import org.xml.sax.helpers.DefaultHandler; import org.apache.commons.logging.Log; @@ -48,7 +49,7 @@ public class PDFExtensionHandler extends DefaultHandler throws SAXException { boolean handled = false; if (PDFExtensionAttachment.CATEGORY.equals(uri)) { - lastAttributes = attributes; + lastAttributes = new AttributesImpl(attributes); handled = false; if (localName.equals(PDFEmbeddedFileExtensionAttachment.ELEMENT)) { //handled in endElement diff --git a/src/java/org/apache/fop/render/ps/extensions/PSExtensionHandler.java b/src/java/org/apache/fop/render/ps/extensions/PSExtensionHandler.java index dee918f19..bf970d0a6 100644 --- a/src/java/org/apache/fop/render/ps/extensions/PSExtensionHandler.java +++ b/src/java/org/apache/fop/render/ps/extensions/PSExtensionHandler.java @@ -21,6 +21,7 @@ package org.apache.fop.render.ps.extensions; import org.xml.sax.Attributes; import org.xml.sax.SAXException; +import org.xml.sax.helpers.AttributesImpl; import org.xml.sax.helpers.DefaultHandler; import org.apache.commons.logging.Log; @@ -49,7 +50,7 @@ public class PSExtensionHandler extends DefaultHandler throws SAXException { boolean handled = false; if (PSExtensionAttachment.CATEGORY.equals(uri)) { - lastAttributes = attributes; + lastAttributes = new AttributesImpl(attributes); handled = false; if (localName.equals(PSSetupCode.ELEMENT) || localName.equals(PSSetPageDevice.ELEMENT) -- cgit v1.2.3 From 0a3aa3b66cfa03b255c96510755a810473a3b81b Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Thu, 21 Oct 2010 19:24:29 +0000 Subject: Bugzilla #42600: Added some support for break-before/-after for RTF output. Submitted by: Maximilian Aster Changes to patch: - Code style fixes - Removed dependency from rtflib to FO Constants. - Tried to implement even/odd/column breaks git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1026110 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/render/rtf/RTFHandler.java | 25 +++- .../fop/render/rtf/TextAttributesConverter.java | 39 ++++++ .../fop/render/rtf/rtflib/rtfdoc/RtfTextrun.java | 133 +++++++++++++++------ status.xml | 3 + 4 files changed, 162 insertions(+), 38 deletions(-) diff --git a/src/java/org/apache/fop/render/rtf/RTFHandler.java b/src/java/org/apache/fop/render/rtf/RTFHandler.java index 5698329c8..35f58e170 100644 --- a/src/java/org/apache/fop/render/rtf/RTFHandler.java +++ b/src/java/org/apache/fop/render/rtf/RTFHandler.java @@ -80,11 +80,11 @@ import org.apache.fop.fo.flow.PageNumber; import org.apache.fop.fo.flow.PageNumberCitation; import org.apache.fop.fo.flow.table.Table; import org.apache.fop.fo.flow.table.TableBody; -import org.apache.fop.fo.flow.table.TableFooter; -import org.apache.fop.fo.flow.table.TablePart; import org.apache.fop.fo.flow.table.TableCell; import org.apache.fop.fo.flow.table.TableColumn; +import org.apache.fop.fo.flow.table.TableFooter; import org.apache.fop.fo.flow.table.TableHeader; +import org.apache.fop.fo.flow.table.TablePart; import org.apache.fop.fo.flow.table.TableRow; import org.apache.fop.fo.pagination.Flow; import org.apache.fop.fo.pagination.PageSequence; @@ -436,7 +436,8 @@ public class RTFHandler extends FOEventHandler { RtfTextrun textrun = container.getTextrun(); textrun.addParagraphBreak(); - textrun.popBlockAttributes(); + int breakValue = toRtfBreakValue(bl.getBreakAfter()); + textrun.popBlockAttributes(breakValue); } catch (IOException ioe) { handleIOTrouble(ioe); @@ -488,7 +489,8 @@ public class RTFHandler extends FOEventHandler { RtfTextrun textrun = container.getTextrun(); textrun.addParagraphBreak(); - textrun.popBlockAttributes(); + int breakValue = toRtfBreakValue(bl.getBreakAfter()); + textrun.popBlockAttributes(breakValue); } catch (IOException ioe) { handleIOTrouble(ioe); @@ -498,6 +500,21 @@ public class RTFHandler extends FOEventHandler { } } + private int toRtfBreakValue(int foBreakValue) { + switch (foBreakValue) { + case Constants.EN_PAGE: + return RtfTextrun.BREAK_PAGE; + case Constants.EN_EVEN_PAGE: + return RtfTextrun.BREAK_EVEN_PAGE; + case Constants.EN_ODD_PAGE: + return RtfTextrun.BREAK_ODD_PAGE; + case Constants.EN_COLUMN: + return RtfTextrun.BREAK_COLUMN; + default: + return RtfTextrun.BREAK_NONE; + } + } + /** {@inheritDoc} */ public void startTable(Table tbl) { if (bDefer) { diff --git a/src/java/org/apache/fop/render/rtf/TextAttributesConverter.java b/src/java/org/apache/fop/render/rtf/TextAttributesConverter.java index 1b7e21bd3..6035b9192 100644 --- a/src/java/org/apache/fop/render/rtf/TextAttributesConverter.java +++ b/src/java/org/apache/fop/render/rtf/TextAttributesConverter.java @@ -35,6 +35,7 @@ import org.apache.fop.fo.flow.BlockContainer; import org.apache.fop.fo.flow.Inline; import org.apache.fop.fo.flow.Leader; import org.apache.fop.fo.flow.PageNumber; +import org.apache.fop.fo.flow.table.TableCell; import org.apache.fop.fo.properties.CommonBorderPaddingBackground; import org.apache.fop.fo.properties.CommonFont; import org.apache.fop.fo.properties.CommonMarginBlock; @@ -80,10 +81,48 @@ final class TextAttributesConverter { attrBlockMargin(fobj.getCommonMarginBlock(), attrib); attrBlockTextAlign(fobj.getTextAlign(), attrib); attrBorder(fobj.getCommonBorderPaddingBackground(), attrib, fobj); + attrBreak(fobj, attrib); return attrib; } + private static void attrBreak(Block fobj, FOPRtfAttributes attrib) { + int breakValue = fobj.getBreakBefore(); + if (breakValue != Constants.EN_NONE) { + //"sect" Creates a new section and a page break, + //a simple page break with control word "page" caused + //some problems + boolean bHasTableCellParent = false; + FONode f = fobj; + while (f.getParent() != null) { + f = f.getParent(); + if (f instanceof TableCell) { + bHasTableCellParent = true; + break; + } + } + if (!bHasTableCellParent) { + attrib.set("sect"); + switch (breakValue) { + case Constants.EN_EVEN_PAGE: + attrib.set("sbkeven"); + break; + case Constants.EN_ODD_PAGE: + attrib.set("sbkodd"); + break; + case Constants.EN_COLUMN: + attrib.set("sbkcol"); + break; + default: + attrib.set("sbkpage"); + } + } else { + log.warn("Cannot create break-before for a block inside a table."); + } + } + //Break after is handled in RtfCloseGroupMark + } + /** * Converts all known text FO properties to RtfAttributes * @param fobj FObj whose properties are to be converted diff --git a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTextrun.java b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTextrun.java index 4831ffd86..128c9a3df 100644 --- a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTextrun.java +++ b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfTextrun.java @@ -25,9 +25,10 @@ import java.io.Writer; import java.util.Iterator; import java.util.List; import java.util.ListIterator; +import java.util.Stack; -// FOP -import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfExternalGraphic; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; /** * Class which contains a linear text run. It has methods to add attributes, @@ -35,9 +36,26 @@ import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfExternalGraphic; * @author Peter Herweg, pherweg@web.de */ public class RtfTextrun extends RtfContainer { + + /** Constant for no page break */ + public static final int BREAK_NONE = 0; + /** Constant for a normal page break */ + public static final int BREAK_PAGE = 1; + /** Constant for a column break */ + public static final int BREAK_COLUMN = 2; + /** Constant for a even page break */ + public static final int BREAK_EVEN_PAGE = 3; + /** Constant for a odd page break */ + public static final int BREAK_ODD_PAGE = 4; + private boolean bSuppressLastPar = false; private RtfListItem rtfListItem; + /** + * logging instance + */ + protected static Log log = LogFactory.getLog(RtfTextrun.class); + /** Manager for handling space-* property. */ private RtfSpaceManager rtfSpaceManager = new RtfSpaceManager(); @@ -68,10 +86,12 @@ public class RtfTextrun extends RtfContainer { /** Class which represents the closing of a RTF group mark.*/ private class RtfCloseGroupMark extends RtfElement { + private int breakType = BREAK_NONE; - RtfCloseGroupMark(RtfContainer parent, Writer w) - throws IOException { + RtfCloseGroupMark(RtfContainer parent, Writer w, int breakType) + throws IOException { super(parent, w); + this.breakType = breakType; } /** @@ -82,11 +102,44 @@ public class RtfTextrun extends RtfContainer { } /** - * write RTF code of all our children + * Returns the break type. + * @return the break type (BREAK_* constants) + */ + public int getBreakType() { + return breakType; + } + + /** + * Write RTF code of all our children. * @throws IOException for I/O problems */ protected void writeRtfContent() throws IOException { writeGroupMark(false); + boolean bHasTableCellParent = this.getParentOfClass(RtfTableCell.class) != null; + + //Unknown behavior when a table starts a new section, + //Word may crash + if (breakType != BREAK_NONE) { + if (!bHasTableCellParent) { + writeControlWord("sect"); + /* The following modifiers don't seem to appear in the right place */ + switch (breakType) { + case BREAK_EVEN_PAGE: + writeControlWord("sbkeven"); + break; + case BREAK_ODD_PAGE: + writeControlWord("sbkodd"); + break; + case BREAK_COLUMN: + writeControlWord("sbkcol"); + break; + default: + writeControlWord("sbkpage"); + } + } else { + log.warn("Cannot create break-after for a paragraph inside a table."); + } + } } } @@ -135,8 +188,18 @@ public class RtfTextrun extends RtfContainer { * * @throws IOException for I/O problems */ + private void addCloseGroupMark(int breakType) throws IOException { + RtfCloseGroupMark r = new RtfCloseGroupMark(this, writer, breakType); + } + + /** + * Adds instance of CloseGroupMark as a child, but without a break option. + * Inline attributes do not need that for example + * + * @throws IOException for I/O problems + */ private void addCloseGroupMark() throws IOException { - RtfCloseGroupMark r = new RtfCloseGroupMark(this, writer); + RtfCloseGroupMark r = new RtfCloseGroupMark(this, writer, BREAK_NONE); } /** @@ -155,14 +218,14 @@ public class RtfTextrun extends RtfContainer { /** * Pops block attributes, notifies all opened blocks about pushing block * attributes, adds CloseGroupMark as a child. - * + * @param breakType the break type * @throws IOException for I/O problems */ - public void popBlockAttributes() throws IOException { - rtfSpaceManager.popRtfSpaceSplitter(); - rtfSpaceManager.stopUpdatingSpaceBefore(); - addCloseGroupMark(); - } + public void popBlockAttributes(int breakType) throws IOException { + rtfSpaceManager.popRtfSpaceSplitter(); + rtfSpaceManager.stopUpdatingSpaceBefore(); + addCloseGroupMark(breakType); + } /** * Pushes inline attributes. @@ -228,28 +291,30 @@ public class RtfTextrun extends RtfContainer { * @throws IOException for I/O problems */ public void addParagraphBreak() throws IOException { - // get copy of children list - List children = getChildren(); - - // delete all previous CloseGroupMark - int deletedCloseGroupCount = 0; - - ListIterator lit = children.listIterator(children.size()); - while (lit.hasPrevious() - && (lit.previous() instanceof RtfCloseGroupMark)) { - lit.remove(); - deletedCloseGroupCount++; - } - - if (children.size() != 0) { - // add paragraph break and restore all deleted close group marks - setChildren(children); - new RtfParagraphBreak(this, writer); - for (int i = 0; i < deletedCloseGroupCount; i++) { - addCloseGroupMark(); - } - } - } + // get copy of children list + List children = getChildren(); + Stack tmp = new Stack(); + + // delete all previous CloseGroupMark + int deletedCloseGroupCount = 0; + + ListIterator lit = children.listIterator(children.size()); + while (lit.hasPrevious() + && (lit.previous() instanceof RtfCloseGroupMark)) { + tmp.push(new Integer(((RtfCloseGroupMark)lit.next()).getBreakType())); + lit.remove(); + deletedCloseGroupCount++; + } + + if (children.size() != 0) { + // add paragraph break and restore all deleted close group marks + setChildren(children); + new RtfParagraphBreak(this, writer); + for (int i = 0; i < deletedCloseGroupCount; i++) { + addCloseGroupMark(((Integer)tmp.pop()).intValue()); + } + } + } /** * Inserts a leader. diff --git a/status.xml b/status.xml index 131312589..a0079f995 100644 --- a/status.xml +++ b/status.xml @@ -58,6 +58,9 @@ documents. Example: the fix of marks layering will be such a case when it's done. --> + + Added some support for break-before/-after for RTF output. + Added ability to embed an external AFP page segment resource file (AFP output only). -- cgit v1.2.3 From 351d9426dad94ffc70259be33e96bc2f7c61bd5e Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Thu, 21 Oct 2010 19:32:06 +0000 Subject: Bugzilla #42600: Wrong constant used. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1026114 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/render/rtf/TextAttributesConverter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java/org/apache/fop/render/rtf/TextAttributesConverter.java b/src/java/org/apache/fop/render/rtf/TextAttributesConverter.java index 6035b9192..d377f740d 100644 --- a/src/java/org/apache/fop/render/rtf/TextAttributesConverter.java +++ b/src/java/org/apache/fop/render/rtf/TextAttributesConverter.java @@ -88,7 +88,7 @@ final class TextAttributesConverter { private static void attrBreak(Block fobj, FOPRtfAttributes attrib) { int breakValue = fobj.getBreakBefore(); - if (breakValue != Constants.EN_NONE) { + if (breakValue != Constants.EN_AUTO) { //"sect" Creates a new section and a page break, //a simple page break with control word "page" caused //some problems -- cgit v1.2.3 From a2f1dbe772277b645632ec3f86aa73a0f0bfdac9 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Tue, 26 Oct 2010 12:48:55 +0000 Subject: Added two more character to be escaped in a PDF name (now in sync with PDFBox). git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1027520 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/pdf/PDFName.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java/org/apache/fop/pdf/PDFName.java b/src/java/org/apache/fop/pdf/PDFName.java index 419907429..3f9af7669 100644 --- a/src/java/org/apache/fop/pdf/PDFName.java +++ b/src/java/org/apache/fop/pdf/PDFName.java @@ -41,7 +41,7 @@ public class PDFName extends PDFObject { this.name = escapeName(name); } - private static final String ESCAPED_NAME_CHARS = "/()<>[]"; + private static final String ESCAPED_NAME_CHARS = "/()<>[]%#"; /** * Escapes a PDF name. It adds the leading slash and escapes characters as necessary. -- cgit v1.2.3 From 5d507935e659831813565d10b328f45500aa9831 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Wed, 27 Oct 2010 16:03:30 +0000 Subject: Small improvement for XMP generation. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1028021 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/pdf/PDFMetadata.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/java/org/apache/fop/pdf/PDFMetadata.java b/src/java/org/apache/fop/pdf/PDFMetadata.java index 49f762708..b9612d11b 100644 --- a/src/java/org/apache/fop/pdf/PDFMetadata.java +++ b/src/java/org/apache/fop/pdf/PDFMetadata.java @@ -151,6 +151,9 @@ public class PDFMetadata extends PDFStream { } dc.addDate(info.getCreationDate()); + //Somewhat redundant but some PDF/A checkers issue a warning without this. + dc.setFormat("application/pdf"); + //PDF/A identification PDFAMode pdfaMode = pdfDoc.getProfile().getPDFAMode(); if (pdfaMode.isPDFA1LevelB()) { -- cgit v1.2.3 From 353cb3efa6ada2033a43eef693c6beabd2d9c3bf Mon Sep 17 00:00:00 2001 From: Vincent Hennebert Date: Mon, 8 Nov 2010 11:42:01 +0000 Subject: Added entry about bug 45971 git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1032549 13f79535-47bb-0310-9956-ffa450edef68 --- status.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/status.xml b/status.xml index a0079f995..b651ddf89 100644 --- a/status.xml +++ b/status.xml @@ -407,6 +407,9 @@ Fixed a problem where the BPD or a block area could be wrong if there is a nested, absolutely positioned area (for example a block-container). + + Improved the behaviour of the command line interface. + Bugzilla 40798: A conditional-page-master-reference with page-position="last" qualifies for a first page, if it is also the last. Additionally: also added support for -- cgit v1.2.3 From 1939c00e198dd9c45bc5847dd58f27485372934e Mon Sep 17 00:00:00 2001 From: Simon Pepping Date: Thu, 11 Nov 2010 09:48:24 +0000 Subject: Applied patch 50240 by Mehdi Houshmand with changes: Java source and target changed to 1.5. EncodingMode changed from class -> enum. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1033859 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 4 +-- src/java/org/apache/fop/fonts/EncodingMode.java | 35 +++++++--------------- .../org/apache/fop/fonts/FontInfoConfigurator.java | 2 +- .../org/apache/fop/fonts/EncodingModeTest.java | 17 +++++++++++ 4 files changed, 31 insertions(+), 27 deletions(-) create mode 100644 test/java/org/apache/fop/fonts/EncodingModeTest.java diff --git a/build.xml b/build.xml index 15e6d0ac4..ae4f5c886 100644 --- a/build.xml +++ b/build.xml @@ -149,8 +149,8 @@ list of possible build targets. - - + + diff --git a/src/java/org/apache/fop/fonts/EncodingMode.java b/src/java/org/apache/fop/fonts/EncodingMode.java index 734292c54..8a40d6593 100644 --- a/src/java/org/apache/fop/fonts/EncodingMode.java +++ b/src/java/org/apache/fop/fonts/EncodingMode.java @@ -19,25 +19,19 @@ package org.apache.fop.fonts; -import java.io.ObjectStreamException; -import java.io.Serializable; - - /** * This class enumerates all supported encoding modes for fonts: auto, single-byte and CID. */ -public final class EncodingMode implements Serializable { - - private static final long serialVersionUID = 8311486102457779529L; +public enum EncodingMode { /** Automatic selection of encoding mode. */ - public static final EncodingMode AUTO = new EncodingMode("auto"); + AUTO("auto"), /** Single-byte encoding */ - public static final EncodingMode SINGLE_BYTE = new EncodingMode("single-byte"); + SINGLE_BYTE("single-byte"), /** CID encoding */ - public static final EncodingMode CID = new EncodingMode("cid"); + CID("cid"); private String name; @@ -58,25 +52,18 @@ public final class EncodingMode implements Serializable { * @param name the name of the encoding mode to look up * @return the encoding mode constant */ - public static EncodingMode valueOf(String name) { - if (name.equalsIgnoreCase(EncodingMode.AUTO.getName())) { - return EncodingMode.AUTO; - } else if (name.equalsIgnoreCase(EncodingMode.SINGLE_BYTE.getName())) { - return EncodingMode.SINGLE_BYTE; - } else if (name.equalsIgnoreCase(EncodingMode.CID.getName())) { - return EncodingMode.CID; - } else { - throw new IllegalArgumentException("Invalid encoding mode: " + name); + public static EncodingMode getEncodingMode(String name) { + for (EncodingMode em : EncodingMode.values()) { + if (name.equalsIgnoreCase(em.getName())) { + return em; + } } - } - - private Object readResolve() throws ObjectStreamException { - return valueOf(getName()); + throw new IllegalArgumentException("Invalid encoding mode: " + name); } /** {@inheritDoc} */ public String toString() { - return "EncodingMode:" + getName(); + return "EncodingMode: " + getName(); } } diff --git a/src/java/org/apache/fop/fonts/FontInfoConfigurator.java b/src/java/org/apache/fop/fonts/FontInfoConfigurator.java index f8399b110..9a11f84bc 100644 --- a/src/java/org/apache/fop/fonts/FontInfoConfigurator.java +++ b/src/java/org/apache/fop/fonts/FontInfoConfigurator.java @@ -254,7 +254,7 @@ public class FontInfoConfigurator { } boolean useKerning = fontCfg.getAttributeAsBoolean("kerning", true); - EncodingMode encodingMode = EncodingMode.valueOf( + EncodingMode encodingMode = EncodingMode.getEncodingMode( fontCfg.getAttribute("encoding-mode", EncodingMode.AUTO.getName())); EmbedFontInfo embedFontInfo = new EmbedFontInfo(metricsUrl, useKerning, tripletList, embedUrl, subFont); diff --git a/test/java/org/apache/fop/fonts/EncodingModeTest.java b/test/java/org/apache/fop/fonts/EncodingModeTest.java new file mode 100644 index 000000000..d291f4c0b --- /dev/null +++ b/test/java/org/apache/fop/fonts/EncodingModeTest.java @@ -0,0 +1,17 @@ +package org.apache.fop.fonts; + +import junit.framework.TestCase; + +public class EncodingModeTest extends TestCase { + public void testGetName() { + assertEquals("auto", EncodingMode.AUTO.getName()); + assertEquals("single-byte", EncodingMode.SINGLE_BYTE.getName()); + assertEquals("cid", EncodingMode.CID.getName()); + } + + public void testGetValue() { + assertEquals(EncodingMode.AUTO, EncodingMode.getEncodingMode("auto")); + assertEquals(EncodingMode.SINGLE_BYTE, EncodingMode.getEncodingMode("single-byte")); + assertEquals(EncodingMode.CID, EncodingMode.getEncodingMode("cid")); + } +} -- cgit v1.2.3 From e6245e4939c018c81f41ec548dc61a8669c749d0 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Mon, 15 Nov 2010 13:51:20 +0000 Subject: Removed tab characters. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1035275 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/fop/fonts/EncodingModeTest.java | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/test/java/org/apache/fop/fonts/EncodingModeTest.java b/test/java/org/apache/fop/fonts/EncodingModeTest.java index d291f4c0b..a76b33e9f 100644 --- a/test/java/org/apache/fop/fonts/EncodingModeTest.java +++ b/test/java/org/apache/fop/fonts/EncodingModeTest.java @@ -3,15 +3,15 @@ package org.apache.fop.fonts; import junit.framework.TestCase; public class EncodingModeTest extends TestCase { - public void testGetName() { - assertEquals("auto", EncodingMode.AUTO.getName()); - assertEquals("single-byte", EncodingMode.SINGLE_BYTE.getName()); - assertEquals("cid", EncodingMode.CID.getName()); - } - - public void testGetValue() { - assertEquals(EncodingMode.AUTO, EncodingMode.getEncodingMode("auto")); - assertEquals(EncodingMode.SINGLE_BYTE, EncodingMode.getEncodingMode("single-byte")); - assertEquals(EncodingMode.CID, EncodingMode.getEncodingMode("cid")); - } + public void testGetName() { + assertEquals("auto", EncodingMode.AUTO.getName()); + assertEquals("single-byte", EncodingMode.SINGLE_BYTE.getName()); + assertEquals("cid", EncodingMode.CID.getName()); + } + + public void testGetValue() { + assertEquals(EncodingMode.AUTO, EncodingMode.getEncodingMode("auto")); + assertEquals(EncodingMode.SINGLE_BYTE, EncodingMode.getEncodingMode("single-byte")); + assertEquals(EncodingMode.CID, EncodingMode.getEncodingMode("cid")); + } } -- cgit v1.2.3 From 3dc848243b02e9a7b1c24b4dfd252dc545bfa0f7 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Mon, 15 Nov 2010 13:52:58 +0000 Subject: Added missing license header. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1035276 13f79535-47bb-0310-9956-ffa450edef68 --- test/java/org/apache/fop/fonts/EncodingModeTest.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/java/org/apache/fop/fonts/EncodingModeTest.java b/test/java/org/apache/fop/fonts/EncodingModeTest.java index a76b33e9f..4e81c46d6 100644 --- a/test/java/org/apache/fop/fonts/EncodingModeTest.java +++ b/test/java/org/apache/fop/fonts/EncodingModeTest.java @@ -1,3 +1,22 @@ +/* + * 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.fonts; import junit.framework.TestCase; -- cgit v1.2.3