aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--build.xml32
-rw-r--r--lib/xmlgraphics-commons-1.4svn.jarbin554968 -> 552493 bytes
-rw-r--r--src/documentation/content/xdocs/trunk/anttask.xml35
-rw-r--r--src/java/org/apache/fop/afp/AFPDataObjectFactory.java34
-rw-r--r--src/java/org/apache/fop/afp/AFPPaintingState.java23
-rw-r--r--src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java18
-rw-r--r--src/java/org/apache/fop/afp/ioca/IDEStructureParameter.java151
-rw-r--r--src/java/org/apache/fop/afp/ioca/ImageContent.java104
-rw-r--r--src/java/org/apache/fop/afp/ioca/ImageSegment.java10
-rw-r--r--src/java/org/apache/fop/afp/modca/AbstractAFPObject.java17
-rw-r--r--src/java/org/apache/fop/afp/modca/AbstractTripletStructuredObject.java9
-rw-r--r--src/java/org/apache/fop/afp/modca/ContainerDataDescriptor.java2
-rw-r--r--src/java/org/apache/fop/afp/modca/ImageDataDescriptor.java1
-rw-r--r--src/java/org/apache/fop/afp/modca/ImageObject.java13
-rw-r--r--src/java/org/apache/fop/afp/modca/TagLogicalElement.java111
-rw-r--r--src/java/org/apache/fop/afp/modca/triplets/AbstractTriplet.java62
-rw-r--r--src/java/org/apache/fop/afp/modca/triplets/AttributeQualifierTriplet.java67
-rw-r--r--src/java/org/apache/fop/afp/modca/triplets/AttributeValueTriplet.java72
-rw-r--r--src/java/org/apache/fop/afp/modca/triplets/Triplet.java85
-rw-r--r--src/java/org/apache/fop/cli/CommandLineOptions.java7
-rw-r--r--src/java/org/apache/fop/cli/InputHandler.java119
-rw-r--r--src/java/org/apache/fop/fo/FObj.java4
-rw-r--r--src/java/org/apache/fop/fonts/CIDSubset.java4
-rw-r--r--src/java/org/apache/fop/fonts/Font.java5
-rw-r--r--src/java/org/apache/fop/layoutmgr/AbstractBreaker.java50
-rw-r--r--src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java61
-rw-r--r--src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java42
-rw-r--r--src/java/org/apache/fop/layoutmgr/ElementListUtils.java30
-rw-r--r--src/java/org/apache/fop/layoutmgr/InlineKnuthSequence.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/KnuthBox.java20
-rw-r--r--src/java/org/apache/fop/layoutmgr/KnuthElement.java22
-rw-r--r--src/java/org/apache/fop/layoutmgr/KnuthGlue.java49
-rw-r--r--src/java/org/apache/fop/layoutmgr/KnuthPenalty.java69
-rw-r--r--src/java/org/apache/fop/layoutmgr/KnuthSequence.java5
-rw-r--r--src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java47
-rw-r--r--src/java/org/apache/fop/layoutmgr/PageProvider.java11
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java4
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java6
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java45
-rw-r--r--src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java14
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/ActiveCell.java24
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/RowPainter.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java2
-rw-r--r--src/java/org/apache/fop/pdf/PDFFontNonBase14.java2
-rw-r--r--src/java/org/apache/fop/render/afp/AFPCustomizable.java8
-rw-r--r--src/java/org/apache/fop/render/afp/AFPDocumentHandler.java5
-rw-r--r--src/java/org/apache/fop/render/afp/AFPImageHandlerRawStream.java9
-rw-r--r--src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java34
-rw-r--r--src/java/org/apache/fop/render/afp/AFPRenderer.java8
-rw-r--r--src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java3
-rw-r--r--src/java/org/apache/fop/tools/anttasks/Fop.java138
-rw-r--r--status.xml12
-rw-r--r--test/java/org/apache/fop/layoutengine/ElementListCheck.java36
-rw-r--r--test/java/org/apache/fop/util/ElementListUtilsTestCase.java30
-rw-r--r--test/layoutengine/standard-testcases/flow_changing-ipd_no-restartable.xml404
-rw-r--r--test/layoutengine/standard-testcases/flow_changing-ipd_table-after-break.xml80
58 files changed, 1711 insertions, 552 deletions
diff --git a/build.xml b/build.xml
index b9b5a7b36..0e0b98935 100644
--- a/build.xml
+++ b/build.xml
@@ -156,10 +156,14 @@ list of possible build targets.
<property name="fo.examples.userconfig" value="conf/fop.xconf"/>
<property name="fo.examples.include" value="**/*.fo"/>
<property name="fo.examples.force" value="false"/>
+ <property name="xml.tests.include" value="**/*.xml"/>
+ <property name="xml.tests.force" value="false"/>
+ <property name="xml.tests.userconfig" value="conf/fop.xconf"/>
<property name="lib.dir" value="${basedir}/lib"/>
<property name="user.hyph.dir" value="${basedir}/hyph"/>
<property name="unidata.dir" value="${basedir}/UNIDATA"/>
<property name="hyph.stacksize" value="512k"/>
+ <property name="test.dir" value="${basedir}/test"/>
<property name="build.dir" value="${basedir}/build"/>
<property name="build.gensrc.dir" value="${build.dir}/gensrc"/>
<property name="build.classes.dir" value="${build.dir}/classes"/>
@@ -167,9 +171,11 @@ list of possible build targets.
<property name="build.codegen-classes.dir" value="${build.dir}/codegen-classes"/>
<property name="build.javadocs.dir" value="${build.dir}/javadocs"/>
<property name="build.examples.dir" value="${build.dir}/examples"/>
+ <property name="build.tests.dir" value="${build.dir}/tests"/>
<property name="build.viewer.resources.dir" value="${build.classes.dir}/org/apache/fop/render/awt/viewer/resources"/>
<property name="build.viewer.images.dir" value="${build.classes.dir}/org/apache/fop/render/awt/viewer/images"/>
<property name="build.property.examples.mime.type" value="application/pdf"/>
+ <property name="build.property.tests.mime.type" value="application/pdf"/>
<!--property name="layoutengine.disabled" value="test/layoutengine/disabled-testcases.txt"/-->
<!--property name="fotree.disabled" value="test/fotree/disabled-testcases.txt"/-->
<property name="layoutengine.disabled" value="test/layoutengine/disabled-testcases.xml"/>
@@ -755,7 +761,7 @@ list of possible build targets.
<mkdir dir="${build.dir}/test-gensrc"/>
<mkdir dir="${junit.reports.dir}"/>
<javac destdir="${build.dir}/test-classes" fork="${javac.fork}" debug="${javac.debug}" deprecation="${javac.deprecation}" optimize="${javac.optimize}" source="${javac.source}" target="${javac.target}">
- <src path="${basedir}/test/java"/>
+ <src path="${test.dir}/java"/>
<patternset refid="test-sources"/>
<classpath>
<path refid="libs-build-tools-classpath"/>
@@ -765,19 +771,19 @@ list of possible build targets.
</classpath>
</javac>
<copy todir="${build.dir}/test-classes">
- <fileset dir="${basedir}/test/java">
+ <fileset dir="${test.dir}/java">
<include name="**/*.xsl"/>
</fileset>
</copy>
</target>
<target name="junit-compile-copy-resources" if="junit.present">
<eventResourceGenerator modelfile="${build.dir}/test-gensrc/org/apache/fop/events/test-event-model.xml">
- <fileset dir="${basedir}/test/java">
+ <fileset dir="${test.dir}/java">
<include name="**/*.java"/>
</fileset>
</eventResourceGenerator>
<copy todir="${build.dir}/test-classes">
- <fileset dir="${basedir}/test/java">
+ <fileset dir="${test.dir}/java">
<include name="META-INF/**"/>
<include name="**/*.xml"/>
</fileset>
@@ -1336,9 +1342,9 @@ NOTE:
</jar>
</target>
<!-- =================================================================== -->
-<!-- Generate example PDFs -->
+<!-- Generate examples -->
<!-- =================================================================== -->
- <target name="examples" depends="package" description="Generates example PDF files">
+ <target name="examples" depends="package" description="Generates the example files">
<taskdef name="fop" classname="org.apache.fop.tools.anttasks.Fop" classpathref="libs-run-classpath"/>
<mkdir dir="${build.examples.dir}"/>
<fop format="${build.property.examples.mime.type}" outdir="${build.examples.dir}" messagelevel="debug" basedir="${fo.examples.dir}" userconfig="${fo.examples.userconfig}" force="${fo.examples.force}">
@@ -1347,6 +1353,20 @@ NOTE:
</fileset>
</fop>
</target>
+
+<!-- =================================================================== -->
+<!-- Generate unit tests -->
+<!-- =================================================================== -->
+ <target name="tests" depends="package" description="Generates the test files">
+ <taskdef name="fop" classname="org.apache.fop.tools.anttasks.Fop" classpathref="libs-run-classpath"/>
+ <mkdir dir="${build.tests.dir}"/>
+ <fop format="${build.property.tests.mime.type}" xsltfile="${test.dir}/layoutengine/testcase2fo.xsl" outdir="${build.tests.dir}" messagelevel="debug" basedir="${test.dir}" userconfig="${fo.examples.userconfig}" force="${xml.tests.force}">
+ <fileset dir="${test.dir}">
+ <include name="${xml.tests.include}"/>
+ </fileset>
+ </fop>
+ </target>
+
<!-- =================================================================== -->
<!-- Helper task to generate source files that have already been -->
<!-- checked into CVS. For these files, CVS version is the official one -->
diff --git a/lib/xmlgraphics-commons-1.4svn.jar b/lib/xmlgraphics-commons-1.4svn.jar
index 3b0a7230e..103e7c269 100644
--- a/lib/xmlgraphics-commons-1.4svn.jar
+++ b/lib/xmlgraphics-commons-1.4svn.jar
Binary files differ
diff --git a/src/documentation/content/xdocs/trunk/anttask.xml b/src/documentation/content/xdocs/trunk/anttask.xml
index 9dd508ad1..a543a5623 100644
--- a/src/documentation/content/xdocs/trunk/anttask.xml
+++ b/src/documentation/content/xdocs/trunk/anttask.xml
@@ -69,6 +69,16 @@
<td>Yes, if no fileset nested element is used</td>
</tr>
<tr>
+ <td>xmlfile</td>
+ <td>XML input file</td>
+ <td>Yes, if no fofile is specified</td>
+ </tr>
+ <tr>
+ <td>xsltfile</td>
+ <td>XSLT input file</td>
+ <td>Yes, if no fofile is specified</td>
+ </tr>
+ <tr>
<td>outfile</td>
<td>Output filename</td>
<td>Yes, when fofile is used. (This attribute is not valid for filesets.)</td>
@@ -196,6 +206,31 @@
</fop>
</target>
]]></source>
+ <p>
+ The following example transforms and converts a single XML and XSLT file to an AFP document:
+ </p>
+ <source><![CDATA[
+<target name="generate-afp-from-transform" description="Generates a single AFP file from an XSLT stylesheet">
+ <fop format="application/x-afp"
+ xmlfile="c:\working\foDirectory\Document.xml"
+ xsltfile="c:\working\foDirectory\Document.xslt"
+ outfile="c:\working\afpDirectory\Document.afp" />
+</target>
+ ]]></source>
+ <p>
+ This example transforms and converts all XML files within an entire directory to PostScript:
+ </p>
+ <source><![CDATA[
+<target name="generate-multiple-ps-from-transform" description="Generates multiple PostScript files using an XSLT stylesheet">
+ <fop format="application/postscript"
+ xsltfile="c:\working\foDirectory\Document.xslt"
+ outdir="${build.dir}" messagelevel="debug">
+ <fileset dir="${test.dir}">
+ <include name="*.xml"/>
+ </fileset>
+ </fop>
+</target>
+ ]]></source>
</section>
</body>
</document>
diff --git a/src/java/org/apache/fop/afp/AFPDataObjectFactory.java b/src/java/org/apache/fop/afp/AFPDataObjectFactory.java
index f6de7b5b4..792909b9e 100644
--- a/src/java/org/apache/fop/afp/AFPDataObjectFactory.java
+++ b/src/java/org/apache/fop/afp/AFPDataObjectFactory.java
@@ -24,6 +24,7 @@ import java.awt.geom.Rectangle2D;
import org.apache.xmlgraphics.image.codec.tiff.TIFFImage;
import org.apache.xmlgraphics.java2d.Graphics2DImagePainter;
+import org.apache.fop.afp.ioca.IDEStructureParameter;
import org.apache.fop.afp.ioca.ImageContent;
import org.apache.fop.afp.modca.AbstractDataObject;
import org.apache.fop.afp.modca.AbstractNamedAFPObject;
@@ -113,12 +114,35 @@ public class AFPDataObjectFactory {
}
}
- if (imageObjectInfo.isColor()) {
- imageObj.setIDESize((byte) 24);
- } else {
- imageObj.setIDESize((byte) imageObjectInfo.getBitsPerPixel());
+ ImageContent content = imageObj.getImageSegment().getImageContent();
+ int bitsPerPixel = imageObjectInfo.getBitsPerPixel();
+ imageObj.setIDESize((byte) bitsPerPixel);
+ IDEStructureParameter ideStruct;
+ switch (bitsPerPixel) {
+ case 1:
+ //Skip IDE Structure Parameter
+ break;
+ case 4:
+ case 8:
+ ideStruct = content.needIDEStructureParameter();
+ ideStruct.setBitsPerComponent(new int[] {bitsPerPixel});
+ break;
+ case 24:
+ ideStruct = content.needIDEStructureParameter();
+ ideStruct.setDefaultRGBColorModel();
+ break;
+ case 32:
+ ideStruct = content.needIDEStructureParameter();
+ ideStruct.setDefaultCMYKColorModel();
+ break;
+ default:
+ throw new IllegalArgumentException("Unsupported number of bits per pixel: "
+ + bitsPerPixel);
+ }
+ if (imageObjectInfo.isSubtractive()) {
+ ideStruct = content.needIDEStructureParameter();
+ ideStruct.setSubtractive(imageObjectInfo.isSubtractive());
}
- imageObj.setSubtractive(imageObjectInfo.isSubtractive());
imageObj.setData(imageObjectInfo.getData());
diff --git a/src/java/org/apache/fop/afp/AFPPaintingState.java b/src/java/org/apache/fop/afp/AFPPaintingState.java
index 578924d67..643dcb702 100644
--- a/src/java/org/apache/fop/afp/AFPPaintingState.java
+++ b/src/java/org/apache/fop/afp/AFPPaintingState.java
@@ -46,8 +46,10 @@ implements Cloneable {
/** color image support */
private boolean colorImages = false;
- /** images are supported in this AFP environment */
+ /** true if certain image formats may be embedded unchanged in their native format. */
private boolean nativeImagesSupported = false;
+ /** true if CMYK images (requires IOCA FS45 suppport on the target platform) may be generated */
+ private boolean cmykImagesSupported;
/** default value for image depth */
private int bitsPerPixel = 8;
@@ -64,6 +66,7 @@ implements Cloneable {
/** a unit converter */
private final transient AFPUnitConverter unitConv = new AFPUnitConverter(this);
+
/**
* Sets the rotation to be used for portrait pages, valid values are 0
* (default), 90, 180, 270.
@@ -186,6 +189,24 @@ implements Cloneable {
}
/**
+ * Controls whether CMYK images (IOCA FS45) are enabled. By default, support is disabled
+ * for wider compatibility. When disabled, any CMYK image is converted to the selected
+ * color format.
+ * @param value true to enabled CMYK images
+ */
+ public void setCMYKImagesSupported(boolean value) {
+ this.cmykImagesSupported = value;
+ }
+
+ /**
+ * Indicates whether CMYK images (IOCA FS45) are enabled.
+ * @return true if IOCA FS45 is enabled
+ */
+ public boolean isCMYKImagesSupported() {
+ return this.cmykImagesSupported;
+ }
+
+ /**
* Sets the output/device resolution
*
* @param resolution
diff --git a/src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java b/src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java
index 4094314a2..6d6e44c97 100644
--- a/src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java
+++ b/src/java/org/apache/fop/afp/goca/GraphicsCharacterString.java
@@ -45,7 +45,7 @@ public class GraphicsCharacterString extends AbstractGraphicsCoord {
*/
public GraphicsCharacterString(String str, int x, int y) {
super(x, y);
- this.str = truncate(str);
+ this.str = truncate(str, MAX_STR_LEN);
}
/**
@@ -57,7 +57,7 @@ public class GraphicsCharacterString extends AbstractGraphicsCoord {
*/
public GraphicsCharacterString(String str) {
super(null);
- this.str = truncate(str);
+ this.str = truncate(str, MAX_STR_LEN);
}
/** {@inheritDoc} */
@@ -83,20 +83,6 @@ public class GraphicsCharacterString extends AbstractGraphicsCoord {
}
/**
- * Truncates the string as necessary
- *
- * @param str a character string
- * @return a possibly truncated string
- */
- private String truncate(String str) {
- if (str.length() > MAX_STR_LEN) {
- str = str.substring(0, MAX_STR_LEN);
- log.warn("truncated character string, longer than " + MAX_STR_LEN + " chars");
- }
- return str;
- }
-
- /**
* Returns the text string as an encoded byte array
*
* @return the text string as an encoded byte array
diff --git a/src/java/org/apache/fop/afp/ioca/IDEStructureParameter.java b/src/java/org/apache/fop/afp/ioca/IDEStructureParameter.java
new file mode 100644
index 000000000..8c0d0d49a
--- /dev/null
+++ b/src/java/org/apache/fop/afp/ioca/IDEStructureParameter.java
@@ -0,0 +1,151 @@
+/*
+ * 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.ioca;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.fop.afp.Streamable;
+
+/**
+ * This class represents the IOCA IDE Structure parameter (X'9B').
+ */
+public class IDEStructureParameter implements Streamable {
+
+ /** The RGB color model used by the IDE Structure parameter */
+ public static final byte COLOR_MODEL_RGB = (byte)0x01;
+ /** The YCrCb color model used by the IDE Structure parameter */
+ public static final byte COLOR_MODEL_YCRCB = (byte)0x02;
+ /** The CMYK color model used by the IDE Structure parameter */
+ public static final byte COLOR_MODEL_CMYK = (byte)0x04;
+ /** The YCbCr color model used by the IDE Structure parameter */
+ public static final byte COLOR_MODEL_YCBCR = (byte)0x12;
+
+ /** additive/subtractive setting for ASFLAG */
+ private boolean subtractive = false;
+
+ /** setting for GRAYCODE flag */
+ private boolean grayCoding = false;
+
+ /** the image color model */
+ private byte colorModel = COLOR_MODEL_RGB;
+
+ /** the array with the number of bits/IDE for each component */
+ private byte[] bitsPerIDE = new byte[] {(byte)1}; //1-bit by default
+
+ /**
+ * Creates a new IDE Structure parameter. The values are initialized for a bi-level image
+ * using the RGB color model.
+ */
+ public IDEStructureParameter() {
+ //nop
+ }
+
+ /**
+ * Sets the image IDE color model.
+ *
+ * @param color the IDE color model.
+ */
+ public void setColorModel(byte color) {
+ this.colorModel = color;
+ }
+
+ /**
+ * Establishes the parameter values for the normal RGB 24bit color model.
+ */
+ public void setDefaultRGBColorModel() {
+ this.colorModel = COLOR_MODEL_RGB;
+ setUniformBitsPerComponent(3, 8);
+ }
+
+ /**
+ * Establishes the parameter values for the normal CMYK 32bit color model.
+ */
+ public void setDefaultCMYKColorModel() {
+ this.colorModel = COLOR_MODEL_CMYK;
+ setUniformBitsPerComponent(4, 8);
+ }
+
+ /**
+ * Sets
+ * @param numComponents
+ * @param bitsPerComponent
+ */
+ public void setUniformBitsPerComponent(int numComponents, int bitsPerComponent) {
+ if (bitsPerComponent < 0 || bitsPerComponent >= 256) {
+ throw new IllegalArgumentException(
+ "The number of bits per component must be between 0 and 255");
+ }
+ this.bitsPerIDE = new byte[numComponents];
+ for (int i = 0; i < numComponents; i++) {
+ this.bitsPerIDE[i] = (byte)bitsPerComponent;
+ }
+ }
+
+ /**
+ * Sets the array for the bits/IDE, one entry per component.
+ * @param bitsPerComponent the
+ */
+ public void setBitsPerComponent(int[] bitsPerComponent) {
+ int numComponents = bitsPerComponent.length;
+ this.bitsPerIDE = new byte[numComponents];
+ for (int i = 0; i < numComponents; i++) {
+ int bits = bitsPerComponent[i];
+ if (bits < 0 || bits >= 256) {
+ throw new IllegalArgumentException(
+ "The number of bits per component must be between 0 and 255");
+ }
+ this.bitsPerIDE[i] = (byte)bits;
+ }
+ }
+
+ /**
+ * Set either additive or subtractive mode (used for ASFLAG).
+ * @param subtractive true for subtractive mode, false for additive mode
+ */
+ public void setSubtractive(boolean subtractive) {
+ this.subtractive = subtractive;
+ }
+
+ /** {@inheritDoc} */
+ public void writeToStream(OutputStream os) throws IOException {
+ int length = 7 + bitsPerIDE.length;
+
+ byte flags = 0x00;
+ if (subtractive) {
+ flags |= 1 << 7;
+ }
+ if (grayCoding) {
+ flags |= 1 << 6;
+ }
+
+ DataOutputStream dout = new DataOutputStream(os);
+ dout.writeByte(0x9B); //ID
+ dout.writeByte(length - 2); //LENGTH
+ dout.writeByte(flags); //FLAGS
+ dout.writeByte(this.colorModel); //FORMAT
+ for (int i = 0; i < 3; i++) {
+ dout.writeByte(0); //RESERVED
+ }
+ dout.write(this.bitsPerIDE); //component sizes
+ }
+
+}
diff --git a/src/java/org/apache/fop/afp/ioca/ImageContent.java b/src/java/org/apache/fop/afp/ioca/ImageContent.java
index fe902b381..9c06589e0 100644
--- a/src/java/org/apache/fop/afp/ioca/ImageContent.java
+++ b/src/java/org/apache/fop/afp/ioca/ImageContent.java
@@ -56,21 +56,18 @@ public class ImageContent extends AbstractStructuredObject {
/** the image size parameter */
private ImageSizeParameter imageSizeParameter = null;
+ /** the IDE Structure parameter */
+ private IDEStructureParameter ideStructureParameter = null;
+
/** the image encoding */
private byte encoding = (byte)0x03;
- /** the image ide size */
- private byte size = 1;
+ /** the image IDE (Image Data Element, Sample) size */
+ private byte ideSize = 1;
/** the image compression */
private byte compression = (byte)0xC0;
- /** the image color model */
- private byte colorModel = (byte)0x01;
-
- /** additive/subtractive setting for ASFLAG */
- private boolean subtractive = false;
-
/** the image data */
private byte[] data;
@@ -90,6 +87,34 @@ public class ImageContent extends AbstractStructuredObject {
}
/**
+ * Sets the IDE Structure parameter.
+ * @param parameter the IDE Structure parameter
+ */
+ public void setIDEStructureParameter(IDEStructureParameter parameter) {
+ this.ideStructureParameter = parameter;
+ }
+
+ /**
+ * Returns the (optional) IDE Structure parameter
+ * @return the IDE Structure parameter or null if none is set
+ */
+ public IDEStructureParameter getIDEStructureParameter() {
+ return this.ideStructureParameter;
+ }
+
+ /**
+ * Returns the (optional) IDE Structure parameter. If none is set an instance is prepared
+ * with defaults for a bi-level image.
+ * @return the IDE Structure parameter
+ */
+ public IDEStructureParameter needIDEStructureParameter() {
+ if (this.ideStructureParameter == null) {
+ setIDEStructureParameter(new IDEStructureParameter());
+ }
+ return getIDEStructureParameter();
+ }
+
+ /**
* Sets the image encoding.
*
* @param enc The image encoding.
@@ -113,24 +138,26 @@ public class ImageContent extends AbstractStructuredObject {
* @param s The IDE size.
*/
public void setImageIDESize(byte s) {
- this.size = s;
+ this.ideSize = s;
}
/**
* Sets the image IDE color model.
*
* @param color the IDE color model.
+ * @deprecated use {@link #setIDEStructureParameter(IDEStructureParameter)} instead
*/
public void setImageIDEColorModel(byte color) {
- this.colorModel = color;
+ needIDEStructureParameter().setColorModel(color);
}
/**
* Set either additive or subtractive mode (used for ASFLAG).
* @param subtractive true for subtractive mode, false for additive mode
+ * @deprecated use {@link #setIDEStructureParameter(IDEStructureParameter)} instead
*/
public void setSubtractive(boolean subtractive) {
- this.subtractive = subtractive;
+ needIDEStructureParameter().setSubtractive(subtractive);
}
/**
@@ -155,10 +182,12 @@ public class ImageContent extends AbstractStructuredObject {
os.write(getImageIDESizeParameter());
- boolean useFS10 = (this.size == 1);
- if (!useFS10) {
- os.write(getIDEStructureParameter());
+ if (getIDEStructureParameter() != null) {
+ getIDEStructureParameter().writeToStream(os);
+ }
+ boolean useFS10 = (this.ideSize == 1);
+ if (!useFS10) {
os.write(getExternalAlgorithmParameter());
}
@@ -243,58 +272,15 @@ public class ImageContent extends AbstractStructuredObject {
* @return byte[] The data stream.
*/
private byte[] getImageIDESizeParameter() {
- if (size != 1) {
+ if (ideSize != 1) {
final byte[] ideSizeData = new byte[] {
(byte)0x96, // ID
0x01, // Length
- size};
+ ideSize};
return ideSizeData;
} else {
return new byte[0];
}
}
- /**
- * Helper method to return the external algorithm parameter.
- *
- * @return byte[] The data stream.
- */
- private byte[] getIDEStructureParameter() {
- byte flags = 0x00;
- if (subtractive) {
- flags |= 1 << 7;
- }
- if (colorModel != 0 && size == 24) {
- final byte bits = (byte)(size / 3);
- final byte[] ideStructData = new byte[] {
- (byte)0x9B, // ID
- 0x00, // Length
- flags, // FLAGS
- colorModel, // COLOR MODEL
- 0x00, // Reserved
- 0x00, // Reserved
- 0x00, // Reserved
- bits,
- bits,
- bits,
- };
- ideStructData[1] = (byte)(ideStructData.length - 2);
- return ideStructData;
- } else if (size == 1) {
- final byte[] ideStructData = new byte[] {
- (byte)0x9B, // ID
- 0x00, // Length
- flags, // FLAGS
- colorModel, // COLOR MODEL
- 0x00, // Reserved
- 0x00, // Reserved
- 0x00, // Reserved
- 0x01
- };
- ideStructData[1] = (byte)(ideStructData.length - 2);
- return ideStructData;
- }
- return new byte[0];
- }
-
}
diff --git a/src/java/org/apache/fop/afp/ioca/ImageSegment.java b/src/java/org/apache/fop/afp/ioca/ImageSegment.java
index d8ba38ec0..9965bb94a 100644
--- a/src/java/org/apache/fop/afp/ioca/ImageSegment.java
+++ b/src/java/org/apache/fop/afp/ioca/ImageSegment.java
@@ -56,7 +56,11 @@ public class ImageSegment extends AbstractNamedAFPObject {
this.factory = factory;
}
- private ImageContent getImageContent() {
+ /**
+ * Returns the image content object associated with this image segment.
+ * @return the image content
+ */
+ public ImageContent getImageContent() {
if (imageContent == null) {
this.imageContent = factory.createImageContent();
}
@@ -108,6 +112,7 @@ public class ImageSegment extends AbstractNamedAFPObject {
* Sets the image IDE color model.
*
* @param colorModel the IDE color model.
+ * @deprecated Use {@link IDEStructureParameter#setColorModel(byte)} instead.
*/
public void setIDEColorModel(byte colorModel) {
getImageContent().setImageIDEColorModel(colorModel);
@@ -116,6 +121,7 @@ public class ImageSegment extends AbstractNamedAFPObject {
/**
* Set either additive or subtractive mode (used for ASFLAG).
* @param subtractive true for subtractive mode, false for additive mode
+ * @deprecated Use {@link IDEStructureParameter#setSubtractive(boolean)} instead.
*/
public void setSubtractive(boolean subtractive) {
getImageContent().setSubtractive(subtractive);
@@ -124,7 +130,7 @@ public class ImageSegment extends AbstractNamedAFPObject {
/**
* Set the data image data.
*
- * @param data the image data
+ * @param imageData the image data
*/
public void setData(byte[] imageData) {
getImageContent().setImageData(imageData);
diff --git a/src/java/org/apache/fop/afp/modca/AbstractAFPObject.java b/src/java/org/apache/fop/afp/modca/AbstractAFPObject.java
index ae1c83377..45239a6cf 100644
--- a/src/java/org/apache/fop/afp/modca/AbstractAFPObject.java
+++ b/src/java/org/apache/fop/afp/modca/AbstractAFPObject.java
@@ -43,7 +43,7 @@ public abstract class AbstractAFPObject implements Streamable {
/** the structured field class id */
protected static final byte SF_CLASS = (byte)0xD3;
- private static final byte[] SF_HEADER = new byte[] {
+ protected static final byte[] SF_HEADER = new byte[] {
0x5A, // Structured field identifier
0x00, // Length byte 1
0x10, // Length byte 2
@@ -177,6 +177,21 @@ public abstract class AbstractAFPObject implements Streamable {
}
}
+ /**
+ * Truncates the string as necessary
+ *
+ * @param str a character string
+ * @param maxLength the maximum length allowed for the string
+ * @return a possibly truncated string
+ */
+ protected String truncate(String str, int maxLength) {
+ if (str.length() > maxLength) {
+ str = str.substring(0, maxLength);
+ log.warn("truncated character string '" + str + "', longer than " + maxLength + " chars");
+ }
+ return str;
+ }
+
/** structured field type codes */
public interface Type {
diff --git a/src/java/org/apache/fop/afp/modca/AbstractTripletStructuredObject.java b/src/java/org/apache/fop/afp/modca/AbstractTripletStructuredObject.java
index a14af2967..efc38f3b8 100644
--- a/src/java/org/apache/fop/afp/modca/AbstractTripletStructuredObject.java
+++ b/src/java/org/apache/fop/afp/modca/AbstractTripletStructuredObject.java
@@ -27,9 +27,12 @@ import java.util.List;
import org.apache.fop.afp.modca.Registry.ObjectType;
import org.apache.fop.afp.modca.triplets.AbstractTriplet;
+import org.apache.fop.afp.modca.triplets.AttributeQualifierTriplet;
+import org.apache.fop.afp.modca.triplets.AttributeValueTriplet;
import org.apache.fop.afp.modca.triplets.CommentTriplet;
import org.apache.fop.afp.modca.triplets.FullyQualifiedNameTriplet;
import org.apache.fop.afp.modca.triplets.ObjectClassificationTriplet;
+import org.apache.fop.afp.modca.triplets.Triplet;
/**
* A MODCA structured object base class providing support for Triplets
@@ -37,7 +40,7 @@ import org.apache.fop.afp.modca.triplets.ObjectClassificationTriplet;
public class AbstractTripletStructuredObject extends AbstractStructuredObject {
/** list of object triplets */
- protected List/*<AbstractTriplet>*/ triplets = new java.util.ArrayList/*<AbstractTriplet>*/();
+ protected List/*<Triplet>*/ triplets = new java.util.ArrayList/*<Triplet>*/();
/**
* Returns the triplet data length
@@ -109,7 +112,7 @@ public class AbstractTripletStructuredObject extends AbstractStructuredObject {
*
* @param triplet the triplet to add
*/
- protected void addTriplet(AbstractTriplet triplet) {
+ protected void addTriplet(Triplet triplet) {
triplets.add(triplet);
}
@@ -130,7 +133,7 @@ public class AbstractTripletStructuredObject extends AbstractStructuredObject {
}
/**
- * Sets the fully qualified name of this resource
+ * Sets the fully qualified name of this structured field
*
* @param fqnType the fully qualified name type of this resource
* @param fqnFormat the fully qualified name format of this resource
diff --git a/src/java/org/apache/fop/afp/modca/ContainerDataDescriptor.java b/src/java/org/apache/fop/afp/modca/ContainerDataDescriptor.java
index 0f99d6624..38c60d7b6 100644
--- a/src/java/org/apache/fop/afp/modca/ContainerDataDescriptor.java
+++ b/src/java/org/apache/fop/afp/modca/ContainerDataDescriptor.java
@@ -79,6 +79,8 @@ public class ContainerDataDescriptor extends AbstractDescriptor {
data[18] = ysize[0];
data[19] = ysize[1];
data[20] = ysize[2];
+
+ os.write(data);
}
}
diff --git a/src/java/org/apache/fop/afp/modca/ImageDataDescriptor.java b/src/java/org/apache/fop/afp/modca/ImageDataDescriptor.java
index 0a7b665d7..386d2f40f 100644
--- a/src/java/org/apache/fop/afp/modca/ImageDataDescriptor.java
+++ b/src/java/org/apache/fop/afp/modca/ImageDataDescriptor.java
@@ -31,6 +31,7 @@ public class ImageDataDescriptor extends AbstractDescriptor {
public static final byte FUNCTION_SET_FS10 = 0x0A;
public static final byte FUNCTION_SET_FS11 = 0x0B;
+ public static final byte FUNCTION_SET_FS45 = 45;
private byte functionSet = FUNCTION_SET_FS11; // FCNSET = IOCA FS 11
diff --git a/src/java/org/apache/fop/afp/modca/ImageObject.java b/src/java/org/apache/fop/afp/modca/ImageObject.java
index 65802f6ca..2f075ce33 100644
--- a/src/java/org/apache/fop/afp/modca/ImageObject.java
+++ b/src/java/org/apache/fop/afp/modca/ImageObject.java
@@ -24,9 +24,12 @@ import java.io.OutputStream;
import org.apache.commons.io.output.ByteArrayOutputStream;
+import org.apache.xmlgraphics.util.MimeConstants;
+
import org.apache.fop.afp.AFPDataObjectInfo;
import org.apache.fop.afp.AFPImageObjectInfo;
import org.apache.fop.afp.Factory;
+import org.apache.fop.afp.ioca.IDEStructureParameter;
import org.apache.fop.afp.ioca.ImageSegment;
/**
@@ -50,7 +53,11 @@ public class ImageObject extends AbstractDataObject {
super(factory, name);
}
- private ImageSegment getImageSegment() {
+ /**
+ * Returns the image segment object associated with this image object.
+ * @return the image segment
+ */
+ public ImageSegment getImageSegment() {
if (imageSegment == null) {
this.imageSegment = factory.createImageSegment();
}
@@ -71,6 +78,8 @@ public class ImageObject extends AbstractDataObject {
= factory.createImageDataDescriptor(dataWidth, dataHeight, dataWidthRes, dataHeightRes);
if (imageObjectInfo.getBitsPerPixel() == 1) {
imageDataDescriptor.setFunctionSet(ImageDataDescriptor.FUNCTION_SET_FS10);
+ } else if (MimeConstants.MIME_AFP_IOCA_FS45.equals(imageObjectInfo.getMimeType())) {
+ imageDataDescriptor.setFunctionSet(ImageDataDescriptor.FUNCTION_SET_FS45);
}
getObjectEnvironmentGroup().setDataDescriptor(imageDataDescriptor);
getObjectEnvironmentGroup().setMapImageObject(
@@ -110,6 +119,7 @@ public class ImageObject extends AbstractDataObject {
* Sets the image IDE color model.
*
* @param colorModel the IDE color model.
+ * @deprecated Use {@link IDEStructureParameter#setColorModel(byte)} instead.
*/
public void setIDEColorModel(byte colorModel) {
getImageSegment().setIDEColorModel(colorModel);
@@ -118,6 +128,7 @@ public class ImageObject extends AbstractDataObject {
/**
* Set either additive or subtractive mode (used for ASFLAG).
* @param subtractive true for subtractive mode, false for additive mode
+ * @deprecated Use {@link IDEStructureParameter#setSubtractive(boolean)} instead.
*/
public void setSubtractive(boolean subtractive) {
getImageSegment().setSubtractive(subtractive);
diff --git a/src/java/org/apache/fop/afp/modca/TagLogicalElement.java b/src/java/org/apache/fop/afp/modca/TagLogicalElement.java
index 5c1f7bbbb..cb7a67d28 100644
--- a/src/java/org/apache/fop/afp/modca/TagLogicalElement.java
+++ b/src/java/org/apache/fop/afp/modca/TagLogicalElement.java
@@ -21,9 +21,10 @@ package org.apache.fop.afp.modca;
import java.io.IOException;
import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import org.apache.fop.afp.AFPConstants;
+import org.apache.fop.afp.modca.triplets.AttributeQualifierTriplet;
+import org.apache.fop.afp.modca.triplets.AttributeValueTriplet;
+import org.apache.fop.afp.modca.triplets.FullyQualifiedNameTriplet;
import org.apache.fop.afp.util.BinaryUtils;
/**
@@ -45,7 +46,7 @@ import org.apache.fop.afp.util.BinaryUtils;
* effect on the appearance of a document when it is presented.
* <p/>
*/
-public class TagLogicalElement extends AbstractAFPObject {
+public class TagLogicalElement extends AbstractTripletStructuredObject {
/**
* Name of the key, used within the TLE
@@ -75,77 +76,43 @@ public class TagLogicalElement extends AbstractAFPObject {
this.tleID = tleID;
}
- /** {@inheritDoc} */
- public void writeToStream(OutputStream os) throws IOException {
-
- // convert name and value to ebcdic
- byte[] tleByteName = null;
- byte[] tleByteValue = null;
- try {
- tleByteName = name.getBytes(AFPConstants.EBCIDIC_ENCODING);
- tleByteValue = value.getBytes(AFPConstants.EBCIDIC_ENCODING);
- } catch (UnsupportedEncodingException usee) {
- tleByteName = name.getBytes();
- tleByteValue = value.getBytes();
- log.warn(
- "Constructor:: UnsupportedEncodingException translating the name "
- + name);
- }
-
- byte[] data = new byte[27 + tleByteName.length + tleByteValue.length];
-
- data[0] = 0x5A;
- // Set the total record length
- byte[] rl1
- = BinaryUtils.convert(26 + tleByteName.length + tleByteValue.length, 2);
- //Ignore first byte
- data[1] = rl1[0];
- data[2] = rl1[1];
-
- // Structured field ID for a TLE
- data[3] = (byte) 0xD3;
- data[4] = (byte) Type.ATTRIBUTE;
- data[5] = (byte) Category.PROCESS_ELEMENT;
-
- data[6] = 0x00; // Reserved
- data[7] = 0x00; // Reserved
- data[8] = 0x00; // Reserved
-
- //Use 2 triplets, attribute name and value (the key for indexing)
-
- byte[] rl2 = BinaryUtils.convert(tleByteName.length + 4, 1);
- data[9] = rl2[0]; // length of the triplet, including this field
- data[10] = 0x02; //Identifies it as a FQN triplet
- data[11] = 0x0B; // GID format
- data[12] = 0x00;
-
- // write out TLE name
- int pos = 13;
- for (int i = 0; i < tleByteName.length; i++) {
- data[pos++] = tleByteName[i];
- }
-
- byte[] rl3 = BinaryUtils.convert(tleByteValue.length + 4, 1);
- data[pos++] = rl3[0]; // length of the triplet, including this field
- data[pos++] = 0x36; //Identifies the triplet, attribute value
- data[pos++] = 0x00; // Reserved
- data[pos++] = 0x00; // Reserved
+ /**
+ * Sets the attribute value of this structured field
+ *
+ * @param value the attribute value
+ */
+ public void setAttributeValue(String value) {
+ addTriplet(new AttributeValueTriplet(value));
+ }
- for (int i = 0; i < tleByteValue.length; i++) {
- data[pos++] = tleByteValue[i];
- }
- // attribute qualifier
- data[pos++] = 0x0A;
- data[pos++] = (byte)0x80;
- byte[] id = BinaryUtils.convert(tleID, 4);
- for (int i = 0; i < id.length; i++) {
- data[pos++] = id[i];
- }
- byte[] level = BinaryUtils.convert(1, 4);
- for (int i = 0; i < level.length; i++) {
- data[pos++] = level[i];
- }
+ /**
+ * Sets the attribute qualifier of this structured field
+ *
+ * @param seqNumber the attribute sequence number
+ * @param levNumber the attribute level number
+ */
+ public void setAttributeQualifier(int seqNumber, int levNumber) {
+ addTriplet(new AttributeQualifierTriplet(seqNumber, levNumber));
+ }
+ /** {@inheritDoc} */
+ public void writeToStream(OutputStream os) throws IOException {
+ setFullyQualifiedName(
+ FullyQualifiedNameTriplet.TYPE_ATTRIBUTE_GID,
+ FullyQualifiedNameTriplet.FORMAT_CHARSTR,
+ name);
+ setAttributeQualifier(tleID, 1);
+ setAttributeValue(value);
+
+ byte[] data = new byte[SF_HEADER.length];
+ copySF(data, Type.ATTRIBUTE, Category.PROCESS_ELEMENT);
+
+ int tripletDataLength = getTripletDataLength();
+ byte[] l = BinaryUtils.convert(data.length + tripletDataLength - 1, 2);
+ data[1] = l[0];
+ data[2] = l[1];
os.write(data);
+
+ writeTriplets(os);
}
}
diff --git a/src/java/org/apache/fop/afp/modca/triplets/AbstractTriplet.java b/src/java/org/apache/fop/afp/modca/triplets/AbstractTriplet.java
index 598df1b98..5cd136ab2 100644
--- a/src/java/org/apache/fop/afp/modca/triplets/AbstractTriplet.java
+++ b/src/java/org/apache/fop/afp/modca/triplets/AbstractTriplet.java
@@ -19,70 +19,12 @@
package org.apache.fop.afp.modca.triplets;
-import org.apache.fop.afp.Streamable;
-import org.apache.fop.afp.StructuredData;
+import org.apache.fop.afp.modca.AbstractAFPObject;
/**
* A simple implementation of a MOD:CA triplet
*/
-public abstract class AbstractTriplet implements Streamable, StructuredData {
- public static final byte CODED_GRAPHIC_CHARACTER_SET_GLOBAL_IDENTIFIER = 0x01;
-
- /** Triplet identifiers */
- public static final byte FULLY_QUALIFIED_NAME = 0x02;
- public static final byte MAPPING_OPTION = 0x04;
- public static final byte OBJECT_CLASSIFICATION = 0x10;
- public static final byte MODCA_INTERCHANGE_SET = 0x18;
- public static final byte FONT_DESCRIPTOR_SPECIFICATION = 0x1F;
- public static final byte OBJECT_FUNCTION_SET_SPECIFICATION = 0x21;
- public static final byte EXTENDED_RESOURCE_LOCAL_IDENTIFIER = 0x22;
- public static final byte RESOURCE_LOCAL_IDENTIFIER = 0x24;
- public static final byte RESOURCE_SECTION_NUMBER = 0x25;
- public static final byte CHARACTER_ROTATION = 0x26;
- public static final byte OBJECT_BYTE_OFFSET = 0x2D;
- public static final byte ATTRIBUTE_VALUE = 0x36;
- public static final byte DESCRIPTOR_POSITION = 0x43;
- public static final byte MEDIA_EJECT_CONTROL = 0x45;
- public static final byte PAGE_OVERLAY_CONDITIONAL_PROCESSING = 0x46;
- public static final byte RESOURCE_USAGE_ATTRIBUTE = 0x47;
- public static final byte MEASUREMENT_UNITS = 0x4B;
- public static final byte OBJECT_AREA_SIZE = 0x4C;
- public static final byte AREA_DEFINITION = 0x4D;
- public static final byte COLOR_SPECIFICATION = 0x4E;
- public static final byte ENCODING_SCHEME_ID = 0x50;
- public static final byte MEDIUM_MAP_PAGE_NUMBER = 0x56;
- public static final byte OBJECT_BYTE_EXTENT = 0x57;
- public static final byte OBJECT_STRUCTURED_FIELD_OFFSET = 0x58;
- public static final byte OBJECT_STRUCTURED_FIELD_EXTENT = 0x59;
- public static final byte OBJECT_OFFSET = 0x5A;
- public static final byte FONT_HORIZONTAL_SCALE_FACTOR = 0x5D;
- public static final byte OBJECT_COUNT = 0x5E;
- public static final byte OBJECT_DATE_AND_TIMESTAMP = 0x62;
- public static final byte COMMENT = 0x65;
- public static final byte MEDIUM_ORIENTATION = 0x68;
- public static final byte RESOURCE_OBJECT_INCLUDE = 0x6C;
- public static final byte PRESENTATION_SPACE_RESET_MIXING = 0x70;
- public static final byte PRESENTATION_SPACE_MIXING_RULE = 0x71;
- public static final byte UNIVERSAL_DATE_AND_TIMESTAMP = 0x72;
- public static final byte TONER_SAVER = 0x74;
- public static final byte COLOR_FIDELITY = 0x75;
- public static final byte FONT_FIDELITY = 0x78;
- public static final byte ATTRIBUTE_QUALIFIER = (byte)0x80;
- public static final byte PAGE_POSITION_INFORMATION = (byte)0x81;
- public static final byte PARAMETER_VALUE = (byte)0x82;
- public static final byte PRESENTATION_CONTROL = (byte)0x83;
- public static final byte FONT_RESOLUTION_AND_METRIC_TECHNOLOGY = (byte)0x84;
- public static final byte FINISHING_OPERATION = (byte)0x85;
- public static final byte TEXT_FIDELITY = (byte)0x86;
- public static final byte MEDIA_FIDELITY = (byte)0x87;
- public static final byte FINISHING_FIDELITY = (byte)0x88;
- public static final byte DATA_OBJECT_FONT_DESCRIPTOR = (byte)0x8B;
- public static final byte LOCALE_SELECTOR = (byte)0x8C;
- public static final byte UP3I_FINISHING_OPERATION = (byte)0x8E;
- public static final byte COLOR_MANAGEMENT_RESOURCE_DESCRIPTOR = (byte)0x91;
- public static final byte RENDERING_INTENT = (byte)0x95;
- public static final byte CMR_TAG_FIDELITY = (byte)0x96;
- public static final byte DEVICE_APPEARANCE = (byte)0x97;
+public abstract class AbstractTriplet extends AbstractAFPObject implements Triplet {
/** the triplet identifier */
protected final byte id;
diff --git a/src/java/org/apache/fop/afp/modca/triplets/AttributeQualifierTriplet.java b/src/java/org/apache/fop/afp/modca/triplets/AttributeQualifierTriplet.java
new file mode 100644
index 000000000..2f924d585
--- /dev/null
+++ b/src/java/org/apache/fop/afp/modca/triplets/AttributeQualifierTriplet.java
@@ -0,0 +1,67 @@
+/*
+ * 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.modca.triplets;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.fop.afp.util.BinaryUtils;
+
+/**
+ * The attribute qualifier triplet is used to specify a qualifier for a document
+ * attribute.
+ */
+public class AttributeQualifierTriplet extends AbstractTriplet {
+
+ private int seqNumber;
+ private int levNumber;
+
+ /**
+ * Main constructor
+ *
+ * @param seqNumber the attribute qualifier sequence number
+ * @param levNumber the attribute qualifier level number
+ */
+ public AttributeQualifierTriplet(int seqNumber, int levNumber) {
+ super(ATTRIBUTE_QUALIFIER);
+ this.seqNumber = seqNumber;
+ this.levNumber = levNumber;
+ }
+
+ /** {@inheritDoc} */
+ public void writeToStream(OutputStream os) throws IOException {
+ byte[] data = getData();
+ byte[] id = BinaryUtils.convert(seqNumber, 4);
+ System.arraycopy(id, 0, data, 2, id.length);
+ byte[] level = BinaryUtils.convert(levNumber, 4);
+ System.arraycopy(level, 0, data, 6, level.length);
+ os.write(data);
+ }
+
+ /** {@inheritDoc} */
+ public int getDataLength() {
+ return 10;
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return "seqNumber=" + seqNumber + ", levNumber=" + levNumber;
+ }
+}
diff --git a/src/java/org/apache/fop/afp/modca/triplets/AttributeValueTriplet.java b/src/java/org/apache/fop/afp/modca/triplets/AttributeValueTriplet.java
new file mode 100644
index 000000000..ec2ae8d7c
--- /dev/null
+++ b/src/java/org/apache/fop/afp/modca/triplets/AttributeValueTriplet.java
@@ -0,0 +1,72 @@
+/*
+ * 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.modca.triplets;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+
+import org.apache.fop.afp.AFPConstants;
+
+/**
+ * The attribute value triplet is used to specify a value for a document
+ * attribute.
+ */
+public class AttributeValueTriplet extends AbstractTriplet {
+ private String attVal;
+
+ /**
+ * Main constructor
+ *
+ * @param attVal an attribute value
+ */
+ public AttributeValueTriplet(String attVal) {
+ super(ATTRIBUTE_VALUE);
+ this.attVal = truncate(attVal, MAX_LENGTH - 4);
+ }
+
+ /** {@inheritDoc} */
+ public void writeToStream(OutputStream os) throws IOException {
+ byte[] data = super.getData();
+ data[2] = 0x00; // Reserved
+ data[3] = 0x00; // Reserved
+
+ // convert name and value to ebcdic
+ byte[] tleByteValue = null;
+ try {
+ tleByteValue = attVal.getBytes(AFPConstants.EBCIDIC_ENCODING);
+ } catch (UnsupportedEncodingException usee) {
+ tleByteValue = attVal.getBytes();
+ throw new IllegalArgumentException(attVal + " encoding failed");
+ }
+ System.arraycopy(tleByteValue, 0, data, 4, tleByteValue.length);
+ os.write(data);
+ }
+
+ /** {@inheritDoc} */
+ public int getDataLength() {
+ return 4 + attVal.length();
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return attVal;
+ }
+}
diff --git a/src/java/org/apache/fop/afp/modca/triplets/Triplet.java b/src/java/org/apache/fop/afp/modca/triplets/Triplet.java
new file mode 100644
index 000000000..726727e3e
--- /dev/null
+++ b/src/java/org/apache/fop/afp/modca/triplets/Triplet.java
@@ -0,0 +1,85 @@
+/*
+ * 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.modca.triplets;
+
+import org.apache.fop.afp.Streamable;
+import org.apache.fop.afp.StructuredData;
+
+public interface Triplet extends Streamable, StructuredData {
+ int MAX_LENGTH = 254;
+
+ byte CODED_GRAPHIC_CHARACTER_SET_GLOBAL_IDENTIFIER = 0x01;
+
+ /** Triplet identifiers */
+ byte FULLY_QUALIFIED_NAME = 0x02;
+ byte MAPPING_OPTION = 0x04;
+ byte OBJECT_CLASSIFICATION = 0x10;
+ byte MODCA_INTERCHANGE_SET = 0x18;
+ byte FONT_DESCRIPTOR_SPECIFICATION = 0x1F;
+ byte OBJECT_FUNCTION_SET_SPECIFICATION = 0x21;
+ byte EXTENDED_RESOURCE_LOCAL_IDENTIFIER = 0x22;
+ byte RESOURCE_LOCAL_IDENTIFIER = 0x24;
+ byte RESOURCE_SECTION_NUMBER = 0x25;
+ byte CHARACTER_ROTATION = 0x26;
+ byte OBJECT_BYTE_OFFSET = 0x2D;
+ byte ATTRIBUTE_VALUE = 0x36;
+ byte DESCRIPTOR_POSITION = 0x43;
+ byte MEDIA_EJECT_CONTROL = 0x45;
+ byte PAGE_OVERLAY_CONDITIONAL_PROCESSING = 0x46;
+ byte RESOURCE_USAGE_ATTRIBUTE = 0x47;
+ byte MEASUREMENT_UNITS = 0x4B;
+ byte OBJECT_AREA_SIZE = 0x4C;
+ byte AREA_DEFINITION = 0x4D;
+ byte COLOR_SPECIFICATION = 0x4E;
+ byte ENCODING_SCHEME_ID = 0x50;
+ byte MEDIUM_MAP_PAGE_NUMBER = 0x56;
+ byte OBJECT_BYTE_EXTENT = 0x57;
+ byte OBJECT_STRUCTURED_FIELD_OFFSET = 0x58;
+ byte OBJECT_STRUCTURED_FIELD_EXTENT = 0x59;
+ byte OBJECT_OFFSET = 0x5A;
+ byte FONT_HORIZONTAL_SCALE_FACTOR = 0x5D;
+ byte OBJECT_COUNT = 0x5E;
+ byte OBJECT_DATE_AND_TIMESTAMP = 0x62;
+ byte COMMENT = 0x65;
+ byte MEDIUM_ORIENTATION = 0x68;
+ byte RESOURCE_OBJECT_INCLUDE = 0x6C;
+ byte PRESENTATION_SPACE_RESET_MIXING = 0x70;
+ byte PRESENTATION_SPACE_MIXING_RULE = 0x71;
+ byte UNIVERSAL_DATE_AND_TIMESTAMP = 0x72;
+ byte TONER_SAVER = 0x74;
+ byte COLOR_FIDELITY = 0x75;
+ byte FONT_FIDELITY = 0x78;
+ byte ATTRIBUTE_QUALIFIER = (byte)0x80;
+ byte PAGE_POSITION_INFORMATION = (byte)0x81;
+ byte PARAMETER_VALUE = (byte)0x82;
+ byte PRESENTATION_CONTROL = (byte)0x83;
+ byte FONT_RESOLUTION_AND_METRIC_TECHNOLOGY = (byte)0x84;
+ byte FINISHING_OPERATION = (byte)0x85;
+ byte TEXT_FIDELITY = (byte)0x86;
+ byte MEDIA_FIDELITY = (byte)0x87;
+ byte FINISHING_FIDELITY = (byte)0x88;
+ byte DATA_OBJECT_FONT_DESCRIPTOR = (byte)0x8B;
+ byte LOCALE_SELECTOR = (byte)0x8C;
+ byte UP3I_FINISHING_OPERATION = (byte)0x8E;
+ byte COLOR_MANAGEMENT_RESOURCE_DESCRIPTOR = (byte)0x91;
+ byte RENDERING_INTENT = (byte)0x95;
+ byte CMR_TAG_FIDELITY = (byte)0x96;
+ byte DEVICE_APPEARANCE = (byte)0x97;
+}
diff --git a/src/java/org/apache/fop/cli/CommandLineOptions.java b/src/java/org/apache/fop/cli/CommandLineOptions.java
index 043dfe3c8..2e6e204a8 100644
--- a/src/java/org/apache/fop/cli/CommandLineOptions.java
+++ b/src/java/org/apache/fop/cli/CommandLineOptions.java
@@ -109,6 +109,8 @@ public class CommandLineOptions {
private boolean useStdIn = false;
/* true if System.out (stdout) should be used for the output file */
private boolean useStdOut = false;
+ /* true if a catalog resolver should be used for entity and uri resolution */
+ private boolean useCatalogResolver = false;
/* rendering options (for the user agent) */
private Map renderingOptions = new java.util.HashMap();
/* target resolution (for the user agent) */
@@ -354,6 +356,8 @@ public class CommandLineOptions {
} else {
throw new FOPException("invalid param usage: use -param <name> <value>");
}
+ } else if (args[i].equals("-catalog")) {
+ useCatalogResolver = true;
} else if (args[i].equals("-o")) {
i = i + parsePDFOwnerPassword(args, i);
} else if (args[i].equals("-u")) {
@@ -1024,7 +1028,7 @@ public class CommandLineOptions {
case IF_INPUT:
return new IFInputHandler(iffile);
case XSLT_INPUT:
- return new InputHandler(xmlfile, xsltfile, xsltParams);
+ return new InputHandler(xmlfile, xsltfile, xsltParams, useCatalogResolver);
case IMAGE_INPUT:
return new ImageInputHandler(imagefile, xsltfile, xsltParams);
default:
@@ -1166,6 +1170,7 @@ public class CommandLineOptions {
+ " -xsl stylesheet xslt stylesheet \n \n"
+ " -param name value <value> to use for parameter <name> in xslt stylesheet\n"
+ " (repeat '-param name value' for each parameter)\n \n"
+ + " -catalog use catalog resolver for input XML and XSLT files\n"
+ " [OUTPUT] \n"
+ " outfile input will be rendered as PDF into outfile\n"
+ " (use '-' for outfile to pipe output to stdout)\n"
diff --git a/src/java/org/apache/fop/cli/InputHandler.java b/src/java/org/apache/fop/cli/InputHandler.java
index 4f49ea269..a1ff1715b 100644
--- a/src/java/org/apache/fop/cli/InputHandler.java
+++ b/src/java/org/apache/fop/cli/InputHandler.java
@@ -19,7 +19,6 @@
package org.apache.fop.cli;
-// Imported java.io classes
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
@@ -34,11 +33,13 @@ import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.URIResolver;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
+import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
@@ -51,27 +52,27 @@ import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.render.awt.viewer.Renderable;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
/**
* Class for handling files input from command line
* either with XML and XSLT files (and optionally xsl
- * parameters) or FO File input alone
+ * parameters) or FO File input alone.
*/
public class InputHandler implements ErrorListener, Renderable {
/** original source file */
- protected File sourcefile = null;
- private File stylesheet = null; // for XML/XSLT usage
- private Vector xsltParams = null; // for XML/XSLT usage
+ protected File sourcefile;
+ private File stylesheet; // for XML/XSLT usage
+ private Vector xsltParams; // for XML/XSLT usage
+ private EntityResolver entityResolver;
+ private URIResolver uriResolver;
/** the logger */
protected Log log = LogFactory.getLog(InputHandler.class);
/**
* Constructor for XML->XSLT->FO input
+ *
* @param xmlfile XML file
* @param xsltfile XSLT file
* @param params Vector of command-line parameters (name, value,
@@ -84,6 +85,23 @@ public class InputHandler implements ErrorListener, Renderable {
}
/**
+ * Constructor for XML->XSLT->FO input
+ *
+ * @param xmlfile XML file
+ * @param xsltfile XSLT file
+ * @param params Vector of command-line parameters (name, value,
+ * name, value, ...) for XSL stylesheet, null if none
+ * @param useCatalogResolver if true, use a catalog resolver
+ * for XML parsing and XSLT URI resolution
+ */
+ public InputHandler(File xmlfile, File xsltfile, Vector params, boolean useCatalogResolver) {
+ this(xmlfile, xsltfile, params);
+ if (useCatalogResolver) {
+ createCatalogResolver();
+ }
+ }
+
+ /**
* Constructor for FO input
* @param fofile the file to read the FO document.
*/
@@ -151,7 +169,7 @@ public class InputHandler implements ErrorListener, Renderable {
* @return the Source for the main input file
*/
protected Source createMainSource() {
- Source result;
+ Source source;
InputStream in;
String uri;
if (this.sourcefile != null) {
@@ -169,37 +187,91 @@ public class InputHandler implements ErrorListener, Renderable {
try {
InputSource is = new InputSource(in);
is.setSystemId(uri);
- SAXParserFactory spf = SAXParserFactory.newInstance();
- spf.setFeature("http://xml.org/sax/features/namespaces", true);
- spf.setFeature("http://apache.org/xml/features/xinclude", true);
- XMLReader xr = spf.newSAXParser().getXMLReader();
- result = new SAXSource(xr, is);
+ XMLReader xr = getXMLReader();
+ if (entityResolver != null) {
+ xr.setEntityResolver(entityResolver);
+ }
+ source = new SAXSource(xr, is);
} catch (SAXException e) {
if (this.sourcefile != null) {
- result = new StreamSource(this.sourcefile);
+ source = new StreamSource(this.sourcefile);
} else {
- result = new StreamSource(in, uri);
+ source = new StreamSource(in, uri);
}
} catch (ParserConfigurationException e) {
if (this.sourcefile != null) {
- result = new StreamSource(this.sourcefile);
+ source = new StreamSource(this.sourcefile);
} else {
- result = new StreamSource(in, uri);
+ source = new StreamSource(in, uri);
+ }
+ }
+ return source;
+ }
+
+ /**
+ * Creates a catalog resolver and uses it for XML parsing and XSLT URI resolution.
+ * Tries the Apache Commons Resolver, and if unsuccessful,
+ * tries the same built into Java 6.
+ */
+ private void createCatalogResolver() {
+ String[] classNames = new String[] {
+ "org.apache.xml.resolver.tools.CatalogResolver",
+ "com.sun.org.apache.xml.internal.resolver.tools.CatalogResolver"};
+ Class resolverClass = null;
+ for (int i = 0; i < classNames.length && resolverClass == null; ++i) {
+ try {
+ resolverClass = Class.forName(classNames[i]);
+ } catch (ClassNotFoundException e) {
+ // No worries
}
}
- return result;
+ if (resolverClass == null) {
+ log.error("Could not find catalog resolver in class path");
+ return;
+ }
+ try {
+ entityResolver = (EntityResolver) resolverClass.newInstance();
+ uriResolver = (URIResolver) resolverClass.newInstance();
+ } catch (InstantiationException e) {
+ log.error("Error creating the catalog resolver: " + e.getMessage());
+ } catch (IllegalAccessException e) {
+ log.error("Error creating the catalog resolver: " + e.getMessage());
+ }
}
/**
* Creates a Source for the selected stylesheet.
+ *
* @return the Source for the selected stylesheet or null if there's no stylesheet
*/
protected Source createXSLTSource() {
+ Source xslt = null;
if (this.stylesheet != null) {
- return new StreamSource(this.stylesheet);
- } else {
- return null;
+ if (entityResolver != null) {
+ try {
+ InputSource is = new InputSource(this.stylesheet.getPath());
+ XMLReader xr = getXMLReader();
+ xr.setEntityResolver(entityResolver);
+ xslt = new SAXSource(xr, is);
+ } catch (SAXException e) {
+ // return StreamSource
+ } catch (ParserConfigurationException e) {
+ // return StreamSource
+ }
+ }
+ if (xslt == null) {
+ xslt = new StreamSource(this.stylesheet);
+ }
}
+ return xslt;
+ }
+
+ private XMLReader getXMLReader() throws ParserConfigurationException, SAXException {
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ spf.setFeature("http://xml.org/sax/features/namespaces", true);
+ spf.setFeature("http://apache.org/xml/features/xinclude", true);
+ XMLReader xr = spf.newSAXParser().getXMLReader();
+ return xr;
}
/**
@@ -226,6 +298,9 @@ public class InputHandler implements ErrorListener, Renderable {
(String) xsltParams.elementAt(i + 1));
}
}
+ if (uriResolver != null) {
+ transformer.setURIResolver(uriResolver);
+ }
}
transformer.setErrorListener(this);
diff --git a/src/java/org/apache/fop/fo/FObj.java b/src/java/org/apache/fop/fo/FObj.java
index 2ebfaaf95..133d932bc 100644
--- a/src/java/org/apache/fop/fo/FObj.java
+++ b/src/java/org/apache/fop/fo/FObj.java
@@ -56,7 +56,7 @@ public abstract class FObj extends FONode implements Constants {
private List/*<ExtensionAttachment>*/ extensionAttachments = null;
/** The map of foreign attributes, null if none */
- private Map foreignAttributes = null;
+ private Map/*<QName,String>*/ foreignAttributes = null;
/** Used to indicate if this FO is either an Out Of Line FO (see rec)
* or a descendant of one. Used during FO validation.
@@ -591,7 +591,7 @@ public abstract class FObj extends FONode implements Constants {
throw new NullPointerException("Parameter attributeName must not be null");
}
if (foreignAttributes == null) {
- foreignAttributes = new java.util.HashMap();
+ foreignAttributes = new java.util.HashMap/*<QName,String>*/();
}
foreignAttributes.put(attributeName, value);
}
diff --git a/src/java/org/apache/fop/fonts/CIDSubset.java b/src/java/org/apache/fop/fonts/CIDSubset.java
index c2505488b..6be4007ea 100644
--- a/src/java/org/apache/fop/fonts/CIDSubset.java
+++ b/src/java/org/apache/fop/fonts/CIDSubset.java
@@ -161,12 +161,12 @@ public class CIDSubset {
}
/**
- * Returns a BitSet with bits set for each available glyph index.
+ * Returns a BitSet with bits set for each available glyph index in the subset.
* @return a BitSet indicating available glyph indices
*/
public BitSet getGlyphIndexBitSet() {
BitSet bitset = new BitSet();
- Iterator iter = usedGlyphs.keySet().iterator();
+ Iterator iter = usedGlyphsIndex.keySet().iterator();
while (iter.hasNext()) {
Integer cid = (Integer)iter.next();
bitset.set(cid.intValue());
diff --git a/src/java/org/apache/fop/fonts/Font.java b/src/java/org/apache/fop/fonts/Font.java
index e9740c00c..d0a87efbf 100644
--- a/src/java/org/apache/fop/fonts/Font.java
+++ b/src/java/org/apache/fop/fonts/Font.java
@@ -170,6 +170,9 @@ public class Font {
/**
* Returns the amount of kerning between two characters.
+ *
+ * The value returned measures in pt. So it is already adjusted for font size.
+ *
* @param ch1 first character
* @param ch2 second character
* @return the distance to adjust for kerning, 0 if there's no kerning
@@ -179,7 +182,7 @@ public class Font {
if (kernPair != null) {
Integer width = (Integer)kernPair.get(new Integer(ch2));
if (width != null) {
- return width.intValue();
+ return width.intValue() * getFontSize() / 1000;
}
}
return 0;
diff --git a/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java b/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
index 1a6f7cfb9..53a52597b 100644
--- a/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
+++ b/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
@@ -367,7 +367,7 @@ public abstract class AbstractBreaker {
alg.setConstantLineWidth(flowBPD);
int optimalPageCount = alg.findBreakingPoints(effectiveList, 1, true,
BreakingAlgorithm.ALL_BREAKS);
- if (alg.ipdChanged()) {
+ if (alg.getIPDdifference() != 0) {
KnuthNode optimalBreak = alg.getBestNodeBeforeIPDChange();
int positionIndex = optimalBreak.position;
KnuthElement elementAtBreak = alg.getElement(positionIndex);
@@ -381,14 +381,19 @@ public abstract class AbstractBreaker {
LayoutManager restartAtLM = null;
List firstElements = Collections.EMPTY_LIST;
if (containsNonRestartableLM(positionAtBreak)) {
+ if (alg.getIPDdifference() > 0) {
+ log.warn("Content that cannot handle IPD changes is flowing to a"
+ + " narrower page. Part of it may be clipped"
+ + " by the page border.");
+ }
firstElements = new LinkedList();
boolean boxFound = false;
- Iterator iter = effectiveList.listIterator(++positionIndex);
+ Iterator iter = effectiveList.listIterator(positionIndex + 1);
Position position = null;
while (iter.hasNext()
&& (position == null || containsNonRestartableLM(position))) {
- KnuthElement element = (KnuthElement) iter.next();
positionIndex++;
+ KnuthElement element = (KnuthElement) iter.next();
position = element.getPosition();
if (element.isBox()) {
boxFound = true;
@@ -400,9 +405,11 @@ public abstract class AbstractBreaker {
if (position instanceof SpaceResolver.SpaceHandlingBreakPosition) {
/* Retrieve the original position wrapped into this space position */
positionAtBreak = position.getPosition();
+ } else {
+ positionAtBreak = null;
}
}
- if (positionAtBreak.getIndex() == -1) {
+ if (positionAtBreak != null && positionAtBreak.getIndex() == -1) {
/*
* This is an indication that we are between two blocks
* (possibly surrounded by another block), not inside a
@@ -588,7 +595,7 @@ public abstract class AbstractBreaker {
.listIterator(startElementIndex);
while (effectiveListIterator.nextIndex() <= endElementIndex) {
KnuthElement tempEl = (KnuthElement)effectiveListIterator.next();
- if (tempEl.isBox() && tempEl.getW() > 0) {
+ if (tempEl.isBox() && tempEl.getWidth() > 0) {
boxCount++;
}
}
@@ -678,8 +685,23 @@ public abstract class AbstractBreaker {
BlockSequence blockList;
List returnedList;
- if (positionAtIPDChange == null) {
+ if (firstElements == null) {
returnedList = getNextKnuthElements(childLC, alignment);
+ } else if (positionAtIPDChange == null) {
+ /*
+ * No restartable element found after changing IPD break. Simply add the
+ * non-restartable elements found after the break.
+ */
+ returnedList = firstElements;
+ /*
+ * Remove the last 3 penalty-filler-forced break elements that were added by
+ * the Knuth algorithm. They will be re-added later on.
+ */
+ ListIterator iter = returnedList.listIterator(returnedList.size());
+ for (int i = 0; i < 3; i++) {
+ iter.previous();
+ iter.remove();
+ }
} else {
returnedList = getNextKnuthElements(childLC, alignment, positionAtIPDChange,
restartAtLM);
@@ -861,9 +883,9 @@ public abstract class AbstractBreaker {
case BlockLevelLayoutManager.LINE_NUMBER_ADJUSTMENT:
// potential line number adjustment
lineNumberMaxAdjustment.max += ((KnuthGlue) thisElement)
- .getY();
+ .getStretch();
lineNumberMaxAdjustment.min -= ((KnuthGlue) thisElement)
- .getZ();
+ .getShrink();
adjustableLinesList.add(thisElement);
break;
case BlockLevelLayoutManager.LINE_HEIGHT_ADJUSTMENT:
@@ -885,9 +907,9 @@ public abstract class AbstractBreaker {
KnuthGlue blockSpace = (KnuthGlue) unconfirmedList
.removeFirst();
spaceMaxAdjustment.max += ((KnuthGlue) blockSpace)
- .getY();
+ .getStretch();
spaceMaxAdjustment.min -= ((KnuthGlue) blockSpace)
- .getZ();
+ .getShrink();
blockSpacesList.add(blockSpace);
}
}
@@ -898,11 +920,11 @@ public abstract class AbstractBreaker {
log.debug("| space adj = "
+ spaceMaxAdjustment);
- if (thisElement.isPenalty() && thisElement.getW() > 0) {
+ if (thisElement.isPenalty() && thisElement.getWidth() > 0) {
log.debug(" mandatory variation to the number of lines!");
((BlockLevelLayoutManager) thisElement
.getLayoutManager()).negotiateBPDAdjustment(
- thisElement.getW(), thisElement);
+ thisElement.getWidth(), thisElement);
}
if (thisBreak.bpdAdjust != 0
@@ -967,7 +989,7 @@ public abstract class AbstractBreaker {
int partial = 0;
while (spaceListIterator.hasNext()) {
KnuthGlue blockSpace = (KnuthGlue)spaceListIterator.next();
- partial += (difference > 0 ? blockSpace.getY() : blockSpace.getZ());
+ partial += (difference > 0 ? blockSpace.getStretch() : blockSpace.getShrink());
if (log.isDebugEnabled()) {
log.debug("available = " + partial + " / " + total);
log.debug("competenza = "
@@ -990,7 +1012,7 @@ public abstract class AbstractBreaker {
int partial = 0;
while (lineListIterator.hasNext()) {
KnuthGlue line = (KnuthGlue)lineListIterator.next();
- partial += (difference > 0 ? line.getY() : line.getZ());
+ partial += (difference > 0 ? line.getStretch() : line.getShrink());
int newAdjust = ((BlockLevelLayoutManager) line.getLayoutManager()).negotiateBPDAdjustment(((int) ((float) partial * difference / total)) - adjustedDiff, line);
adjustedDiff += newAdjust;
}
diff --git a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
index e86c5feaf..3378d86d7 100644
--- a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
@@ -1133,7 +1133,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
// by this BlockLM, and must be ignored
if (element.getLayoutManager() != this) {
splitList.add(element);
- splitLength += element.getW();
+ splitLength += element.getWidth();
lastLM = element.getLayoutManager();
}
}
diff --git a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
index 53dc5b38c..d7453a399 100644
--- a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
@@ -339,7 +339,7 @@ public class BlockLayoutManager extends BlockStackingLayoutManager
// by this BlockLM, and must be ignored
if (element.getLayoutManager() != this) {
splitList.add(element);
- splitLength += element.getW();
+ splitLength += element.getWidth();
lastLM = element.getLayoutManager();
}
}
diff --git a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
index 9a0dbe220..92a423098 100644
--- a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
@@ -695,11 +695,11 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
/*LF*/ //log.debug(" BLM.negotiateBPDAdjustment> bpunit con penalty");
KnuthPenalty storedPenalty = (KnuthPenalty)
storedList.get(mappingPos.getLastIndex());
- if (storedPenalty.getW() > 0) {
+ if (storedPenalty.getWidth() > 0) {
// the original penalty has width > 0
/*LF*/ //log.debug(" BLM.negotiateBPDAdjustment> chiamata passata");
return ((BlockLevelLayoutManager)storedPenalty.getLayoutManager())
- .negotiateBPDAdjustment(storedPenalty.getW(),
+ .negotiateBPDAdjustment(storedPenalty.getWidth(),
storedPenalty);
} else {
// the original penalty has width = 0
@@ -1406,17 +1406,18 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
while (oldListIterator.hasNext()) {
KnuthElement element = (KnuthElement) oldListIterator.next();
if (element.isBox()) {
- totalLength.add(new MinOptMax(element.getW()));
- //log.debug("box " + element.getW());
+ totalLength.add(new MinOptMax(element.getWidth()));
+ //log.debug("box " + element.getWidth());
} else if (element.isGlue()) {
- totalLength.min -= element.getZ();
- totalLength.max += element.getY();
+ totalLength.min -= element.getShrink();
+ totalLength.max += element.getStretch();
//leafValue = ((LeafPosition) element.getPosition()).getLeafPos();
- //log.debug("glue " + element.getW() + " + "
- // + ((KnuthGlue) element).getY() + " - " + ((KnuthGlue) element).getZ());
+ //log.debug("glue " + element.getWidth() + " + "
+ // + ((KnuthGlue) element).getStretch() + " - "
+ // + ((KnuthGlue) element).getShrink());
} else {
- //log.debug((((KnuthPenalty)element).getP() == KnuthElement.INFINITE
- // ? "PENALTY " : "penalty ") + element.getW());
+ //log.debug((((KnuthPenalty)element).getPenalty() == KnuthElement.INFINITE
+ // ? "PENALTY " : "penalty ") + element.getWidth());
}
}
// compute the total amount of "units"
@@ -1443,22 +1444,22 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
KnuthElement element = (KnuthElement) oldListIterator.next();
lastIndex++;
if (element.isBox()) {
- lengthBeforeBreak.add(new MinOptMax(element.getW()));
- lengthAfterBreak.subtract(new MinOptMax(element.getW()));
+ lengthBeforeBreak.add(new MinOptMax(element.getWidth()));
+ lengthAfterBreak.subtract(new MinOptMax(element.getWidth()));
bPrevIsBox = true;
} else if (element.isGlue()) {
- lengthBeforeBreak.min -= element.getZ();
- lengthAfterBreak.min += element.getZ();
- lengthBeforeBreak.max += element.getY();
- lengthAfterBreak.max -= element.getY();
+ lengthBeforeBreak.min -= element.getShrink();
+ lengthAfterBreak.min += element.getShrink();
+ lengthBeforeBreak.max += element.getStretch();
+ lengthAfterBreak.max -= element.getStretch();
bPrevIsBox = false;
} else {
- lengthBeforeBreak.add(new MinOptMax(element.getW()));
+ lengthBeforeBreak.add(new MinOptMax(element.getWidth()));
bPrevIsBox = false;
}
// create the new elements
- if (element.isPenalty() && element.getP() < KnuthElement.INFINITE
+ if (element.isPenalty() && element.getPenalty() < KnuthElement.INFINITE
|| element.isGlue() && bPrevIsBox
|| !oldListIterator.hasNext()) {
// suppress elements after the breaking point
@@ -1468,8 +1469,8 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
iStepsForward++;
if (el.isGlue()) {
// suppressed glue
- lengthAfterBreak.min += el.getZ();
- lengthAfterBreak.max -= el.getY();
+ lengthAfterBreak.min += el.getShrink();
+ lengthAfterBreak.max -= el.getStretch();
} else if (el.isPenalty()) {
// suppressed penalty, do nothing
} else {
@@ -1489,8 +1490,8 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
for (int i = 0; i < iStepsForward; i++) {
KnuthElement el = (KnuthElement) oldListIterator.previous();
if (el.isGlue()) {
- lengthAfterBreak.min -= el.getZ();
- lengthAfterBreak.max += el.getY();
+ lengthAfterBreak.min -= el.getShrink();
+ lengthAfterBreak.max += el.getStretch();
}
}
@@ -1611,7 +1612,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
}
if (element.isPenalty()) {
- lengthBeforeBreak.add(new MinOptMax(-element.getW()));
+ lengthBeforeBreak.add(new MinOptMax(-element.getWidth()));
}
}
@@ -1640,14 +1641,14 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
- neededUnits(totalLength.opt - adjustedSpaceBefore))
* bpUnit;
// insert the correct elements
- newList.addFirst(new KnuthBox(wrongBox.getW() - decreasedLength,
+ newList.addFirst(new KnuthBox(wrongBox.getWidth() - decreasedLength,
wrongBox.getPosition(), false));
newList.addFirst(new KnuthGlue(decreasedLength, 0, 0, SPACE_BEFORE_ADJUSTMENT,
wrongBox.getPosition(), false));
- //log.debug(" rimosso box " + neededUnits(wrongBox.getW()));
+ //log.debug(" rimosso box " + neededUnits(wrongBox.getWidth()));
//log.debug(" aggiunto glue " + neededUnits(decreasedLength) + " 0 0");
//log.debug(" aggiunto box " + neededUnits(
- // wrongBox.getW() - decreasedLength));
+ // wrongBox.getWidth() - decreasedLength));
}
// if space-after.conditionality is "discard", correct newList
@@ -1663,7 +1664,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
// (it cannot be parted and has some stretch or shrink)
// the wrong box is the first one, not the last one
LinkedList preserveList = new LinkedList();
- if (wrongBox.getW() == 0) {
+ if (wrongBox.getWidth() == 0) {
preserveList.add(wrongBox);
preserveList.addFirst((KnuthGlue) newList.removeLast());
preserveList.addFirst((KnuthPenalty) newList.removeLast());
@@ -1676,7 +1677,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
- neededUnits(totalLength.opt - adjustedSpaceAfter))
* bpUnit;
// insert the correct box
- newList.addLast(new KnuthBox(wrongBox.getW() - decreasedLength,
+ newList.addLast(new KnuthBox(wrongBox.getWidth() - decreasedLength,
wrongBox.getPosition(), false));
// add preserved elements
if (!preserveList.isEmpty()) {
@@ -1685,9 +1686,9 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
// insert the correct glue
newList.addLast(new KnuthGlue(decreasedLength, 0, 0, SPACE_AFTER_ADJUSTMENT,
wrongBox.getPosition(), false));
- //log.debug(" rimosso box " + neededUnits(wrongBox.getW()));
+ //log.debug(" rimosso box " + neededUnits(wrongBox.getWidth()));
//log.debug(" aggiunto box " + neededUnits(
- // wrongBox.getW() - decreasedLength));
+ // wrongBox.getWidth() - decreasedLength));
//log.debug(" aggiunto glue " + neededUnits(decreasedLength) + " 0 0");
}
diff --git a/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java b/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java
index 3a688cce8..4516c8d97 100644
--- a/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java
+++ b/src/java/org/apache/fop/layoutmgr/BreakingAlgorithm.java
@@ -491,7 +491,7 @@ public abstract class BreakingAlgorithm {
elementIndex, previousIsBox, allowedBreaks).isBox();
if (activeNodeCount == 0) {
- if (ipdChanged()) {
+ if (getIPDdifference() != 0) {
return handleIpdChange();
}
if (!force) {
@@ -538,8 +538,8 @@ public abstract class BreakingAlgorithm {
return line;
}
- protected boolean ipdChanged() {
- return false;
+ protected int getIPDdifference() {
+ return 0;
}
protected int handleIpdChange() {
@@ -676,7 +676,7 @@ public abstract class BreakingAlgorithm {
protected void handleBox(KnuthBox box) {
// a KnuthBox object is not a legal line break,
// just add the width to the total
- totalWidth += box.getW();
+ totalWidth += box.getWidth();
}
/**
@@ -697,9 +697,9 @@ public abstract class BreakingAlgorithm {
&& !(allowedBreaks == ONLY_FORCED_BREAKS)) {
considerLegalBreak(glue, position);
}
- totalWidth += glue.getW();
- totalStretch += glue.getY();
- totalShrink += glue.getZ();
+ totalWidth += glue.getWidth();
+ totalStretch += glue.getStretch();
+ totalShrink += glue.getShrink();
}
/**
@@ -716,8 +716,8 @@ public abstract class BreakingAlgorithm {
// only if its penalty is not infinite;
// consider all penalties, non-flagged penalties or non-forcing penalties
// according to the value of allowedBreaks
- if (((penalty.getP() < KnuthElement.INFINITE)
- && (!(allowedBreaks == NO_FLAGGED_PENALTIES) || !penalty.isFlagged())
+ if (((penalty.getPenalty() < KnuthElement.INFINITE)
+ && (!(allowedBreaks == NO_FLAGGED_PENALTIES) || !penalty.isPenaltyFlagged())
&& (!(allowedBreaks == ONLY_FORCED_BREAKS)
|| penalty.isForcedBreak()))) {
considerLegalBreak(penalty, position);
@@ -880,7 +880,7 @@ public abstract class BreakingAlgorithm {
*/
protected boolean elementCanEndLine(KnuthElement element, int line, int difference) {
return (!element.isPenalty()
- || element.getP() < KnuthElement.INFINITE);
+ || element.getPenalty() < KnuthElement.INFINITE);
}
/**
@@ -921,9 +921,9 @@ public abstract class BreakingAlgorithm {
if (tempElement.isBox()) {
break;
} else if (tempElement.isGlue()) {
- newWidth += tempElement.getW();
- newStretch += tempElement.getY();
- newShrink += tempElement.getZ();
+ newWidth += tempElement.getWidth();
+ newStretch += tempElement.getStretch();
+ newShrink += tempElement.getShrink();
} else if (tempElement.isForcedBreak() && i != elementIdx) {
break;
}
@@ -1034,9 +1034,9 @@ public abstract class BreakingAlgorithm {
if (tempElement.isBox()) {
break;
} else if (tempElement.isGlue()) {
- newWidth += tempElement.getW();
- newStretch += tempElement.getY();
- newShrink += tempElement.getZ();
+ newWidth += tempElement.getWidth();
+ newStretch += tempElement.getStretch();
+ newShrink += tempElement.getShrink();
} else if (tempElement.isForcedBreak() && i != elementIdx) {
break;
}
@@ -1075,7 +1075,7 @@ public abstract class BreakingAlgorithm {
// compute the adjustment ratio
int actualWidth = totalWidth - activeNode.totalWidth;
if (element.isPenalty()) {
- actualWidth += element.getW();
+ actualWidth += element.getWidth();
}
return getLineWidth() - actualWidth;
}
@@ -1133,7 +1133,7 @@ public abstract class BreakingAlgorithm {
double f = Math.abs(r);
f = 1 + 100 * f * f * f;
if (element.isPenalty()) {
- double penalty = element.getP();
+ double penalty = element.getPenalty();
if (penalty >= 0) {
f += penalty;
demerits = f * f;
@@ -1146,9 +1146,9 @@ public abstract class BreakingAlgorithm {
demerits = f * f;
}
- if (element.isPenalty() && ((KnuthPenalty) element).isFlagged()
+ if (element.isPenalty() && ((KnuthPenalty) element).isPenaltyFlagged()
&& getElement(activeNode.position).isPenalty()
- && ((KnuthPenalty) getElement(activeNode.position)).isFlagged()) {
+ && ((KnuthPenalty) getElement(activeNode.position)).isPenaltyFlagged()) {
// add demerit for consecutive breaks at flagged penalties
demerits += repeatedFlaggedDemerit;
// there are at least two consecutive lines ending with a flagged penalty;
@@ -1160,7 +1160,7 @@ public abstract class BreakingAlgorithm {
prevNode = prevNode.previous) {
KnuthElement prevElement = getElement(prevNode.position);
if (prevElement.isPenalty()
- && ((KnuthPenalty) prevElement).isFlagged()) {
+ && ((KnuthPenalty) prevElement).isPenaltyFlagged()) {
// the previous line ends with a flagged penalty too
flaggedPenaltiesCount++;
} else {
diff --git a/src/java/org/apache/fop/layoutmgr/ElementListUtils.java b/src/java/org/apache/fop/layoutmgr/ElementListUtils.java
index d3403cd6b..ca11d27c2 100644
--- a/src/java/org/apache/fop/layoutmgr/ElementListUtils.java
+++ b/src/java/org/apache/fop/layoutmgr/ElementListUtils.java
@@ -62,13 +62,14 @@ public final class ElementListUtils {
if (el.isPenalty()) {
KnuthPenalty penalty = (KnuthPenalty)el;
//Convert all penalties to break inhibitors
- if (penalty.getP() < KnuthPenalty.INFINITE) {
- iter.set(new KnuthPenalty(penalty.getW(), KnuthPenalty.INFINITE,
- penalty.isFlagged(), penalty.getPosition(), penalty.isAuxiliary()));
+ if (penalty.getPenalty() < KnuthPenalty.INFINITE) {
+ iter.set(new KnuthPenalty(penalty.getWidth(), KnuthPenalty.INFINITE,
+ penalty.isPenaltyFlagged(), penalty.getPosition(),
+ penalty.isAuxiliary()));
}
} else if (el.isGlue()) {
KnuthGlue glue = (KnuthGlue)el;
- len += glue.getW();
+ len += glue.getWidth();
iter.previous();
el = (ListElement)iter.previous();
iter.next();
@@ -84,7 +85,7 @@ public final class ElementListUtils {
}
} else {
KnuthElement kel = (KnuthElement)el;
- len += kel.getW();
+ len += kel.getWidth();
}
if (len >= constraint) {
return false;
@@ -109,13 +110,14 @@ public final class ElementListUtils {
if (el.isPenalty()) {
KnuthPenalty penalty = (KnuthPenalty)el;
//Convert all penalties to break inhibitors
- if (penalty.getP() < KnuthPenalty.INFINITE) {
- i.set(new KnuthPenalty(penalty.getW(), KnuthPenalty.INFINITE,
- penalty.isFlagged(), penalty.getPosition(), penalty.isAuxiliary()));
+ if (penalty.getPenalty() < KnuthPenalty.INFINITE) {
+ i.set(new KnuthPenalty(penalty.getWidth(), KnuthPenalty.INFINITE,
+ penalty.isPenaltyFlagged(), penalty.getPosition(),
+ penalty.isAuxiliary()));
}
} else if (el.isGlue()) {
KnuthGlue glue = (KnuthGlue)el;
- len += glue.getW();
+ len += glue.getWidth();
el = (ListElement)i.previous();
i.next();
if (el.isBox()) {
@@ -134,7 +136,7 @@ public final class ElementListUtils {
}
} else {
KnuthElement kel = (KnuthElement)el;
- len += kel.getW();
+ len += kel.getWidth();
}
if (len >= constraint) {
return false;
@@ -158,9 +160,9 @@ public final class ElementListUtils {
while (iter.hasNext()) {
ListElement el = (ListElement)iter.next();
if (el.isBox()) {
- len += ((KnuthElement)el).getW();
+ len += ((KnuthElement)el).getWidth();
} else if (el.isGlue()) {
- len += ((KnuthElement)el).getW();
+ len += ((KnuthElement)el).getWidth();
} else {
//log.debug("Ignoring penalty: " + el);
//ignore penalties
@@ -210,7 +212,7 @@ public final class ElementListUtils {
*/
public static boolean endsWithNonInfinitePenalty(List elems) {
ListElement last = (ListElement) ListUtil.getLast(elems);
- if (last.isPenalty() && ((KnuthPenalty)last).getP() < KnuthElement.INFINITE) {
+ if (last.isPenalty() && ((KnuthPenalty)last).getPenalty() < KnuthElement.INFINITE) {
return true;
} else if (last instanceof BreakElement
&& ((BreakElement)last).getPenaltyValue() < KnuthElement.INFINITE) {
@@ -230,7 +232,7 @@ public final class ElementListUtils {
int prevBreak = startIndex - 1;
while (prevBreak >= 0) {
KnuthElement el = (KnuthElement)elems.get(prevBreak);
- if (el.isPenalty() && el.getP() < KnuthElement.INFINITE) {
+ if (el.isPenalty() && el.getPenalty() < KnuthElement.INFINITE) {
break;
}
prevBreak--;
diff --git a/src/java/org/apache/fop/layoutmgr/InlineKnuthSequence.java b/src/java/org/apache/fop/layoutmgr/InlineKnuthSequence.java
index 104c71131..0d00b710a 100644
--- a/src/java/org/apache/fop/layoutmgr/InlineKnuthSequence.java
+++ b/src/java/org/apache/fop/layoutmgr/InlineKnuthSequence.java
@@ -72,7 +72,7 @@ public class InlineKnuthSequence extends KnuthSequence {
lastOldElement = getLast();
firstNewElement = sequence.getElement(0);
if (firstNewElement.isBox() && !((KnuthElement) firstNewElement).isAuxiliary()
- && lastOldElement.isBox() && ((KnuthElement) lastOldElement).getW() != 0) {
+ && lastOldElement.isBox() && ((KnuthElement) lastOldElement).getWidth() != 0) {
addALetterSpace();
}
addAll(sequence);
diff --git a/src/java/org/apache/fop/layoutmgr/KnuthBox.java b/src/java/org/apache/fop/layoutmgr/KnuthBox.java
index 7c3df61fa..d7615dda1 100644
--- a/src/java/org/apache/fop/layoutmgr/KnuthBox.java
+++ b/src/java/org/apache/fop/layoutmgr/KnuthBox.java
@@ -37,12 +37,12 @@ public class KnuthBox extends KnuthElement {
/**
* Create a new KnuthBox.
*
- * @param w the width of this box
+ * @param width the width of this box
* @param pos the Position stored in this box
- * @param bAux is this box auxiliary?
+ * @param auxiliary is this box auxiliary?
*/
- public KnuthBox(int w, Position pos, boolean bAux) {
- super(w, pos, bAux);
+ public KnuthBox(int width, Position pos, boolean auxiliary) {
+ super(width, pos, auxiliary);
}
/** {@inheritDoc} */
@@ -52,14 +52,14 @@ public class KnuthBox extends KnuthElement {
/** {@inheritDoc} */
public String toString() {
- StringBuffer sb = new StringBuffer(64);
+ StringBuffer buffer = new StringBuffer(64);
if (isAuxiliary()) {
- sb.append("aux. ");
+ buffer.append("aux. ");
}
- sb.append("box");
- sb.append(" w=");
- sb.append(getW());
- return sb.toString();
+ buffer.append("box");
+ buffer.append(" w=");
+ buffer.append(getWidth());
+ return buffer.toString();
}
}
diff --git a/src/java/org/apache/fop/layoutmgr/KnuthElement.java b/src/java/org/apache/fop/layoutmgr/KnuthElement.java
index 41c813010..e8ca6d85b 100644
--- a/src/java/org/apache/fop/layoutmgr/KnuthElement.java
+++ b/src/java/org/apache/fop/layoutmgr/KnuthElement.java
@@ -33,44 +33,44 @@ public abstract class KnuthElement extends ListElement {
public static final int INFINITE = 1000;
private int width;
- private boolean bIsAuxiliary;
+ private boolean auxiliary;
/**
* Create a new KnuthElement.
* This class being abstract, this can be called only by subclasses.
*
- * @param w the width of this element
+ * @param width the width of this element
* @param pos the Position stored in this element
- * @param bAux is this an auxiliary element?
+ * @param auxiliary is this an auxiliary element?
*/
- protected KnuthElement(int w, Position pos, boolean bAux) {
+ protected KnuthElement(int width, Position pos, boolean auxiliary) {
super(pos);
- width = w;
- bIsAuxiliary = bAux;
+ this.width = width;
+ this.auxiliary = auxiliary;
}
/** @return true if this element is an auxiliary one. */
public boolean isAuxiliary() {
- return bIsAuxiliary;
+ return auxiliary;
}
/** @return the width of this element. */
- public int getW() {
+ public int getWidth() {
return width;
}
/** @return the penalty value of this element, if applicable. */
- public int getP() {
+ public int getPenalty() {
throw new RuntimeException("Element is not a penalty");
}
/** @return the stretch value of this element, if applicable. */
- public int getY() {
+ public int getStretch() {
throw new RuntimeException("Element is not a glue");
}
/** @return the shrink value of this element, if applicable. */
- public int getZ() {
+ public int getShrink() {
throw new RuntimeException("Element is not a glue");
}
diff --git a/src/java/org/apache/fop/layoutmgr/KnuthGlue.java b/src/java/org/apache/fop/layoutmgr/KnuthGlue.java
index fbb291f6b..7533a4117 100644
--- a/src/java/org/apache/fop/layoutmgr/KnuthGlue.java
+++ b/src/java/org/apache/fop/layoutmgr/KnuthGlue.java
@@ -54,24 +54,25 @@ public class KnuthGlue extends KnuthElement {
/**
* Create a new KnuthGlue.
*
- * @param w the width of this glue
- * @param y the stretchability of this glue
- * @param z the shrinkability of this glue
+ * @param width the width of this glue
+ * @param stretchability the stretchability of this glue
+ * @param shrinkability the shrinkability of this glue
* @param pos the Position stored in this glue
- * @param bAux is this glue auxiliary?
+ * @param auxiliary is this glue auxiliary?
*/
- public KnuthGlue(int w, int y, int z, Position pos, boolean bAux) {
- super(w, pos, bAux);
- stretchability = y;
- shrinkability = z;
+ public KnuthGlue(int width, int stretchability, int shrinkability, Position pos,
+ boolean auxiliary) {
+ super(width, pos, auxiliary);
+ this.stretchability = stretchability;
+ this.shrinkability = shrinkability;
}
- public KnuthGlue(int w, int y, int z,
- int iAdjClass, Position pos, boolean bAux) {
- super(w, pos, bAux);
- stretchability = y;
- shrinkability = z;
- adjustmentClass = iAdjClass;
+ public KnuthGlue(int width, int stretchability, int shrinkability, int adjustmentClass,
+ Position pos, boolean auxiliary) {
+ super(width, pos, auxiliary);
+ this.stretchability = stretchability;
+ this.shrinkability = shrinkability;
+ this.adjustmentClass = adjustmentClass;
}
/** {@inheritDoc} */
@@ -80,12 +81,12 @@ public class KnuthGlue extends KnuthElement {
}
/** @return the stretchability of this glue. */
- public int getY() {
+ public int getStretch() {
return stretchability;
}
/** @return the shrinkability of this glue. */
- public int getZ() {
+ public int getShrink() {
return shrinkability;
}
@@ -96,18 +97,18 @@ public class KnuthGlue extends KnuthElement {
/** {@inheritDoc} */
public String toString() {
- StringBuffer sb = new StringBuffer(64);
+ StringBuffer buffer = new StringBuffer(64);
if (isAuxiliary()) {
- sb.append("aux. ");
+ buffer.append("aux. ");
}
- sb.append("glue");
- sb.append(" w=").append(getW());
- sb.append(" stretch=").append(getY());
- sb.append(" shrink=").append(getZ());
+ buffer.append("glue");
+ buffer.append(" w=").append(getWidth());
+ buffer.append(" stretch=").append(getStretch());
+ buffer.append(" shrink=").append(getShrink());
if (getAdjustmentClass() >= 0) {
- sb.append(" adj-class=").append(getAdjustmentClass());
+ buffer.append(" adj-class=").append(getAdjustmentClass());
}
- return sb.toString();
+ return buffer.toString();
}
}
diff --git a/src/java/org/apache/fop/layoutmgr/KnuthPenalty.java b/src/java/org/apache/fop/layoutmgr/KnuthPenalty.java
index 9031b6b64..c17e9c7a2 100644
--- a/src/java/org/apache/fop/layoutmgr/KnuthPenalty.java
+++ b/src/java/org/apache/fop/layoutmgr/KnuthPenalty.java
@@ -45,39 +45,40 @@ public class KnuthPenalty extends KnuthElement {
public static final int FLAGGED_PENALTY = 50;
private int penalty;
- private boolean isFlagged;
+ private boolean penaltyFlagged;
private int breakClass = -1;
/**
* Create a new KnuthPenalty.
*
- * @param w the width of this penalty
- * @param p the penalty value of this penalty
- * @param f is this penalty flagged?
+ * @param width the width of this penalty
+ * @param penalty the penalty value of this penalty
+ * @param penaltyFlagged is this penalty flagged?
* @param pos the Position stored in this penalty
- * @param isAuxiliary is this penalty auxiliary?
+ * @param auxiliary is this penalty auxiliary?
*/
- public KnuthPenalty(int w, int p, boolean f, Position pos, boolean isAuxiliary) {
- super(w, pos, isAuxiliary);
- penalty = p;
- isFlagged = f;
+ public KnuthPenalty(int width, int penalty, boolean penaltyFlagged, Position pos,
+ boolean auxiliary) {
+ super(width, pos, auxiliary);
+ this.penalty = penalty;
+ this.penaltyFlagged = penaltyFlagged;
}
/**
* Create a new KnuthPenalty.
*
- * @param w the width of this penalty
- * @param p the penalty value of this penalty
- * @param f is this penalty flagged?
+ * @param width the width of this penalty
+ * @param penalty the penalty value of this penalty
+ * @param penaltyFlagged is this penalty flagged?
* @param breakClass the break class of this penalty (one of
* {@link Constants#EN_AUTO}, {@link Constants#EN_COLUMN}, {@link Constants#EN_PAGE},
* {@link Constants#EN_EVEN_PAGE}, {@link Constants#EN_ODD_PAGE})
* @param pos the Position stored in this penalty
* @param isAuxiliary is this penalty auxiliary?
*/
- public KnuthPenalty(int w, int p, boolean f,
- int breakClass, Position pos, boolean isAuxiliary) {
- this(w, p, f, pos, isAuxiliary);
+ public KnuthPenalty(int width, int penalty, boolean penaltyFlagged, int breakClass,
+ Position pos, boolean isAuxiliary) {
+ this(width, penalty, penaltyFlagged, pos, isAuxiliary);
this.breakClass = breakClass;
}
@@ -90,6 +91,8 @@ public class KnuthPenalty extends KnuthElement {
* (Mainly used in {@link #toString()} methods, to improve readability
* of the trace logs.)
*
+ * TODO: shouldn't be penalty a class of its own?
+ *
* @param penaltyValue the penalty value
* @return the penalty value as a {@link java.lang.String}
*/
@@ -110,21 +113,21 @@ public class KnuthPenalty extends KnuthElement {
/**
* @return the penalty value of this penalty.
*/
- public int getP() {
+ public int getPenalty() {
return penalty;
}
/**
* Sets a new penalty value.
- * @param p the new penalty value
+ * @param penalty the new penalty value
*/
- public void setP(int p) {
- this.penalty = p;
+ public void setPenalty(int penalty) {
+ this.penalty = penalty;
}
/** @return true is this penalty is a flagged one. */
- public boolean isFlagged() {
- return isFlagged;
+ public boolean isPenaltyFlagged() {
+ return penaltyFlagged;
}
/** {@inheritDoc} */
@@ -142,28 +145,28 @@ public class KnuthPenalty extends KnuthElement {
/** {@inheritDoc} */
public String toString() {
- StringBuffer sb = new StringBuffer(64);
+ StringBuffer buffer = new StringBuffer(64);
if (isAuxiliary()) {
- sb.append("aux. ");
+ buffer.append("aux. ");
}
- sb.append("penalty");
- sb.append(" p=");
- sb.append(valueOf(this.penalty));
- if (this.isFlagged) {
- sb.append(" [flagged]");
+ buffer.append("penalty");
+ buffer.append(" p=");
+ buffer.append(valueOf(this.penalty));
+ if (this.penaltyFlagged) {
+ buffer.append(" [flagged]");
}
- sb.append(" w=");
- sb.append(getW());
+ buffer.append(" w=");
+ buffer.append(getWidth());
if (isForcedBreak()) {
- sb.append(" (forced break, ")
+ buffer.append(" (forced break, ")
.append(getBreakClassName(this.breakClass))
.append(")");
} else if (this.penalty >= 0 && this.breakClass != -1) {
//penalty corresponding to a keep constraint
- sb.append(" (keep constraint, ")
+ buffer.append(" (keep constraint, ")
.append(getBreakClassName(this.breakClass))
.append(")");
}
- return sb.toString();
+ return buffer.toString();
}
}
diff --git a/src/java/org/apache/fop/layoutmgr/KnuthSequence.java b/src/java/org/apache/fop/layoutmgr/KnuthSequence.java
index feb633265..7c712040a 100644
--- a/src/java/org/apache/fop/layoutmgr/KnuthSequence.java
+++ b/src/java/org/apache/fop/layoutmgr/KnuthSequence.java
@@ -26,9 +26,12 @@ import java.util.List;
import java.util.ListIterator;
/**
- * Represents a list of Knuth elements.
+ * Represents a list of {@link KnuthElement Knuth elements}.
*/
public abstract class KnuthSequence extends ArrayList {
+
+ //TODO: do not extend ArrayList
+
/**
* Creates a new and empty list.
*/
diff --git a/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java b/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
index 52238e9be..83dea01bf 100644
--- a/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
+++ b/src/java/org/apache/fop/layoutmgr/PageBreakingAlgorithm.java
@@ -96,7 +96,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
//Controls whether a single part should be forced if possible (ex. block-container)
private boolean favorSinglePart = false;
- private boolean ipdChange;
+ private int ipdDifference;
private KnuthNode bestNodeForIPDChange;
//Used to keep track of switches in keep-context
@@ -320,7 +320,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
* will not have considered it a legal break, but it could still
* be one.
*/
- if (penalty.getP() == KnuthPenalty.INFINITE) {
+ if (penalty.getPenalty() == KnuthPenalty.INFINITE) {
int breakClass = penalty.getBreakClass();
if (breakClass == Constants.EN_PAGE
|| breakClass == Constants.EN_COLUMN) {
@@ -363,7 +363,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
noteListIterator.hasNext();) {
final KnuthElement element = (KnuthElement) noteListIterator.next();
if (element.isBox() || element.isGlue()) {
- noteLength += element.getW();
+ noteLength += element.getWidth();
}
}
int prevLength = (lengthList == null || lengthList.isEmpty())
@@ -445,22 +445,22 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
return true;
} else {
KnuthPenalty p = (KnuthPenalty) element;
- if (p.getP() <= 0) {
+ if (p.getPenalty() <= 0) {
return true;
} else {
int context = p.getBreakClass();
switch (context) {
case Constants.EN_LINE:
case Constants.EN_COLUMN:
- return p.getP() < KnuthPenalty.INFINITE;
+ return p.getPenalty() < KnuthPenalty.INFINITE;
case Constants.EN_PAGE:
- return p.getP() < KnuthPenalty.INFINITE
+ return p.getPenalty() < KnuthPenalty.INFINITE
|| !pageProvider.endPage(line - 1);
case Constants.EN_AUTO:
log.debug("keep is not auto but context is");
return true;
default:
- if (p.getP() < KnuthPenalty.INFINITE) {
+ if (p.getPenalty() < KnuthPenalty.INFINITE) {
log.debug("Non recognized keep context:" + context);
return true;
} else {
@@ -479,7 +479,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
int footnoteSplit = 0;
boolean canDeferOldFootnotes;
if (element.isPenalty()) {
- actualWidth += element.getW();
+ actualWidth += element.getWidth();
}
if (footnotesPending) {
// compute the total length of the footnotes not yet inserted
@@ -588,7 +588,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
index++) {
if (par.getElement(index).isGlue() && par.getElement(index - 1).isBox()
|| par.getElement(index).isPenalty()
- && ((KnuthElement) par.getElement(index)).getP() < KnuthElement.INFINITE) {
+ && ((KnuthElement) par.getElement(index)).getPenalty() < KnuthElement.INFINITE) {
// break found
break;
}
@@ -711,7 +711,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
element = (KnuthElement) noteListIterator.next();
if (element.isBox()) {
// element is a box
- splitLength += element.getW();
+ splitLength += element.getWidth();
boxPreceding = true;
} else if (element.isGlue()) {
// element is a glue
@@ -721,10 +721,10 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
break;
}
boxPreceding = false;
- splitLength += element.getW();
+ splitLength += element.getWidth();
} else {
// element is a penalty
- if (element.getP() < KnuthElement.INFINITE) {
+ if (element.getPenalty() < KnuthElement.INFINITE) {
// end of the sub-sequence
index = noteListIterator.previousIndex();
break;
@@ -792,7 +792,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
double f = Math.abs(r);
f = 1 + 100 * f * f * f;
if (element.isPenalty()) {
- double penalty = element.getP();
+ double penalty = element.getPenalty();
if (penalty >= 0) {
f += penalty;
demerits = f * f;
@@ -805,9 +805,9 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
demerits = f * f;
}
- if (element.isPenalty() && ((KnuthPenalty) element).isFlagged()
+ if (element.isPenalty() && ((KnuthPenalty) element).isPenaltyFlagged()
&& getElement(activeNode.position).isPenalty()
- && ((KnuthPenalty) getElement(activeNode.position)).isFlagged()) {
+ && ((KnuthPenalty) getElement(activeNode.position)).isPenaltyFlagged()) {
// add demerit for consecutive breaks at flagged penalties
demerits += repeatedFlaggedDemerit;
}
@@ -1077,8 +1077,8 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
}
/** {@inheritDoc} */
- protected boolean ipdChanged() {
- return ipdChange;
+ protected int getIPDdifference() {
+ return ipdDifference;
}
/** {@inheritDoc} */
@@ -1104,9 +1104,9 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
* @param node the active node to add
*/
protected void addNode(int line, KnuthNode node) {
- if (node.position < par.size() - 1 && line > 0 && ipdChange(line - 1)) {
+ if (node.position < par.size() - 1 && line > 0
+ && (ipdDifference = compareIPDs(line - 1)) != 0) {
log.trace("IPD changes at page " + line);
- ipdChange = true;
if (bestNodeForIPDChange == null
|| node.totalDemerits < bestNodeForIPDChange.totalDemerits) {
bestNodeForIPDChange = node;
@@ -1117,7 +1117,7 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
* The whole sequence could actually fit on the last page before
* the IPD change. No need to do any special handling.
*/
- ipdChange = false;
+ ipdDifference = 0;
}
super.addNode(line, node);
}
@@ -1127,12 +1127,11 @@ class PageBreakingAlgorithm extends BreakingAlgorithm {
return bestNodeForIPDChange;
}
- /** {@inheritDoc} */
- protected boolean ipdChange(int line) {
+ private int compareIPDs(int line) {
if (pageProvider == null) {
- return false;
+ return 0;
}
- return pageProvider.ipdChange(line);
+ return pageProvider.compareIPDs(line);
}
}
diff --git a/src/java/org/apache/fop/layoutmgr/PageProvider.java b/src/java/org/apache/fop/layoutmgr/PageProvider.java
index bd556366a..2e531a8d8 100644
--- a/src/java/org/apache/fop/layoutmgr/PageProvider.java
+++ b/src/java/org/apache/fop/layoutmgr/PageProvider.java
@@ -161,12 +161,13 @@ public class PageProvider implements Constants {
}
/**
- * Returns true if the part following the given one has a different IPD.
+ * Compares the IPD of the given part with the following one.
*
* @param index index of the current part
- * @return true if the following part has a different IPD, false otherwise
+ * @return a negative integer, zero or a positive integer as the current IPD is less
+ * than, equal to or greater than the IPD of the following part
*/
- public boolean ipdChange(int index) {
+ public int compareIPDs(int index) {
int columnCount = 0;
int colIndex = startColumnOfCurrentElementList + index;
int pageIndex = -1;
@@ -179,11 +180,11 @@ public class PageProvider implements Constants {
} while (colIndex >= columnCount);
if (colIndex + 1 < columnCount) {
// Next part is a column on same page => same IPD
- return false;
+ return 0;
} else {
Page nextPage = getPage(false, pageIndex + 1, RELTO_CURRENT_ELEMENT_LIST);
return page.getPageViewport().getBodyRegion().getIPD()
- != nextPage.getPageViewport().getBodyRegion().getIPD();
+ - nextPage.getPageViewport().getBodyRegion().getIPD();
}
}
diff --git a/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java
index 95f798161..4680f642e 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/ContentLayoutManager.java
@@ -266,12 +266,12 @@ public class ContentLayoutManager extends AbstractBaseLayoutManager
KnuthSequence ks = (KnuthSequence)obj;
for (Iterator it = ks.iterator(); it.hasNext(); ) {
contentElement = (KnuthElement)it.next();
- stackSize += contentElement.getW();
+ stackSize += contentElement.getWidth();
contentList.add(contentElement);
}
} else {
contentElement = (KnuthElement)obj;
- stackSize += contentElement.getW();
+ stackSize += contentElement.getWidth();
contentList.add(contentElement);
}
}
diff --git a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
index 7c30ab9bb..0b95ef859 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
@@ -680,7 +680,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
assert lastElement != null;
previousIsBox = lastElement.isBox()
&& !((KnuthElement) lastElement).isAuxiliary()
- && ((KnuthElement) lastElement).getW() != 0;
+ && ((KnuthElement) lastElement).getWidth() != 0;
// if last paragraph is open, add the new elements to the paragraph
// else this is the last paragraph
@@ -705,7 +705,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
// finish last paragraph if it was closed with a linefeed
if (lastElement.isPenalty()
- && ((KnuthPenalty) lastElement).getP() == -KnuthPenalty.INFINITE) {
+ && ((KnuthPenalty) lastElement).getPenalty() == -KnuthPenalty.INFINITE) {
// a penalty item whose value is -inf
// represents a preserved linefeed,
// which forces a line break
@@ -1172,7 +1172,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager
LeafPosition pos = (LeafPosition)lastElement.getPosition();
int totalAdj = adj;
//if (lastElement.isPenalty()) {
- // totalAdj += lastElement.getW();
+ // totalAdj += lastElement.getWidth();
//}
//int lineNumberDifference = (int)((double) totalAdj / constantLineHeight);
int lineNumberDifference = (int) Math.round((double) totalAdj / constantLineHeight
diff --git a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
index b8a2b283f..f793bb3bb 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java
@@ -57,6 +57,8 @@ import org.apache.fop.util.ListUtil;
*/
public class TextLayoutManager extends LeafNodeLayoutManager {
+ //TODO: remove all final modifiers at local variables
+
/**
* Store information about each potential text area.
* Index of character which ends the area, IPD of area, including
@@ -703,39 +705,39 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
}
private AreaInfo processWord(final int alignment, final KnuthSequence sequence,
- AreaInfo prevAi, final char ch, final boolean breakOpportunity,
+ AreaInfo prevAreaInfo, final char ch, final boolean breakOpportunity,
final boolean checkEndsWithHyphen) {
- AreaInfo ai;
+
//Word boundary found, process widths and kerning
int lastIndex = this.nextStart;
while (lastIndex > 0
- && this.foText.charAt(lastIndex - 1) == CharUtilities.SOFT_HYPHEN) {
+ && foText.charAt(lastIndex - 1) == CharUtilities.SOFT_HYPHEN) {
lastIndex--;
}
final boolean endsWithHyphen = checkEndsWithHyphen
- && this.foText.charAt(lastIndex) == CharUtilities.SOFT_HYPHEN;
+ && foText.charAt(lastIndex) == CharUtilities.SOFT_HYPHEN;
final Font font = FontSelector
- .selectFontForCharactersInText(this.foText,
- this.thisStart, lastIndex, this.foText, this);
+ .selectFontForCharactersInText(foText,
+ this.thisStart, lastIndex, foText, this);
final int wordLength = lastIndex - this.thisStart;
final boolean kerning = font.hasKerning();
final MinOptMax wordIPD = new MinOptMax(0);
for (int i = this.thisStart; i < lastIndex; i++) {
- final char c = this.foText.charAt(i);
+ final char currentChar = foText.charAt(i);
//character width
- final int charWidth = font.getCharWidth(c);
+ final int charWidth = font.getCharWidth(currentChar);
wordIPD.add(charWidth);
//kerning
if (kerning) {
int kern = 0;
if (i > this.thisStart) {
- final char previous = this.foText.charAt(i - 1);
- kern = font.getKernValue(previous, c) * font.getFontSize() / 1000;
- } else if (prevAi != null && !prevAi.isSpace && prevAi.breakIndex > 0) {
- final char previous = this.foText.charAt(prevAi.breakIndex - 1);
- kern = font.getKernValue(previous, c) * font.getFontSize() / 1000;
+ final char previousChar = foText.charAt(i - 1);
+ kern = font.getKernValue(previousChar, currentChar);
+ } else if (prevAreaInfo != null && !prevAreaInfo.isSpace && prevAreaInfo.breakIndex > 0) {
+ final char previousChar = foText.charAt(prevAreaInfo.breakIndex - 1);
+ kern = font.getKernValue(previousChar, currentChar);
}
if (kern != 0) {
this.addToLetterAdjust(i, kern);
@@ -748,11 +750,10 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
&& !TextLayoutManager.isSpace(ch)
&& lastIndex > 0
&& endsWithHyphen) {
- final int kern = font.getKernValue(
- this.foText.charAt(lastIndex - 1), ch)
- * font.getFontSize() / 1000;
+ final int kern = font.getKernValue(foText.charAt(lastIndex - 1), ch);
if (kern != 0) {
this.addToLetterAdjust(lastIndex, kern);
+ //TODO: add kern to wordIPD?
}
}
int iLetterSpaces = wordLength - 1;
@@ -765,20 +766,20 @@ public class TextLayoutManager extends LeafNodeLayoutManager {
wordIPD.add(MinOptMax.multiply(this.letterSpaceIPD, iLetterSpaces));
// create the AreaInfo object
- ai = new AreaInfo(this.thisStart, lastIndex, 0,
+ AreaInfo areaInfo = new AreaInfo(this.thisStart, lastIndex, 0,
iLetterSpaces, wordIPD,
endsWithHyphen,
false, breakOpportunity, font);
- prevAi = ai;
- this.vecAreaInfo.add(ai);
+ prevAreaInfo = areaInfo;
+ this.vecAreaInfo.add(areaInfo);
this.tempStart = this.nextStart;
//add the elements
- this.addElementsForAWordFragment(sequence, alignment, ai,
+ this.addElementsForAWordFragment(sequence, alignment, areaInfo,
this.vecAreaInfo.size() - 1, this.letterSpaceIPD);
- ai = null;
this.thisStart = this.nextStart;
- return prevAi;
+
+ return prevAreaInfo;
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
index fb88bb79d..9848584c0 100644
--- a/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/list/ListItemLayoutManager.java
@@ -298,14 +298,14 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager
int stepPenalty = 0;
KnuthElement endEl = (KnuthElement)elementLists[0].get(end[0]);
if (endEl instanceof KnuthPenalty) {
- additionalPenaltyHeight = endEl.getW();
- stepPenalty = Math.max(stepPenalty, endEl.getP());
+ additionalPenaltyHeight = endEl.getWidth();
+ stepPenalty = Math.max(stepPenalty, endEl.getPenalty());
}
endEl = (KnuthElement)elementLists[1].get(end[1]);
if (endEl instanceof KnuthPenalty) {
additionalPenaltyHeight = Math.max(
- additionalPenaltyHeight, endEl.getW());
- stepPenalty = Math.max(stepPenalty, endEl.getP());
+ additionalPenaltyHeight, endEl.getWidth());
+ stepPenalty = Math.max(stepPenalty, endEl.getPenalty());
}
int boxHeight = step - addedBoxHeight - penaltyHeight;
@@ -367,7 +367,7 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager
end[i]++;
KnuthElement el = (KnuthElement)elementLists[i].get(end[i]);
if (el.isPenalty()) {
- if (el.getP() < KnuthElement.INFINITE) {
+ if (el.getPenalty() < KnuthElement.INFINITE) {
//First legal break point
break;
}
@@ -379,9 +379,9 @@ public class ListItemLayoutManager extends BlockStackingLayoutManager
break;
}
}
- partialHeights[i] += el.getW();
+ partialHeights[i] += el.getWidth();
} else {
- partialHeights[i] += el.getW();
+ partialHeights[i] += el.getWidth();
}
}
if (end[i] < start[i]) {
diff --git a/src/java/org/apache/fop/layoutmgr/table/ActiveCell.java b/src/java/org/apache/fop/layoutmgr/table/ActiveCell.java
index 53e798e3c..f249d769f 100644
--- a/src/java/org/apache/fop/layoutmgr/table/ActiveCell.java
+++ b/src/java/org/apache/fop/layoutmgr/table/ActiveCell.java
@@ -158,9 +158,9 @@ class ActiveCell {
private int contentLength;
FillerPenalty(KnuthPenalty p, int length) {
- super(length, p.getP(), p.isFlagged(), p.getBreakClass(),
+ super(length, p.getPenalty(), p.isPenaltyFlagged(), p.getBreakClass(),
p.getPosition(), p.isAuxiliary());
- contentLength = p.getW();
+ contentLength = p.getWidth();
}
FillerPenalty(int length) {
@@ -190,7 +190,7 @@ class ActiveCell {
} else if (el instanceof FillerBox) {
return 0;
} else {
- return el.getW();
+ return el.getWidth();
}
}
@@ -248,17 +248,17 @@ class ActiveCell {
KnuthElement el = (KnuthElement) iter.next();
if (el.isBox()) {
prevIsBox = true;
- cumulateLength += el.getW();
+ cumulateLength += el.getWidth();
} else if (el.isGlue()) {
if (prevIsBox) {
elementList.add(iter.nextIndex() - 1,
new FillerPenalty(minBPD - cumulateLength));
}
prevIsBox = false;
- cumulateLength += el.getW();
+ cumulateLength += el.getWidth();
} else {
prevIsBox = false;
- if (cumulateLength + el.getW() < minBPD) {
+ if (cumulateLength + el.getWidth() < minBPD) {
iter.set(new FillerPenalty((KnuthPenalty) el, minBPD - cumulateLength));
}
}
@@ -314,7 +314,7 @@ class ActiveCell {
KnuthElement el = (KnuthElement) knuthIter.next();
if (el.isPenalty()) {
prevIsBox = false;
- if (el.getP() < KnuthElement.INFINITE
+ if (el.getPenalty() < KnuthElement.INFINITE
|| ((KnuthPenalty) el).getBreakClass() == Constants.EN_PAGE) {
// TODO too much is being done in that test, only to handle
// keep.within-column properly.
@@ -322,8 +322,8 @@ class ActiveCell {
// First legal break point
breakFound = true;
KnuthPenalty p = (KnuthPenalty) el;
- afterNextStep.penaltyLength = p.getW();
- afterNextStep.penaltyValue = p.getP();
+ afterNextStep.penaltyLength = p.getWidth();
+ afterNextStep.penaltyValue = p.getPenalty();
if (p.isForcedBreak()) {
afterNextStep.breakClass = p.getBreakClass();
}
@@ -333,9 +333,9 @@ class ActiveCell {
// Second legal break point
breakFound = true;
} else {
- afterNextStep.contentLength += el.getW();
+ afterNextStep.contentLength += el.getWidth();
if (!boxFound) {
- afterNextStep.condBeforeContentLength += el.getW();
+ afterNextStep.condBeforeContentLength += el.getWidth();
}
}
prevIsBox = false;
@@ -348,7 +348,7 @@ class ActiveCell {
}
prevIsBox = true;
boxFound = true;
- afterNextStep.contentLength += el.getW();
+ afterNextStep.contentLength += el.getWidth();
}
}
afterNextStep.end = knuthIter.nextIndex() - 1;
diff --git a/src/java/org/apache/fop/layoutmgr/table/RowPainter.java b/src/java/org/apache/fop/layoutmgr/table/RowPainter.java
index 7e32fdd5e..b3cb06582 100644
--- a/src/java/org/apache/fop/layoutmgr/table/RowPainter.java
+++ b/src/java/org/apache/fop/layoutmgr/table/RowPainter.java
@@ -361,7 +361,7 @@ class RowPainter {
while (iter.nextIndex() < endIndex) {
KnuthElement el = (KnuthElement) iter.next();
if (el.isBox() || el.isGlue()) {
- len += el.getW();
+ len += el.getWidth();
}
}
len += ActiveCell.getElementContentLength((KnuthElement) iter.next());
diff --git a/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java
index 4e3c0b102..ea2e64afb 100644
--- a/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/table/TableCellLayoutManager.java
@@ -202,7 +202,7 @@ public class TableCellLayoutManager extends BlockStackingLayoutManager
if (lastItem.isForcedBreak()) {
KnuthPenalty p = (KnuthPenalty) lastItem;
primaryGridUnit.setBreakAfter(p.getBreakClass());
- p.setP(0);
+ p.setPenalty(0);
}
setFinished(true);
diff --git a/src/java/org/apache/fop/pdf/PDFFontNonBase14.java b/src/java/org/apache/fop/pdf/PDFFontNonBase14.java
index 79ed10f48..faef636f6 100644
--- a/src/java/org/apache/fop/pdf/PDFFontNonBase14.java
+++ b/src/java/org/apache/fop/pdf/PDFFontNonBase14.java
@@ -76,7 +76,7 @@ public abstract class PDFFontNonBase14 extends PDFFont {
if (getDocumentSafely().getProfile().isFontEmbeddingRequired()) {
if (this.getDescriptor().getFontFile() == null) {
throw new PDFConformanceException("For " + getDocumentSafely().getProfile()
- + ", all fonts have to be embedded!");
+ + ", all fonts have to be embedded! Offending font: " + getBaseFont());
}
}
}
diff --git a/src/java/org/apache/fop/render/afp/AFPCustomizable.java b/src/java/org/apache/fop/render/afp/AFPCustomizable.java
index ed1ea443b..5f3fe6823 100644
--- a/src/java/org/apache/fop/render/afp/AFPCustomizable.java
+++ b/src/java/org/apache/fop/render/afp/AFPCustomizable.java
@@ -51,6 +51,14 @@ public interface AFPCustomizable {
void setNativeImagesSupported(boolean nativeImages);
/**
+ * Controls whether CMYK images (IOCA FS45) are enabled. By default, support is disabled
+ * for wider compatibility. When disabled, any CMYK image is converted to the selected
+ * color format.
+ * @param value true to enabled CMYK images
+ */
+ void setCMYKImagesSupported(boolean value);
+
+ /**
* Sets the shading mode for painting filled rectangles.
* @param shadingMode the shading mode
*/
diff --git a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
index 1f7a732d1..3fec25d8d 100644
--- a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
+++ b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
@@ -357,6 +357,11 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
}
/** {@inheritDoc} */
+ public void setCMYKImagesSupported(boolean value) {
+ paintingState.setCMYKImagesSupported(value);
+ }
+
+ /** {@inheritDoc} */
public void setShadingMode(AFPShadingMode shadingMode) {
this.shadingMode = shadingMode;
}
diff --git a/src/java/org/apache/fop/render/afp/AFPImageHandlerRawStream.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerRawStream.java
index 99ede8e79..fcfc9c64c 100644
--- a/src/java/org/apache/fop/render/afp/AFPImageHandlerRawStream.java
+++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerRawStream.java
@@ -24,6 +24,7 @@ import org.apache.xmlgraphics.image.loader.ImageFlavor;
import org.apache.xmlgraphics.image.loader.impl.ImageRawEPS;
import org.apache.xmlgraphics.image.loader.impl.ImageRawJPEG;
import org.apache.xmlgraphics.image.loader.impl.ImageRawStream;
+import org.apache.xmlgraphics.util.MimeConstants;
import org.apache.fop.afp.AFPDataObjectInfo;
import org.apache.fop.render.RenderingContext;
@@ -35,6 +36,7 @@ public class AFPImageHandlerRawStream extends AbstractAFPImageHandlerRawStream {
private static final ImageFlavor[] FLAVORS = new ImageFlavor[] {
ImageFlavor.RAW_JPEG,
+ ImageFlavor.RAW_TIFF,
ImageFlavor.RAW_EPS,
};
@@ -63,7 +65,12 @@ public class AFPImageHandlerRawStream extends AbstractAFPImageHandlerRawStream {
if (targetContext instanceof AFPRenderingContext) {
AFPRenderingContext afpContext = (AFPRenderingContext)targetContext;
return (afpContext.getPaintingState().isNativeImagesSupported())
- && (image == null || image instanceof ImageRawJPEG || image instanceof ImageRawEPS);
+ && (image == null
+ || image instanceof ImageRawJPEG
+ || image instanceof ImageRawEPS
+ || ((image instanceof ImageRawStream)
+ && (MimeConstants.MIME_TIFF.equals(
+ ((ImageRawStream)image).getMimeType()))));
}
return false;
}
diff --git a/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java b/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java
index 8f7918583..b0988e754 100644
--- a/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java
+++ b/src/java/org/apache/fop/render/afp/AFPImageHandlerRenderedImage.java
@@ -89,7 +89,11 @@ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements Ima
int resolution = paintingState.getResolution();
int maxPixelSize = paintingState.getBitsPerPixel();
if (paintingState.isColorImages()) {
- maxPixelSize *= 3; //RGB only at the moment
+ if (paintingState.isCMYKImagesSupported()) {
+ maxPixelSize *= 4; //CMYK is maximum
+ } else {
+ maxPixelSize *= 3; //RGB is maximum
+ }
}
RenderedImage renderedImage = imageRendered.getRenderedImage();
@@ -97,6 +101,7 @@ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements Ima
ImageSize intrinsicSize = imageInfo.getSize();
boolean useFS10 = (maxPixelSize == 1) || BitmapImageUtil.isMonochromeImage(renderedImage);
+ int functionSet = useFS10 ? 10 : 11;
boolean usePageSegments = useFS10
&& !imageObjectInfo.getResourceInfo().getLevel().isInline();
@@ -124,11 +129,6 @@ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements Ima
resampledDim.width, resampledDim.height, resolution);
}
}
- if (useFS10) {
- imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS10);
- } else {
- imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS11);
- }
imageObjectInfo.setDataHeightRes((int)Math.round(
effIntrinsicSize.getDpiHorizontal() * 10));
@@ -156,9 +156,9 @@ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements Ima
byte[] imageData = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
boolean allowDirectEncoding = true;
- if (allowDirectEncoding && pixelSize <= maxPixelSize) {
+ if (allowDirectEncoding && (pixelSize <= maxPixelSize)) {
//Attempt to encode without resampling the image
- ImageEncodingHelper helper = new ImageEncodingHelper(renderedImage);
+ ImageEncodingHelper helper = new ImageEncodingHelper(renderedImage, pixelSize == 32);
ColorModel encodedColorModel = helper.getEncodedColorModel();
boolean directEncode = true;
if (helper.getEncodedColorModel().getPixelSize() > maxPixelSize) {
@@ -180,6 +180,9 @@ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements Ima
log.trace("set subtractive mode");
imageObjectInfo.setSubtractive(true);
}
+ if (pixelSize == 32) {
+ functionSet = 45; //IOCA FS45 required for CMYK
+ }
helper.encode(baos);
imageData = baos.toByteArray();
@@ -191,6 +194,7 @@ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements Ima
//Convert image to 24bit RGB
ImageEncodingHelper.encodeRenderedImageAsRGB(renderedImage, baos);
imageData = baos.toByteArray();
+ imageObjectInfo.setBitsPerPixel(24);
boolean colorImages = paintingState.isColorImages();
imageObjectInfo.setColor(colorImages);
@@ -212,6 +216,20 @@ public class AFPImageHandlerRenderedImage extends AFPImageHandler implements Ima
}
}
+ switch (functionSet) {
+ case 10:
+ imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS10);
+ break;
+ case 11:
+ imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS11);
+ break;
+ case 45:
+ imageObjectInfo.setMimeType(MimeConstants.MIME_AFP_IOCA_FS45);
+ break;
+ default:
+ throw new IllegalStateException("Invalid IOCA function set: " + functionSet);
+ }
+
imageObjectInfo.setData(imageData);
// set object area info
diff --git a/src/java/org/apache/fop/render/afp/AFPRenderer.java b/src/java/org/apache/fop/render/afp/AFPRenderer.java
index f019c6a47..250ff9624 100644
--- a/src/java/org/apache/fop/render/afp/AFPRenderer.java
+++ b/src/java/org/apache/fop/render/afp/AFPRenderer.java
@@ -90,8 +90,8 @@ import org.apache.fop.render.afp.extensions.AFPElementMapping;
import org.apache.fop.render.afp.extensions.AFPExtensionAttachment;
import org.apache.fop.render.afp.extensions.AFPIncludeFormMap;
import org.apache.fop.render.afp.extensions.AFPInvokeMediumMap;
-import org.apache.fop.render.afp.extensions.AFPPageSetup;
import org.apache.fop.render.afp.extensions.AFPPageOverlay;
+import org.apache.fop.render.afp.extensions.AFPPageSetup;
/**
* This is an implementation of a FOP Renderer that renders areas to AFP.
@@ -444,6 +444,7 @@ public class AFPRenderer extends AbstractPathOrientedRenderer implements AFPCust
ImageFlavor.XML_DOM,
/*ImageFlavor.RAW_PNG, */ // PNG not natively supported in AFP
ImageFlavor.RAW_JPEG, ImageFlavor.RAW_CCITTFAX, ImageFlavor.RAW_EPS,
+ ImageFlavor.RAW_TIFF,
ImageFlavor.GRAPHICS2D, ImageFlavor.BUFFERED_IMAGE, ImageFlavor.RENDERED_IMAGE };
private static final ImageFlavor[] FLAVORS = new ImageFlavor[] {
@@ -831,6 +832,11 @@ public class AFPRenderer extends AbstractPathOrientedRenderer implements AFPCust
}
/** {@inheritDoc} */
+ public void setCMYKImagesSupported(boolean value) {
+ paintingState.setCMYKImagesSupported(value);
+ }
+
+ /** {@inheritDoc} */
public void setShadingMode(AFPShadingMode shadingMode) {
this.shadingMode = shadingMode;
}
diff --git a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
index 49e51b3d1..1e15d4c72 100644
--- a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
+++ b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
@@ -318,6 +318,9 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator
String imagesMode = imagesCfg.getAttribute("mode", IMAGES_MODE_GRAYSCALE);
if (IMAGES_MODE_COLOR.equals(imagesMode)) {
customizable.setColorImages(true);
+
+ boolean cmyk = imagesCfg.getAttributeAsBoolean("cmyk", false);
+ customizable.setCMYKImagesSupported(cmyk);
} else {
customizable.setColorImages(false);
// default to 8 bits per pixel
diff --git a/src/java/org/apache/fop/tools/anttasks/Fop.java b/src/java/org/apache/fop/tools/anttasks/Fop.java
index da25478c3..cfb8c8ade 100644
--- a/src/java/org/apache/fop/tools/anttasks/Fop.java
+++ b/src/java/org/apache/fop/tools/anttasks/Fop.java
@@ -34,6 +34,7 @@ import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.util.List;
+import java.util.Vector;
// FOP
import org.apache.fop.apps.FOPException;
@@ -67,7 +68,10 @@ import org.xml.sax.SAXException;
public class Fop extends Task {
private File foFile;
- private List filesets = new java.util.ArrayList();
+ private File xmlFile;
+ private File xsltFile;
+ private String xsltParams;
+ private List/*<FileSet>*/ filesets = new java.util.ArrayList/*<FileSet>*/();
private File outFile;
private File outDir;
private String format; //MIME type
@@ -112,6 +116,54 @@ public class Fop extends Task {
}
/**
+ * Gets the input XML file.
+ * @return the input XML file.
+ */
+ public File getXmlFile() {
+ return xmlFile;
+ }
+
+ /**
+ * Sets the input XML file.
+ * @param xmlFile the input XML file.
+ */
+ public void setXmlFile(File xmlFile) {
+ this.xmlFile = xmlFile;
+ }
+
+ /**
+ * Gets the input XSLT file.
+ * @return the input XSLT file.
+ */
+ public File getXsltFile() {
+ return xsltFile;
+ }
+
+ /**
+ * Sets the input XSLT file.
+ * @param xsltFile the input XSLT file.
+ */
+ public void setXsltFile(File xsltFile) {
+ this.xsltFile = xsltFile;
+ }
+
+ /**
+ * Gets the XSLT parameters
+ * @return the XSLT parameters
+ */
+ public String getXsltParams() {
+ return xsltParams;
+ }
+
+ /**
+ * Sets the XSLT parameters
+ * @param xsltParams the XSLT parameters
+ */
+ public void setXsltParams(String xsltParams) {
+ this.xsltParams = xsltParams;
+ }
+
+ /**
* Adds a set of XSL-FO files (nested fileset attribute).
* @param set a fileset
*/
@@ -491,10 +543,39 @@ class FOPTaskStarter {
skippedcount++;
}
}
+ } else if (task.getXmlFile() != null && task.getXsltFile() != null) {
+ if (task.getXmlFile().exists() && task.getXsltFile().exists()) {
+ File outf = task.getOutfile();
+ if (outf == null) {
+ throw new BuildException("outfile is required when fofile is used");
+ }
+ if (task.getOutdir() != null) {
+ outf = new File(task.getOutdir(), outf.getName());
+ }
+ // Render if "force" flag is set OR
+ // 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.getXsltFile().lastModified() > outf.lastModified())) {
+ render(task.getXmlFile(), task.getXsltFile(), outf, outputFormat);
+ actioncount++;
+ } else if (outf.exists()
+ && (task.getXmlFile().lastModified() <= outf.lastModified() ||
+ task.getXsltFile().lastModified() <= outf.lastModified())) {
+ skippedcount++;
+ }
+ }
}
GlobPatternMapper mapper = new GlobPatternMapper();
- mapper.setFrom("*.fo");
+
+ String inputExtension = ".fo";
+ File xsltFile = task.getXsltFile();
+ if (xsltFile != null) {
+ inputExtension = ".xml";
+ }
+ mapper.setFrom("*" + inputExtension);
mapper.setTo("*" + newExtension);
// deal with the filesets
@@ -507,16 +588,19 @@ class FOPTaskStarter {
File f = new File(fs.getDir(task.getProject()), files[j]);
File outf = null;
- if (task.getOutdir() != null && files[j].endsWith(".fo")) {
+ if (task.getOutdir() != null && files[j].endsWith(inputExtension)) {
String[] sa = mapper.mapFileName(files[j]);
outf = new File(task.getOutdir(), sa[0]);
} else {
- outf = replaceExtension(f, ".fo", newExtension);
+ outf = replaceExtension(f, inputExtension, newExtension);
if (task.getOutdir() != null) {
outf = new File(task.getOutdir(), outf.getName());
}
}
-
+ File dir = outf.getParentFile();
+ if (!dir.exists()) {
+ dir.mkdirs();
+ }
try {
if (task.getRelativebase()) {
this.baseURL = f.getParentFile().toURI().toURL().
@@ -536,7 +620,11 @@ class FOPTaskStarter {
// output file is older than input file
if (task.getForce() || !outf.exists()
|| (f.lastModified() > outf.lastModified() )) {
- render(f, outf, outputFormat);
+ if (xsltFile != null) {
+ render(f, xsltFile, outf, outputFormat);
+ } else {
+ render(f, outf, outputFormat);
+ }
actioncount++;
} else if (outf.exists() && (f.lastModified() <= outf.lastModified() )) {
skippedcount++;
@@ -554,10 +642,7 @@ class FOPTaskStarter {
}
}
- private void render(File foFile, File outFile,
- String outputFormat) throws FOPException {
- InputHandler inputHandler = new InputHandler(foFile);
-
+ private void renderInputHandler(InputHandler inputHandler, File outFile, String outputFormat) throws Exception {
OutputStream out = null;
try {
out = new java.io.FileOutputStream(outFile);
@@ -565,11 +650,6 @@ class FOPTaskStarter {
} catch (Exception ex) {
throw new BuildException("Failed to open " + outFile, ex);
}
-
- if (task.getLogFiles()) {
- task.log(foFile + " -> " + outFile, Project.MSG_INFO);
- }
-
boolean success = false;
try {
FOUserAgent userAgent = fopFactory.newFOUserAgent();
@@ -580,7 +660,7 @@ class FOPTaskStarter {
if (task.getThrowexceptions()) {
throw new BuildException(ex);
}
- logger.error("Error rendering fo file: " + foFile, ex);
+ throw ex;
} finally {
try {
out.close();
@@ -593,5 +673,31 @@ class FOPTaskStarter {
}
}
+ private void render(File foFile, File outFile,
+ String outputFormat) throws FOPException {
+ InputHandler inputHandler = new InputHandler(foFile);
+ try {
+ renderInputHandler(inputHandler, outFile, outputFormat);
+ } catch (Exception ex) {
+ logger.error("Error rendering fo file: " + foFile, ex);
+ }
+ if (task.getLogFiles()) {
+ task.log(foFile + " -> " + outFile, Project.MSG_INFO);
+ }
+ }
+
+ private void render(File xmlFile, File xsltFile, File outFile, String outputFormat) {
+ //TODO: implement support for XSLT params
+ final Vector xsltParams = null;
+ InputHandler inputHandler = new InputHandler(xmlFile, xsltFile, xsltParams);
+ try {
+ renderInputHandler(inputHandler, outFile, outputFormat);
+ } catch (Exception ex) {
+ logger.error("Error rendering xml/xslt files: " + xmlFile + ", " + xsltFile, ex);
+ }
+ if (task.getLogFiles()) {
+ task.log("xml: " + xmlFile + ", xslt: " + xsltFile + " -> " + outFile, Project.MSG_INFO);
+ }
+ }
}
diff --git a/status.xml b/status.xml
index 326b75001..25867534c 100644
--- a/status.xml
+++ b/status.xml
@@ -61,6 +61,18 @@
<action context="Renderers" dev="JM" type="add" fixes-bug="46705" due-to="Jost Klopfstein">
Added basic accessibility and Tagged PDF support.
</action>
+ <action context="Code" dev="JM" type="add">
+ Added support for encoding CMYK bitmap images (IOCA FS45) and TIFF images as embedded objects.
+ </action>
+ <action context="Code" dev="AC" type="add">
+ Added support for xmlfile and xsltfile parameters in FOP's Ant Task.
+ </action>
+ <action context="Renderers" dev="AC" type="fix" fixes-bug="47941">
+ BugFix: Maintain valid AFP by providing TLE truncation on Attribute Value Triplet values that are greater than 250 chars in length.
+ </action>
+ <action context="Fonts" dev="JM" type="fix" fixes-bug="47711" due-to="Nicolas Peninguy">
+ Fixed generation of CIDSet object in PDF output.
+ </action>
<action context="Layout" dev="VH" type="fix">
Fixed handling of percentage values for provisional-label-separation.
</action>
diff --git a/test/java/org/apache/fop/layoutengine/ElementListCheck.java b/test/java/org/apache/fop/layoutengine/ElementListCheck.java
index 1b6077c29..e63fc3291 100644
--- a/test/java/org/apache/fop/layoutengine/ElementListCheck.java
+++ b/test/java/org/apache/fop/layoutengine/ElementListCheck.java
@@ -83,10 +83,10 @@ public class ElementListCheck implements LayoutEngineCheck {
}
if (domEl.getAttribute("w").length() > 0) {
int w = Integer.parseInt(domEl.getAttribute("w"));
- if (w != knuthEl.getW()) {
+ if (w != knuthEl.getWidth()) {
fail("Expected w=" + w
+ " at position " + pos
- + " but got: " + knuthEl.getW());
+ + " but got: " + knuthEl.getWidth());
}
}
if ("true".equals(domEl.getAttribute("aux"))) {
@@ -110,24 +110,24 @@ public class ElementListCheck implements LayoutEngineCheck {
KnuthPenalty pen = (KnuthPenalty)knuthEl;
if (domEl.getAttribute("w").length() > 0) {
int w = Integer.parseInt(domEl.getAttribute("w"));
- if (w != knuthEl.getW()) {
+ if (w != knuthEl.getWidth()) {
fail("Expected w=" + w
+ " at position " + pos
- + " but got: " + knuthEl.getW());
+ + " but got: " + knuthEl.getWidth());
}
}
if (domEl.getAttribute("p").length() > 0) {
if ("<0".equals(domEl.getAttribute("p"))) {
- if (knuthEl.getP() >= 0) {
+ if (knuthEl.getPenalty() >= 0) {
fail("Expected p<0"
+ " at position " + pos
- + " but got: " + knuthEl.getP());
+ + " but got: " + knuthEl.getPenalty());
}
} else if (">0".equals(domEl.getAttribute("p"))) {
- if (knuthEl.getP() <= 0) {
+ if (knuthEl.getPenalty() <= 0) {
fail("Expected p>0"
+ " at position " + pos
- + " but got: " + knuthEl.getP());
+ + " but got: " + knuthEl.getPenalty());
}
} else {
int p;
@@ -142,20 +142,20 @@ public class ElementListCheck implements LayoutEngineCheck {
} else {
p = Integer.parseInt(domEl.getAttribute("p"));
}
- if (p != knuthEl.getP()) {
+ if (p != knuthEl.getPenalty()) {
fail("Expected p=" + p
+ " at position " + pos
- + " but got: " + knuthEl.getP());
+ + " but got: " + knuthEl.getPenalty());
}
}
}
if ("true".equals(domEl.getAttribute("flagged"))) {
- if (!pen.isFlagged()) {
+ if (!pen.isPenaltyFlagged()) {
fail("Expected flagged penalty"
+ " at position " + pos);
}
} else if ("false".equals(domEl.getAttribute("flagged"))) {
- if (pen.isFlagged()) {
+ if (pen.isPenaltyFlagged()) {
fail("Expected non-flagged penalty"
+ " at position " + pos);
}
@@ -180,26 +180,26 @@ public class ElementListCheck implements LayoutEngineCheck {
KnuthGlue glue = (KnuthGlue)knuthEl;
if (domEl.getAttribute("w").length() > 0) {
int w = Integer.parseInt(domEl.getAttribute("w"));
- if (w != knuthEl.getW()) {
+ if (w != knuthEl.getWidth()) {
fail("Expected w=" + w
+ " at position " + pos
- + " but got: " + knuthEl.getW());
+ + " but got: " + knuthEl.getWidth());
}
}
if (domEl.getAttribute("y").length() > 0) {
int stretch = Integer.parseInt(domEl.getAttribute("y"));
- if (stretch != knuthEl.getY()) {
+ if (stretch != knuthEl.getStretch()) {
fail("Expected y=" + stretch
+ " (stretch) at position " + pos
- + " but got: " + knuthEl.getY());
+ + " but got: " + knuthEl.getStretch());
}
}
if (domEl.getAttribute("z").length() > 0) {
int shrink = Integer.parseInt(domEl.getAttribute("z"));
- if (shrink != knuthEl.getZ()) {
+ if (shrink != knuthEl.getShrink()) {
fail("Expected z=" + shrink
+ " (shrink) at position " + pos
- + " but got: " + knuthEl.getZ());
+ + " but got: " + knuthEl.getShrink());
}
}
} else {
diff --git a/test/java/org/apache/fop/util/ElementListUtilsTestCase.java b/test/java/org/apache/fop/util/ElementListUtilsTestCase.java
index d41e9f94f..bebad4422 100644
--- a/test/java/org/apache/fop/util/ElementListUtilsTestCase.java
+++ b/test/java/org/apache/fop/util/ElementListUtilsTestCase.java
@@ -55,9 +55,9 @@ public class ElementListUtilsTestCase extends TestCase {
assertFalse(res);
- assertEquals(KnuthElement.INFINITE, ((KnuthPenalty)lst.get(1)).getP());
- assertEquals(KnuthElement.INFINITE, ((KnuthPenalty)lst.get(3)).getP());
- assertEquals(0, ((KnuthPenalty)lst.get(5)).getP());
+ assertEquals(KnuthElement.INFINITE, ((KnuthPenalty)lst.get(1)).getPenalty());
+ assertEquals(KnuthElement.INFINITE, ((KnuthPenalty)lst.get(3)).getPenalty());
+ assertEquals(0, ((KnuthPenalty)lst.get(5)).getPenalty());
}
/**
@@ -82,11 +82,11 @@ public class ElementListUtilsTestCase extends TestCase {
assertFalse(res);
//Must insert an INFINITE penalty
- assertEquals(KnuthElement.INFINITE, ((KnuthPenalty)lst.get(1)).getP());
- assertEquals(0, ((KnuthGlue)lst.get(2)).getW());
- assertEquals(KnuthElement.INFINITE, ((KnuthPenalty)lst.get(4)).getP());
- assertEquals(0, ((KnuthGlue)lst.get(5)).getW());
- assertEquals(0, ((KnuthGlue)lst.get(7)).getW());
+ assertEquals(KnuthElement.INFINITE, ((KnuthPenalty)lst.get(1)).getPenalty());
+ assertEquals(0, ((KnuthGlue)lst.get(2)).getWidth());
+ assertEquals(KnuthElement.INFINITE, ((KnuthPenalty)lst.get(4)).getPenalty());
+ assertEquals(0, ((KnuthGlue)lst.get(5)).getWidth());
+ assertEquals(0, ((KnuthGlue)lst.get(7)).getWidth());
}
/**
@@ -110,9 +110,9 @@ public class ElementListUtilsTestCase extends TestCase {
assertFalse(res);
- assertEquals(0, ((KnuthPenalty)lst.get(1)).getP());
- assertEquals(KnuthElement.INFINITE, ((KnuthPenalty)lst.get(3)).getP());
- assertEquals(KnuthElement.INFINITE, ((KnuthPenalty)lst.get(5)).getP());
+ assertEquals(0, ((KnuthPenalty)lst.get(1)).getPenalty());
+ assertEquals(KnuthElement.INFINITE, ((KnuthPenalty)lst.get(3)).getPenalty());
+ assertEquals(KnuthElement.INFINITE, ((KnuthPenalty)lst.get(5)).getPenalty());
}
/**
@@ -137,10 +137,10 @@ public class ElementListUtilsTestCase extends TestCase {
assertFalse(res);
//Must insert an INFINITE penalty
- assertEquals(0, ((KnuthPenalty)lst.get(1)).getP());
- assertEquals(KnuthElement.INFINITE, ((KnuthPenalty)lst.get(3)).getP());
- assertEquals(KnuthElement.INFINITE, ((KnuthPenalty)lst.get(5)).getP());
- assertEquals(0, ((KnuthGlue)lst.get(6)).getW());
+ assertEquals(0, ((KnuthPenalty)lst.get(1)).getPenalty());
+ assertEquals(KnuthElement.INFINITE, ((KnuthPenalty)lst.get(3)).getPenalty());
+ assertEquals(KnuthElement.INFINITE, ((KnuthPenalty)lst.get(5)).getPenalty());
+ assertEquals(0, ((KnuthGlue)lst.get(6)).getWidth());
}
diff --git a/test/layoutengine/standard-testcases/flow_changing-ipd_no-restartable.xml b/test/layoutengine/standard-testcases/flow_changing-ipd_no-restartable.xml
new file mode 100644
index 000000000..576a73ac6
--- /dev/null
+++ b/test/layoutengine/standard-testcases/flow_changing-ipd_no-restartable.xml
@@ -0,0 +1,404 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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$ -->
+<testcase>
+ <info>
+ <p>
+ This test checks that the code behaves properly when no restartable element can be found at
+ all after a changing IPD break.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" font-size="8pt" line-height="10pt"
+ provisional-distance-between-starts="6pt" provisional-label-separation="0">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="narrow"
+ page-height="70pt" page-width="320pt" margin="10pt">
+ <fo:region-body background-color="#F0F0F0"/>
+ </fo:simple-page-master>
+ <fo:simple-page-master master-name="wide"
+ page-height="70pt" page-width="420pt" margin="10pt">
+ <fo:region-body background-color="#F0F0F0"/>
+ </fo:simple-page-master>
+ <fo:page-sequence-master master-name="start-narrow-rest-wide">
+ <fo:single-page-master-reference master-reference="narrow"/>
+ <fo:repeatable-page-master-reference master-reference="wide"/>
+ </fo:page-sequence-master>
+ <fo:page-sequence-master master-name="alternate">
+ <fo:repeatable-page-master-alternatives>
+ <fo:conditional-page-master-reference master-reference="narrow" odd-or-even="odd"/>
+ <fo:conditional-page-master-reference master-reference="wide" odd-or-even="even"/>
+ </fo:repeatable-page-master-alternatives>
+ </fo:page-sequence-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="start-narrow-rest-wide">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="30pt">Before the table</fo:block>
+ <fo:table table-layout="fixed" width="100%">
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>
+ <fo:block>Before page break</fo:block>
+ <fo:block>After page break</fo:block>
+ </fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ </fo:flow>
+ </fo:page-sequence>
+ <fo:page-sequence master-reference="start-narrow-rest-wide">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="30pt">Before the table</fo:block>
+ <fo:table table-layout="fixed" width="100%">
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>
+ <fo:block>Before page break</fo:block>
+ <fo:block>After page break</fo:block>
+ </fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>Fill 1</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>Fill 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>Fill 3</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>Fill 4</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>Fill 5</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>Fill 6</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>Fill 7</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ </fo:flow>
+ </fo:page-sequence>
+ <fo:page-sequence master-reference="alternate">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="30pt">Before the table</fo:block>
+ <fo:table table-layout="fixed" width="100%">
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>
+ <fo:block>Before page break</fo:block>
+ <fo:block>After page break</fo:block>
+ </fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>Fill 1</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>Fill 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>Fill 3</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>Fill 4</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>Fill 5</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>Fill 6</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>Fill 7</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ </fo:flow>
+ </fo:page-sequence>
+ <fo:page-sequence master-reference="start-narrow-rest-wide">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="30pt">Before the list</fo:block>
+ <fo:list-block>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>Before page break</fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>After page break</fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ </fo:list-block>
+ </fo:flow>
+ </fo:page-sequence>
+ <fo:page-sequence master-reference="start-narrow-rest-wide">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="30pt">Before the list</fo:block>
+ <fo:list-block>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>Before page break</fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>After page break</fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>Fill 1</fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>Fill 2</fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>Fill 3</fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>Fill 4</fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>Fill 5</fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>Fill 6</fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>Fill 7</fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ </fo:list-block>
+ </fo:flow>
+ </fo:page-sequence>
+ <fo:page-sequence master-reference="alternate">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block space-after="30pt">Before the list</fo:block>
+ <fo:list-block>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>Before page break</fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>After page break</fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>Fill 1</fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>Fill 2</fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>Fill 3</fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>Fill 4</fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>Fill 5</fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>Fill 6</fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ <fo:list-item>
+ <fo:list-item-label end-indent="label-end()">
+ <fo:block>•</fo:block>
+ </fo:list-item-label>
+ <fo:list-item-body start-indent="body-start()">
+ <fo:block>Fill 7</fo:block>
+ </fo:list-item-body>
+ </fo:list-item>
+ </fo:list-block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+
+ <!-- Tables -->
+ <eval expected="Before page break" xpath="//pageSequence[1]/pageViewport[1]//flow/block[2]//text"/>
+ <eval expected="After page break" xpath="//pageSequence[1]/pageViewport[2]//flow/block[1]//text"/>
+
+ <eval expected="Before page break" xpath="//pageSequence[2]/pageViewport[1]//flow/block[2]//text"/>
+ <eval expected="After page break" xpath="//pageSequence[2]/pageViewport[2]//flow/block/block[1]//text"/>
+ <eval expected="Fill 1" xpath="//pageSequence[2]/pageViewport[2]//flow/block/block[2]//text"/>
+ <eval expected="Fill 2" xpath="//pageSequence[2]/pageViewport[2]//flow/block/block[3]//text"/>
+ <eval expected="Fill 3" xpath="//pageSequence[2]/pageViewport[2]//flow/block/block[4]//text"/>
+ <eval expected="Fill 4" xpath="//pageSequence[2]/pageViewport[2]//flow/block/block[5]//text"/>
+ <eval expected="Fill 5" xpath="//pageSequence[2]/pageViewport[3]//flow/block/block[1]//text"/>
+ <eval expected="Fill 6" xpath="//pageSequence[2]/pageViewport[3]//flow/block/block[2]//text"/>
+ <eval expected="Fill 7" xpath="//pageSequence[2]/pageViewport[3]//flow/block/block[3]//text"/>
+
+ <eval expected="Before page break" xpath="//pageSequence[3]/pageViewport[1]//flow/block[2]//text"/>
+ <eval expected="After page break" xpath="//pageSequence[3]/pageViewport[2]//flow/block/block[1]//text"/>
+ <eval expected="Fill 1" xpath="//pageSequence[3]/pageViewport[2]//flow/block/block[2]//text"/>
+ <eval expected="Fill 2" xpath="//pageSequence[3]/pageViewport[2]//flow/block/block[3]//text"/>
+ <eval expected="Fill 3" xpath="//pageSequence[3]/pageViewport[2]//flow/block/block[4]//text"/>
+ <eval expected="Fill 4" xpath="//pageSequence[3]/pageViewport[2]//flow/block/block[5]//text"/>
+ <eval expected="Fill 5" xpath="//pageSequence[3]/pageViewport[3]//flow/block/block[1]//text"/>
+ <eval expected="Fill 6" xpath="//pageSequence[3]/pageViewport[3]//flow/block/block[2]//text"/>
+ <eval expected="Fill 7" xpath="//pageSequence[3]/pageViewport[3]//flow/block/block[3]//text"/>
+
+ <!-- Lists -->
+ <eval expected="Before page break" xpath="//pageSequence[4]/pageViewport[1]//flow/block[2]/block/block[2]//text"/>
+ <eval expected="After page break" xpath="//pageSequence[4]/pageViewport[2]//flow/block[1]/block/block[2]//text"/>
+
+ <eval expected="Before page break" xpath="//pageSequence[5]/pageViewport[1]//flow/block[2]/block/block[2]//text"/>
+ <eval expected="After page break" xpath="//pageSequence[5]/pageViewport[2]//flow/block/block[1]/block[2]//text"/>
+ <eval expected="Fill 1" xpath="//pageSequence[5]/pageViewport[2]//flow/block/block[2]/block[2]//text"/>
+ <eval expected="Fill 2" xpath="//pageSequence[5]/pageViewport[2]//flow/block/block[3]/block[2]//text"/>
+ <eval expected="Fill 3" xpath="//pageSequence[5]/pageViewport[2]//flow/block/block[4]/block[2]//text"/>
+ <eval expected="Fill 4" xpath="//pageSequence[5]/pageViewport[2]//flow/block/block[5]/block[2]//text"/>
+ <eval expected="Fill 5" xpath="//pageSequence[5]/pageViewport[3]//flow/block/block[1]/block[2]//text"/>
+ <eval expected="Fill 6" xpath="//pageSequence[5]/pageViewport[3]//flow/block/block[2]/block[2]//text"/>
+ <eval expected="Fill 7" xpath="//pageSequence[5]/pageViewport[3]//flow/block/block[3]/block[2]//text"/>
+
+ <eval expected="Before page break" xpath="//pageSequence[6]/pageViewport[1]//flow/block[2]/block/block[2]//text"/>
+ <eval expected="After page break" xpath="//pageSequence[6]/pageViewport[2]//flow/block/block[1]/block[2]//text"/>
+ <eval expected="Fill 1" xpath="//pageSequence[6]/pageViewport[2]//flow/block/block[2]/block[2]//text"/>
+ <eval expected="Fill 2" xpath="//pageSequence[6]/pageViewport[2]//flow/block/block[3]/block[2]//text"/>
+ <eval expected="Fill 3" xpath="//pageSequence[6]/pageViewport[2]//flow/block/block[4]/block[2]//text"/>
+ <eval expected="Fill 4" xpath="//pageSequence[6]/pageViewport[2]//flow/block/block[5]/block[2]//text"/>
+ <eval expected="Fill 5" xpath="//pageSequence[6]/pageViewport[3]//flow/block/block[1]/block[2]//text"/>
+ <eval expected="Fill 6" xpath="//pageSequence[6]/pageViewport[3]//flow/block/block[2]/block[2]//text"/>
+ <eval expected="Fill 7" xpath="//pageSequence[6]/pageViewport[3]//flow/block/block[3]/block[2]//text"/>
+
+ </checks>
+</testcase>
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
new file mode 100644
index 000000000..956563e20
--- /dev/null
+++ b/test/layoutengine/standard-testcases/flow_changing-ipd_table-after-break.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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$ -->
+<testcase>
+ <info>
+ <p>
+ This test checks that a table immediately following a changing IPD break is handled properly.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="narrow"
+ page-height="220pt" page-width="320pt" margin="10pt">
+ <fo:region-body background-color="#F0F0F0"/>
+ </fo:simple-page-master>
+ <fo:simple-page-master master-name="wide"
+ page-height="220pt" page-width="420pt" margin="10pt">
+ <fo:region-body background-color="#F0F0F0"/>
+ </fo:simple-page-master>
+ <fo:page-sequence-master master-name="pages">
+ <fo:single-page-master-reference master-reference="narrow"/>
+ <fo:repeatable-page-master-reference master-reference="wide"/>
+ </fo:page-sequence-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="pages" font-size="8pt" line-height="10pt">
+ <fo:flow flow-name="xsl-region-body" text-align="justify">
+ <fo:block space-after="180pt">Before the table</fo:block>
+ <fo:table table-layout="fixed" width="100%" id="table">
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>
+ <fo:block id="before_break">Block before the page break.</fo:block>
+ <fo:block id="after_break">Block after the page break.</fo:block>
+ </fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ <fo:table table-layout="fixed" width="100%">
+ <fo:table-body>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>After the table 1</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ <fo:table-row>
+ <fo:table-cell>
+ <fo:block>After the table 2</fo:block>
+ </fo:table-cell>
+ </fo:table-row>
+ </fo:table-body>
+ </fo:table>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <eval expected="Block before the page break." xpath="//pageViewport[1]//flow/block[2]//text"/>
+ <eval expected="Block after the page break." xpath="//pageViewport[2]//flow/block[1]//text"/>
+ <eval expected="After the table 1" xpath="//pageViewport[2]//flow/block[2]/block[1]//text"/>
+ <eval expected="After the table 2" xpath="//pageViewport[2]//flow/block[2]/block[2]//text"/>
+ </checks>
+</testcase>