aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/fop
diff options
context:
space:
mode:
authorVincent Hennebert <vhennebert@apache.org>2012-05-28 16:16:23 +0000
committerVincent Hennebert <vhennebert@apache.org>2012-05-28 16:16:23 +0000
commitb0ea791fe191cd6f7593aa3ba8ca83ceacc2c1c0 (patch)
tree2786a2fbe4e86197f6ebfa06261cbf8672b967a8 /src/java/org/apache/fop
parent340025483a07776d56b655bbee3b402ba589a5b4 (diff)
parentd48e0e1f467c58a22c4d1b19591d4fa9d22aa8c6 (diff)
downloadxmlgraphics-fop-b0ea791fe191cd6f7593aa3ba8ca83ceacc2c1c0.tar.gz
xmlgraphics-fop-b0ea791fe191cd6f7593aa3ba8ca83ceacc2c1c0.zip
Merged changes from trunk up to revision 1343133
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_TrueTypeInPostScript@1343310 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/fop')
-rw-r--r--src/java/org/apache/fop/accessibility/DummyStructureTreeEventHandler.java2
-rw-r--r--src/java/org/apache/fop/accessibility/StructureTree2SAXEventAdapter.java10
-rw-r--r--src/java/org/apache/fop/accessibility/StructureTreeEventHandler.java3
-rw-r--r--src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java3
-rw-r--r--src/java/org/apache/fop/afp/AFPConstants.java11
-rw-r--r--src/java/org/apache/fop/afp/AFPGraphics2D.java22
-rw-r--r--src/java/org/apache/fop/afp/AFPPaintingState.java26
-rw-r--r--src/java/org/apache/fop/afp/fonts/CharacterSet.java8
-rw-r--r--src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java21
-rw-r--r--src/java/org/apache/fop/afp/fonts/CharacterSetType.java31
-rw-r--r--src/java/org/apache/fop/afp/fonts/CharactersetEncoder.java79
-rw-r--r--src/java/org/apache/fop/afp/fonts/FopCharacterSet.java4
-rw-r--r--src/java/org/apache/fop/afp/goca/GraphicsSetFractionalLineWidth.java69
-rw-r--r--src/java/org/apache/fop/afp/goca/GraphicsSetLineWidth.java4
-rw-r--r--src/java/org/apache/fop/afp/modca/AxisOrientation.java82
-rw-r--r--src/java/org/apache/fop/afp/modca/GraphicsObject.java18
-rw-r--r--src/java/org/apache/fop/afp/modca/IncludeObject.java69
-rw-r--r--src/java/org/apache/fop/afp/modca/Rotation.java46
-rw-r--r--src/java/org/apache/fop/afp/ptoca/PtocaBuilder.java115
-rw-r--r--src/java/org/apache/fop/afp/ptoca/PtocaConstants.java2
-rw-r--r--src/java/org/apache/fop/afp/ptoca/PtocaProducer.java4
-rw-r--r--src/java/org/apache/fop/afp/ptoca/TextDataInfoProducer.java2
-rw-r--r--src/java/org/apache/fop/afp/ptoca/TransparentDataControlSequence.java89
-rw-r--r--src/java/org/apache/fop/cli/CommandLineOptions.java7
-rw-r--r--src/java/org/apache/fop/fo/expr/AbsFunction.java17
-rw-r--r--src/java/org/apache/fop/fo/expr/BodyStartFunction.java17
-rw-r--r--src/java/org/apache/fop/fo/expr/CIELabColorFunction.java18
-rw-r--r--src/java/org/apache/fop/fo/expr/CMYKColorFunction.java (renamed from src/java/org/apache/fop/fo/expr/CMYKcolorFunction.java)12
-rw-r--r--src/java/org/apache/fop/fo/expr/CeilingFunction.java7
-rw-r--r--src/java/org/apache/fop/fo/expr/FloorFunction.java7
-rw-r--r--src/java/org/apache/fop/fo/expr/FromNearestSpecifiedValueFunction.java (renamed from src/java/org/apache/fop/fo/expr/NearestSpecPropFunction.java)39
-rw-r--r--src/java/org/apache/fop/fo/expr/FromParentFunction.java36
-rw-r--r--src/java/org/apache/fop/fo/expr/FromTableColumnFunction.java39
-rw-r--r--src/java/org/apache/fop/fo/expr/Function.java41
-rw-r--r--src/java/org/apache/fop/fo/expr/FunctionBase.java34
-rw-r--r--src/java/org/apache/fop/fo/expr/InheritedPropFunction.java37
-rw-r--r--src/java/org/apache/fop/fo/expr/LabelEndFunction.java18
-rw-r--r--src/java/org/apache/fop/fo/expr/MaxFunction.java17
-rw-r--r--src/java/org/apache/fop/fo/expr/MinFunction.java17
-rw-r--r--src/java/org/apache/fop/fo/expr/PropertyParser.java110
-rw-r--r--src/java/org/apache/fop/fo/expr/PropertyTokenizer.java2
-rw-r--r--src/java/org/apache/fop/fo/expr/ProportionalColumnWidthFunction.java (renamed from src/java/org/apache/fop/fo/expr/PPColWidthFunction.java)33
-rw-r--r--src/java/org/apache/fop/fo/expr/RGBColorFunction.java12
-rw-r--r--src/java/org/apache/fop/fo/expr/RGBICCColorFunction.java (renamed from src/java/org/apache/fop/fo/expr/ICCColorFunction.java)25
-rw-r--r--src/java/org/apache/fop/fo/expr/RGBNamedColorFunction.java (renamed from src/java/org/apache/fop/fo/expr/NamedColorFunction.java)16
-rw-r--r--src/java/org/apache/fop/fo/expr/RoundFunction.java8
-rw-r--r--src/java/org/apache/fop/fo/expr/SystemColorFunction.java5
-rw-r--r--src/java/org/apache/fop/fo/flow/table/ConditionalBorder.java13
-rw-r--r--src/java/org/apache/fop/fo/flow/table/Table.java85
-rw-r--r--src/java/org/apache/fop/fo/pagination/AbstractPageSequence.java15
-rw-r--r--src/java/org/apache/fop/fo/pagination/Flow.java14
-rw-r--r--src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java56
-rw-r--r--src/java/org/apache/fop/fo/properties/FontFamilyProperty.java30
-rw-r--r--src/java/org/apache/fop/fo/properties/SpaceProperty.java24
-rw-r--r--src/java/org/apache/fop/fonts/autodetect/FontFileFinder.java1
-rw-r--r--src/java/org/apache/fop/fonts/truetype/TTFFile.java12
-rw-r--r--src/java/org/apache/fop/fonts/type1/AFMParser.java53
-rw-r--r--src/java/org/apache/fop/layoutmgr/AbstractBreaker.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java3
-rw-r--r--src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java29
-rw-r--r--src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java8
-rw-r--r--src/java/org/apache/fop/layoutmgr/BlockLevelEventProducer.java23
-rw-r--r--src/java/org/apache/fop/layoutmgr/BlockLevelEventProducer.xml3
-rw-r--r--src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java35
-rw-r--r--src/java/org/apache/fop/layoutmgr/BreakOpportunity.java36
-rw-r--r--src/java/org/apache/fop/layoutmgr/BreakOpportunityHelper.java54
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/ImageLayout.java3
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java7
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java11
-rw-r--r--src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java17
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModel.java7
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/ColumnSetup.java9
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/RowPainter.java2
-rw-r--r--src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java7
-rw-r--r--src/java/org/apache/fop/pdf/PDFColorHandler.java7
-rw-r--r--src/java/org/apache/fop/pdf/PDFInfo.java55
-rw-r--r--src/java/org/apache/fop/pdf/PDFJavaScriptLaunchAction.java3
-rw-r--r--src/java/org/apache/fop/pdf/PDFNumber.java9
-rw-r--r--src/java/org/apache/fop/pdf/PDFStructElem.java1
-rw-r--r--src/java/org/apache/fop/render/afp/AFPCustomizable.java7
-rw-r--r--src/java/org/apache/fop/render/afp/AFPDocumentHandler.java5
-rw-r--r--src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java21
-rw-r--r--src/java/org/apache/fop/render/intermediate/IFParser.java12
-rw-r--r--src/java/org/apache/fop/render/intermediate/IFSerializer.java13
-rw-r--r--src/java/org/apache/fop/render/intermediate/IFStructureTreeBuilder.java4
-rw-r--r--src/java/org/apache/fop/render/intermediate/IFUtil.java7
-rw-r--r--src/java/org/apache/fop/render/pdf/FOToPDFRoleMap.java49
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java21
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java67
-rw-r--r--src/java/org/apache/fop/render/ps/PSDocumentHandler.java13
-rw-r--r--src/java/org/apache/fop/render/ps/PSPainter.java10
-rw-r--r--src/java/org/apache/fop/render/ps/extensions/PSExtensionElementMapping.java7
-rw-r--r--src/java/org/apache/fop/render/ps/extensions/PSExtensionHandler.java3
-rw-r--r--src/java/org/apache/fop/render/ps/extensions/PSPageTrailerCodeBefore.java50
-rw-r--r--src/java/org/apache/fop/render/ps/extensions/PSPageTrailerCodeBeforeElement.java55
-rw-r--r--src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfSection.java7
-rw-r--r--src/java/org/apache/fop/render/txt/TXTRenderer.java12
-rw-r--r--src/java/org/apache/fop/render/xml/XMLRenderer.java26
-rw-r--r--src/java/org/apache/fop/svg/PDFGraphics2D.java4
-rw-r--r--src/java/org/apache/fop/util/DecimalFormatCache.java77
100 files changed, 1408 insertions, 990 deletions
diff --git a/src/java/org/apache/fop/accessibility/DummyStructureTreeEventHandler.java b/src/java/org/apache/fop/accessibility/DummyStructureTreeEventHandler.java
index 66eaece89..c63c721e5 100644
--- a/src/java/org/apache/fop/accessibility/DummyStructureTreeEventHandler.java
+++ b/src/java/org/apache/fop/accessibility/DummyStructureTreeEventHandler.java
@@ -34,7 +34,7 @@ public final class DummyStructureTreeEventHandler implements StructureTreeEventH
private DummyStructureTreeEventHandler() { }
/** {@inheritDoc} */
- public void startPageSequence(Locale locale) {
+ public void startPageSequence(Locale locale, String role) {
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/accessibility/StructureTree2SAXEventAdapter.java b/src/java/org/apache/fop/accessibility/StructureTree2SAXEventAdapter.java
index 79c589f9b..7a375ef20 100644
--- a/src/java/org/apache/fop/accessibility/StructureTree2SAXEventAdapter.java
+++ b/src/java/org/apache/fop/accessibility/StructureTree2SAXEventAdapter.java
@@ -30,6 +30,7 @@ import org.apache.fop.fo.FOElementMapping;
import org.apache.fop.fo.extensions.ExtensionElementMapping;
import org.apache.fop.fo.extensions.InternalElementMapping;
import org.apache.fop.render.intermediate.IFConstants;
+import org.apache.fop.util.XMLConstants;
/**
* Converts structure tree events to SAX events.
@@ -52,16 +53,19 @@ public final class StructureTree2SAXEventAdapter implements StructureTreeEventHa
}
/** {@inheritDoc} */
- public void startPageSequence(Locale locale) {
+ public void startPageSequence(Locale locale, String role) {
try {
-
+ AttributesImpl attributes = new AttributesImpl();
+ if (role != null) {
+ attributes.addAttribute("", "type", "type", XMLConstants.CDATA, role);
+ }
contentHandler.startPrefixMapping(
InternalElementMapping.STANDARD_PREFIX, InternalElementMapping.URI);
contentHandler.startPrefixMapping(
ExtensionElementMapping.STANDARD_PREFIX, ExtensionElementMapping.URI);
contentHandler.startElement(IFConstants.NAMESPACE,
IFConstants.EL_STRUCTURE_TREE, IFConstants.EL_STRUCTURE_TREE,
- new AttributesImpl());
+ attributes);
} catch (SAXException e) {
throw new RuntimeException(e);
}
diff --git a/src/java/org/apache/fop/accessibility/StructureTreeEventHandler.java b/src/java/org/apache/fop/accessibility/StructureTreeEventHandler.java
index 4b94d61f1..46b724626 100644
--- a/src/java/org/apache/fop/accessibility/StructureTreeEventHandler.java
+++ b/src/java/org/apache/fop/accessibility/StructureTreeEventHandler.java
@@ -34,8 +34,9 @@ public interface StructureTreeEventHandler {
* Starts a page sequence structure tree node.
*
* @param locale The locale of the page sequence
+ * @param role the value of the role property. May be null.
*/
- void startPageSequence(Locale locale);
+ void startPageSequence(Locale locale, String role);
/**
* Starts a structure tree node.
diff --git a/src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java b/src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java
index 957f40870..51f7f2bed 100644
--- a/src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java
+++ b/src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java
@@ -89,7 +89,8 @@ class StructureTreeEventTrigger extends FOEventHandler {
locale = new Locale(pageSeq.getLanguage());
}
}
- structureTreeEventHandler.startPageSequence(locale);
+ String role = pageSeq.getCommonAccessibility().getRole();
+ structureTreeEventHandler.startPageSequence(locale, role);
}
@Override
diff --git a/src/java/org/apache/fop/afp/AFPConstants.java b/src/java/org/apache/fop/afp/AFPConstants.java
index 6b26c18fd..49b671e66 100644
--- a/src/java/org/apache/fop/afp/AFPConstants.java
+++ b/src/java/org/apache/fop/afp/AFPConstants.java
@@ -50,4 +50,15 @@ public interface AFPConstants {
* 72dpi in millipoints
*/
int DPI_72_MPTS = DPI_72 * 1000;
+
+ /**
+ * The line width is set as a multiplier of a default line with; the width of the default
+ * line width is implementation defined, which probably means different devices use different
+ * actual widths; this means that the source line width (as specified in, say, a SVG line
+ * element) needs to be corrected by a fudge factor that depends on the output device so that
+ * the final output (print to paper, screen viewer) looks as intended.
+ */
+ float LINE_WIDTH_CORRECTION = 2.5f;
+
}
+
diff --git a/src/java/org/apache/fop/afp/AFPGraphics2D.java b/src/java/org/apache/fop/afp/AFPGraphics2D.java
index 41be79160..e9a269ac4 100644
--- a/src/java/org/apache/fop/afp/AFPGraphics2D.java
+++ b/src/java/org/apache/fop/afp/AFPGraphics2D.java
@@ -263,14 +263,6 @@ public class AFPGraphics2D extends AbstractGraphics2D implements NativeImageHand
return length * factor;
}
- /** IBM's AFP Workbench paints lines that are wider than expected. We correct manually. */
- private static final double GUESSED_WIDTH_CORRECTION = 1.7;
-
- private static final double SPEC_NORMAL_LINE_WIDTH = UnitConv.in2pt(0.01); //"approx" 0.01 inch
- private static final double NORMAL_LINE_WIDTH
- = SPEC_NORMAL_LINE_WIDTH * GUESSED_WIDTH_CORRECTION;
-
-
/**
* Apply the stroke to the AFP graphics object.
* This takes the java stroke and outputs the appropriate settings
@@ -282,17 +274,11 @@ public class AFPGraphics2D extends AbstractGraphics2D implements NativeImageHand
if (stroke instanceof BasicStroke) {
BasicStroke basicStroke = (BasicStroke) stroke;
- // set line width
+ // set line width and correct it; NOTE: apparently we need to correct the width so that the
+ // output looks OK since the default with depends on the output device
float lineWidth = basicStroke.getLineWidth();
- if (false) {
- //Old approach. Retained until verified problems with 1440 resolution
- graphicsObj.setLineWidth(Math.round(lineWidth / 2));
- } else {
- double absoluteLineWidth = lineWidth * Math.abs(getTransform().getScaleY());
- double multiplier = absoluteLineWidth / NORMAL_LINE_WIDTH;
- graphicsObj.setLineWidth((int)Math.round(multiplier));
- //TODO Use GSFLW instead of GSLW for higher accuracy?
- }
+ float correction = paintingState.getLineWidthCorrection();
+ graphicsObj.setLineWidth(lineWidth * correction);
//No line join, miter limit and end cap support in GOCA. :-(
diff --git a/src/java/org/apache/fop/afp/AFPPaintingState.java b/src/java/org/apache/fop/afp/AFPPaintingState.java
index 7e6b940a5..ea2ebe475 100644
--- a/src/java/org/apache/fop/afp/AFPPaintingState.java
+++ b/src/java/org/apache/fop/afp/AFPPaintingState.java
@@ -79,6 +79,12 @@ public class AFPPaintingState extends org.apache.fop.util.AbstractPaintingState
/** the output resolution */
private int resolution = 240; // 240 dpi
+ /**
+ * A configurable value to correct the line width so that the output matches the expected. Different
+ * devices may need different values.
+ */
+ private float lineWidthCorrection = AFPConstants.LINE_WIDTH_CORRECTION;
+
/** determines whether GOCA is enabled or disabled */
private boolean gocaEnabled = true;
/** determines whether to stroke text in GOCA mode or to use text operators where possible */
@@ -323,6 +329,18 @@ public class AFPPaintingState extends org.apache.fop.util.AbstractPaintingState
}
/**
+ * Sets the line width correction
+ *
+ * @param correction the line width multiplying factor correction
+ */
+ public void setLineWidthCorrection(float correction) {
+ if (log.isDebugEnabled()) {
+ log.debug("line width correction set to: " + correction);
+ }
+ this.lineWidthCorrection = correction;
+ }
+
+ /**
* Returns the output/device resolution.
*
* @return the resolution in dpi
@@ -332,6 +350,14 @@ public class AFPPaintingState extends org.apache.fop.util.AbstractPaintingState
}
/**
+ * Returns the line width correction.
+ * @return the correction
+ */
+ public float getLineWidthCorrection() {
+ return this.lineWidthCorrection;
+ }
+
+ /**
* Controls whether GOCA is enabled or disabled.
* @param enabled true if GOCA is enabled, false if it is disabled
*/
diff --git a/src/java/org/apache/fop/afp/fonts/CharacterSet.java b/src/java/org/apache/fop/afp/fonts/CharacterSet.java
index 341abde0b..fad5e95e6 100644
--- a/src/java/org/apache/fop/afp/fonts/CharacterSet.java
+++ b/src/java/org/apache/fop/afp/fonts/CharacterSet.java
@@ -94,12 +94,12 @@ public class CharacterSet {
*
* @param codePage the code page identifier
* @param encoding the encoding of the font
- * @param isEBDCS if this is an EBCDIC double byte character set.
+ * @param charsetType the type of the characterset
* @param name the character set name
* @param accessor the resource accessor to load resource with
* @param eventProducer for handling AFP related events
*/
- CharacterSet(String codePage, String encoding, boolean isEBDCS, String name,
+ CharacterSet(String codePage, String encoding, CharacterSetType charsetType, String name,
ResourceAccessor accessor, AFPEventProducer eventProducer) {
if (name.length() > MAX_NAME_LEN) {
String msg = "Character set name '" + name + "' must be a maximum of "
@@ -115,7 +115,7 @@ public class CharacterSet {
}
this.codePage = codePage;
this.encoding = encoding;
- this.encoder = CharactersetEncoder.newInstance(encoding, isEBDCS);
+ this.encoder = CharactersetEncoder.newInstance(encoding, charsetType);
this.accessor = accessor;
this.characterSetOrientations = new HashMap<String, CharacterSetOrientation>(4);
@@ -306,7 +306,7 @@ public class CharacterSet {
*/
private CharacterSetOrientation getCharacterSetOrientation() {
CharacterSetOrientation c
- = (CharacterSetOrientation) characterSetOrientations.get(currentOrientation);
+ = characterSetOrientations.get(currentOrientation);
return c;
}
diff --git a/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java b/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java
index 4988bb949..7da2d71ca 100644
--- a/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java
+++ b/src/java/org/apache/fop/afp/fonts/CharacterSetBuilder.java
@@ -190,10 +190,10 @@ public abstract class CharacterSetBuilder {
* @return CharacterSet object
* @throws IOException if an I/O error occurs
*/
- public CharacterSet build(String characterSetName, String codePageName, String encoding,
+ public CharacterSet buildSBCS(String characterSetName, String codePageName, String encoding,
ResourceAccessor accessor, AFPEventProducer eventProducer) throws IOException {
- return processFont(characterSetName, codePageName, encoding, false, accessor,
- eventProducer);
+ return processFont(characterSetName, codePageName, encoding, CharacterSetType.SINGLE_BYTE,
+ accessor, eventProducer);
}
/**
@@ -204,16 +204,16 @@ public abstract class CharacterSetBuilder {
* @param characterSetName name of the characterset
* @param codePageName name of the code page file
* @param encoding encoding name
- * @param isEDBCS if this is an EBCDIC double byte character set (DBCS)
+ * @param charsetType the characterset type
* @param accessor used to load codepage and characterset
* @param eventProducer for handling AFP related events
* @return CharacterSet object
* @throws IOException if an I/O error occurs
*/
public CharacterSet buildDBCS(String characterSetName, String codePageName, String encoding,
- boolean isEDBCS, ResourceAccessor accessor, AFPEventProducer eventProducer)
+ CharacterSetType charsetType, ResourceAccessor accessor, AFPEventProducer eventProducer)
throws IOException {
- return processFont(characterSetName, codePageName, encoding, isEDBCS, accessor,
+ return processFont(characterSetName, codePageName, encoding, charsetType, accessor,
eventProducer);
}
@@ -236,7 +236,7 @@ public abstract class CharacterSetBuilder {
}
private CharacterSet processFont(String characterSetName, String codePageName, String encoding,
- boolean isEDBCS, ResourceAccessor accessor, AFPEventProducer eventProducer)
+ CharacterSetType charsetType, ResourceAccessor accessor, AFPEventProducer eventProducer)
throws IOException {
// check for cached version of the characterset
String descriptor = characterSetName + "_" + encoding + "_" + codePageName;
@@ -247,7 +247,7 @@ public abstract class CharacterSetBuilder {
}
// characterset not in the cache, so recreating
- characterSet = new CharacterSet(codePageName, encoding, isEDBCS, characterSetName,
+ characterSet = new CharacterSet(codePageName, encoding, charsetType, characterSetName,
accessor, eventProducer);
InputStream inputStream = null;
@@ -465,8 +465,7 @@ public abstract class CharacterSetBuilder {
}
}
- return (CharacterSetOrientation[]) orientations
- .toArray(EMPTY_CSO_ARRAY);
+ return orientations.toArray(EMPTY_CSO_ARRAY);
}
/**
@@ -570,7 +569,7 @@ public abstract class CharacterSetBuilder {
String gcgiString = new String(gcgid, AFPConstants.EBCIDIC_ENCODING);
- String idx = (String) codepage.get(gcgiString);
+ String idx = codepage.get(gcgiString);
if (idx != null) {
diff --git a/src/java/org/apache/fop/afp/fonts/CharacterSetType.java b/src/java/org/apache/fop/afp/fonts/CharacterSetType.java
new file mode 100644
index 000000000..8eaaa089b
--- /dev/null
+++ b/src/java/org/apache/fop/afp/fonts/CharacterSetType.java
@@ -0,0 +1,31 @@
+/*
+ * 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.fonts;
+
+/**
+ * An enumeration of AFP characterset types.
+ */
+public enum CharacterSetType {
+ /** Double byte character sets; these do NOT have the shift-in;shift-out operators */
+ DOUBLE_BYTE,
+ /** Double byte character sets; these can have the shift-in;shift-out operators */
+ DOUBLE_BYTE_LINE_DATA,
+ SINGLE_BYTE;
+}
diff --git a/src/java/org/apache/fop/afp/fonts/CharactersetEncoder.java b/src/java/org/apache/fop/afp/fonts/CharactersetEncoder.java
index 229123a82..f101bdab4 100644
--- a/src/java/org/apache/fop/afp/fonts/CharactersetEncoder.java
+++ b/src/java/org/apache/fop/afp/fonts/CharactersetEncoder.java
@@ -82,13 +82,12 @@ public abstract class CharactersetEncoder {
*
* @param chars the character sequence
* @param encoding the encoding type
- * @param isEDBCS if this encoding represents a double-byte character set
* @return encoded data
* @throws CharacterCodingException if encoding fails
*/
- public static EncodedChars encodeSBCS(CharSequence chars, String encoding, boolean isEDBCS)
+ public static EncodedChars encodeSBCS(CharSequence chars, String encoding)
throws CharacterCodingException {
- CharactersetEncoder encoder = newInstance(encoding, isEDBCS);
+ CharactersetEncoder encoder = newInstance(encoding, CharacterSetType.SINGLE_BYTE);
return encoder.encode(chars);
}
@@ -98,16 +97,16 @@ public abstract class CharactersetEncoder {
* sequence it will return its EBCDIC code-point, however, the "Shift In - Shift Out" operators
* are removed from the sequence of bytes. These are only used in Line Data.
*/
- private static final class EbcdicDoubleByteEncoder extends CharactersetEncoder {
- private EbcdicDoubleByteEncoder(String encoding) {
+ private static final class EbcdicDoubleByteLineDataEncoder extends CharactersetEncoder {
+ private EbcdicDoubleByteLineDataEncoder(String encoding) {
super(encoding);
}
@Override
EncodedChars getEncodedChars(byte[] byteArray, int length) {
if (byteArray[0] == 0x0E && byteArray[length - 1] == 0x0F) {
- return new EncodedChars(byteArray, 1, length - 2);
+ return new EncodedChars(byteArray, 1, length - 2, true);
}
- return new EncodedChars(byteArray);
+ return new EncodedChars(byteArray, true);
}
}
@@ -117,13 +116,16 @@ public abstract class CharactersetEncoder {
* byte character sets (DBCS).
*/
private static final class DefaultEncoder extends CharactersetEncoder {
- private DefaultEncoder(String encoding) {
+ private final boolean isDBCS;
+
+ private DefaultEncoder(String encoding, boolean isDBCS) {
super(encoding);
+ this.isDBCS = isDBCS;
}
@Override
EncodedChars getEncodedChars(byte[] byteArray, int length) {
- return new EncodedChars(byteArray);
+ return new EncodedChars(byteArray, isDBCS);
}
}
@@ -134,47 +136,40 @@ public abstract class CharactersetEncoder {
* @param isEbcdicDBCS whether or not this wraps a double-byte EBCDIC code page.
* @return the CharactersetEncoder
*/
- static CharactersetEncoder newInstance(String encoding, boolean isEbcdicDBCS) {
- if (isEbcdicDBCS) {
- return new EbcdicDoubleByteEncoder(encoding);
- } else {
- return new DefaultEncoder(encoding);
+ static CharactersetEncoder newInstance(String encoding, CharacterSetType charsetType) {
+ switch (charsetType) {
+ case DOUBLE_BYTE_LINE_DATA:
+ return new EbcdicDoubleByteLineDataEncoder(encoding);
+ case DOUBLE_BYTE:
+ return new DefaultEncoder(encoding, true);
+ default:
+ return new DefaultEncoder(encoding, false);
}
}
/**
* A container for encoded character bytes
*/
- public static final class EncodedChars {
+ // CSOFF: FinalClass - disabling "final" modifier so that this class can be mocked
+ public static class EncodedChars {
private final byte[] bytes;
-
private final int offset;
-
private final int length;
+ private final boolean isDBCS;
- private EncodedChars(byte[] bytes, int offset, int length) {
- if (offset < 0) {
- throw new IllegalArgumentException();
- }
-
- if (length < 0) {
+ private EncodedChars(byte[] bytes, int offset, int length, boolean isDBCS) {
+ if (offset < 0 || length < 0 || offset + length > bytes.length) {
throw new IllegalArgumentException();
}
-
- if (offset + length > bytes.length) {
- throw new IllegalArgumentException();
- }
-
this.bytes = bytes;
-
this.offset = offset;
-
this.length = length;
+ this.isDBCS = isDBCS;
}
- private EncodedChars(byte[] bytes) {
- this(bytes, 0, bytes.length);
+ private EncodedChars(byte[] bytes, boolean isDBCS) {
+ this(bytes, 0, bytes.length, isDBCS);
}
/**
@@ -186,18 +181,9 @@ public abstract class CharactersetEncoder {
* @throws IOException if an I/O error occurs
*/
public void writeTo(OutputStream out, int offset, int length) throws IOException {
- if (offset < 0) {
+ if (offset < 0 || length < 0 || offset + length > bytes.length) {
throw new IllegalArgumentException();
}
-
- if (length < 0) {
- throw new IllegalArgumentException();
- }
-
- if (offset + length > this.length) {
- throw new IllegalArgumentException();
- }
-
out.write(bytes, this.offset + offset, length);
}
@@ -211,6 +197,15 @@ public abstract class CharactersetEncoder {
}
/**
+ * Indicates whether or not the EncodedChars object wraps double byte characters.
+ *
+ * @return true if the wrapped characters are double byte (DBCSs)
+ */
+ public boolean isDBCS() {
+ return isDBCS;
+ }
+
+ /**
* The bytes
*
* @return the bytes
diff --git a/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java b/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java
index f949976ba..f83c38621 100644
--- a/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java
+++ b/src/java/org/apache/fop/afp/fonts/FopCharacterSet.java
@@ -42,7 +42,8 @@ public class FopCharacterSet extends CharacterSet {
*/
public FopCharacterSet(String codePage, String encoding, String name, Typeface charSet,
AFPEventProducer eventProducer) {
- super(codePage, encoding, false, name, (ResourceAccessor) null, eventProducer);
+ super(codePage, encoding, CharacterSetType.SINGLE_BYTE, name, (ResourceAccessor) null,
+ eventProducer);
this.charSet = charSet;
}
@@ -132,5 +133,4 @@ public class FopCharacterSet extends CharacterSet {
public char mapChar(char c) {
return charSet.mapChar(c);
}
-
}
diff --git a/src/java/org/apache/fop/afp/goca/GraphicsSetFractionalLineWidth.java b/src/java/org/apache/fop/afp/goca/GraphicsSetFractionalLineWidth.java
new file mode 100644
index 000000000..529001676
--- /dev/null
+++ b/src/java/org/apache/fop/afp/goca/GraphicsSetFractionalLineWidth.java
@@ -0,0 +1,69 @@
+/*
+ * 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.goca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Sets the line width to use when stroking GOCA shapes (structured fields)
+ */
+public class GraphicsSetFractionalLineWidth extends AbstractGraphicsDrawingOrder {
+
+ /** line width multiplier */
+ private final float multiplier;
+
+ /**
+ * Main constructor
+ *
+ * @param multiplier the line width multiplier
+ */
+ public GraphicsSetFractionalLineWidth(float multiplier) {
+ this.multiplier = multiplier;
+ }
+
+ /** {@inheritDoc} */
+ public int getDataLength() {
+ return 4;
+ }
+
+ /** {@inheritDoc} */
+ public void writeToStream(OutputStream os) throws IOException {
+ int integral = (int) multiplier;
+ int fractional = (int) ((multiplier - (float) integral) * 256);
+ byte[] data = new byte[] {
+ getOrderCode(), // GSLW order code
+ 0x02, // two bytes next
+ (byte) integral, // integral line with
+ (byte) fractional // and fractional
+ };
+ os.write(data);
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return "GraphicsSetFractionalLineWidth{multiplier=" + multiplier + "}";
+ }
+
+ /** {@inheritDoc} */
+ byte getOrderCode() {
+ return 0x11;
+ }
+}
diff --git a/src/java/org/apache/fop/afp/goca/GraphicsSetLineWidth.java b/src/java/org/apache/fop/afp/goca/GraphicsSetLineWidth.java
index 96b54f3cd..ca8812f14 100644
--- a/src/java/org/apache/fop/afp/goca/GraphicsSetLineWidth.java
+++ b/src/java/org/apache/fop/afp/goca/GraphicsSetLineWidth.java
@@ -28,7 +28,7 @@ import java.io.OutputStream;
public class GraphicsSetLineWidth extends AbstractGraphicsDrawingOrder {
/** line width multiplier */
- private int multiplier = 1;
+ private final int multiplier;
/**
* Main constructor
@@ -48,7 +48,7 @@ public class GraphicsSetLineWidth extends AbstractGraphicsDrawingOrder {
public void writeToStream(OutputStream os) throws IOException {
byte[] data = new byte[] {
getOrderCode(), // GSLW order code
- (byte)multiplier // MH (line-width)
+ (byte) multiplier // MH (line-width)
};
os.write(data);
}
diff --git a/src/java/org/apache/fop/afp/modca/AxisOrientation.java b/src/java/org/apache/fop/afp/modca/AxisOrientation.java
new file mode 100644
index 000000000..a017fe5e3
--- /dev/null
+++ b/src/java/org/apache/fop/afp/modca/AxisOrientation.java
@@ -0,0 +1,82 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Represents the 4 bytes that specify the axis-area rotation reference coordinate system
+ */
+public enum AxisOrientation {
+
+ RIGHT_HANDED_0(Rotation.ROTATION_0, Rotation.ROTATION_90),
+ RIGHT_HANDED_90(Rotation.ROTATION_90, Rotation.ROTATION_180),
+ RIGHT_HANDED_180(Rotation.ROTATION_180, Rotation.ROTATION_270),
+ RIGHT_HANDED_270(Rotation.ROTATION_270, Rotation.ROTATION_0);
+
+ /**
+ * The object area's X-axis rotation from the X axis of the reference coordinate system
+ */
+ private final Rotation xoaOrent;
+ /**
+ * The object area's Y-axis rotation from the Y axis of the reference coordinate system
+ */
+ private final Rotation yoaOrent;
+
+ public void writeTo(byte[] out, int offset) {
+ xoaOrent.writeTo(out, offset);
+ yoaOrent.writeTo(out, offset + 2);
+ }
+
+ private AxisOrientation(Rotation xoaOrent, Rotation yoaOrent) {
+ this.xoaOrent = xoaOrent;
+ this.yoaOrent = yoaOrent;
+ }
+
+ /**
+ * Writes the axis orientation area bytes to the output stream.
+ *
+ * @param stream the output stream to write to
+ * @throws IOException if an I/O error occurs
+ */
+ public void writeTo(OutputStream stream) throws IOException {
+ byte[] data = new byte[4];
+ writeTo(data, 0);
+ stream.write(data);
+ }
+
+ /**
+ * Gets the right-handed axis orientation object for a given orientation in degrees.
+ *
+ * @param orientation the orientation in degrees
+ * @return the {@link AxisOrientation} object
+ */
+ public static AxisOrientation getRightHandedAxisOrientationFor(int orientation) {
+ switch (orientation) {
+ case 0: return RIGHT_HANDED_0;
+ case 90: return RIGHT_HANDED_90;
+ case 180: return RIGHT_HANDED_180;
+ case 270: return RIGHT_HANDED_270;
+ default: throw new IllegalArgumentException(
+ "The orientation must be one of the values 0, 90, 180, 270");
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/afp/modca/GraphicsObject.java b/src/java/org/apache/fop/afp/modca/GraphicsObject.java
index 9b870767e..7284c69f3 100644
--- a/src/java/org/apache/fop/afp/modca/GraphicsObject.java
+++ b/src/java/org/apache/fop/afp/modca/GraphicsObject.java
@@ -48,6 +48,7 @@ import org.apache.fop.afp.goca.GraphicsLine;
import org.apache.fop.afp.goca.GraphicsSetArcParameters;
import org.apache.fop.afp.goca.GraphicsSetCharacterSet;
import org.apache.fop.afp.goca.GraphicsSetCurrentPosition;
+import org.apache.fop.afp.goca.GraphicsSetFractionalLineWidth;
import org.apache.fop.afp.goca.GraphicsSetLineType;
import org.apache.fop.afp.goca.GraphicsSetLineWidth;
import org.apache.fop.afp.goca.GraphicsSetPatternSymbol;
@@ -182,8 +183,21 @@ public class GraphicsObject extends AbstractDataObject {
* @param lineWidth the line width multiplier
*/
public void setLineWidth(int lineWidth) {
- if (lineWidth != graphicsState.lineWidth) {
+ if ((float) lineWidth != graphicsState.lineWidth) {
addObject(new GraphicsSetLineWidth(lineWidth));
+ graphicsState.lineWidth = (float) lineWidth;
+ }
+ }
+
+ /**
+ * Sets the line width
+ *
+ * @param lineWidth the line width multiplier
+ */
+ public void setLineWidth(float lineWidth) {
+ float epsilon = Float.intBitsToFloat ( 0x00800000 ); // Float.MIN_NORMAL (JDK1.6)
+ if ( Math.abs ( graphicsState.lineWidth - lineWidth ) > epsilon ) {
+ addObject(new GraphicsSetFractionalLineWidth(lineWidth));
graphicsState.lineWidth = lineWidth;
}
}
@@ -414,7 +428,7 @@ public class GraphicsObject extends AbstractDataObject {
private byte lineType;
/** the current line width */
- private int lineWidth;
+ private float lineWidth;
/** the current fill pattern */
private byte patternSymbol;
diff --git a/src/java/org/apache/fop/afp/modca/IncludeObject.java b/src/java/org/apache/fop/afp/modca/IncludeObject.java
index 68fa72688..4dca1b357 100644
--- a/src/java/org/apache/fop/afp/modca/IncludeObject.java
+++ b/src/java/org/apache/fop/afp/modca/IncludeObject.java
@@ -67,7 +67,7 @@ public class IncludeObject extends AbstractNamedAFPObject {
private int yoaOset = 0;
/** the orientation of the referenced object */
- private ObjectAreaRotation oaOrent = ObjectAreaRotation.RIGHT_HANDED_0;
+ private AxisOrientation oaOrent = AxisOrientation.RIGHT_HANDED_0;
/** the X-axis origin defined in the object */
private int xocaOset = -1;
@@ -93,7 +93,7 @@ public class IncludeObject extends AbstractNamedAFPObject {
* The orientation (0,90, 180, 270)
*/
public void setObjectAreaOrientation(int orientation) {
- this.oaOrent = ObjectAreaRotation.objectAreaRotationFor(orientation);
+ this.oaOrent = AxisOrientation.getRightHandedAxisOrientationFor(orientation);
}
/**
@@ -234,69 +234,4 @@ public class IncludeObject extends AbstractNamedAFPObject {
addTriplet(new MeasurementUnitsTriplet(xRes, xRes));
}
- /**
- * Represents the 4 bytes that specify the area rotation reference coordinate system
- *
- */
- private enum ObjectAreaRotation {
-
- RIGHT_HANDED_0(Rotation.ROTATION_0, Rotation.ROTATION_90),
- RIGHT_HANDED_90(Rotation.ROTATION_90, Rotation.ROTATION_180),
- RIGHT_HANDED_180(Rotation.ROTATION_180, Rotation.ROTATION_270),
- RIGHT_HANDED_270(Rotation.ROTATION_270, Rotation.ROTATION_0);
-
- /**
- * The object area's X-axis rotation from the X axis of the reference coordinate system
- */
- private final Rotation xoaOrent;
- /**
- * The object area's Y-axis rotation from the Y axis of the reference coordinate system
- */
- private final Rotation yoaOrent;
-
- public void writeTo(byte[] out, int offset) {
- xoaOrent.writeTo(out, offset);
- yoaOrent.writeTo(out, offset + 2);
- }
-
- ObjectAreaRotation(Rotation xoaOrent, Rotation yoaOrent) {
- this.xoaOrent = xoaOrent;
- this.yoaOrent = yoaOrent;
- }
-
- private static ObjectAreaRotation objectAreaRotationFor(int orientation) {
- switch (orientation) {
- case 0: return RIGHT_HANDED_0;
- case 90: return RIGHT_HANDED_90;
- case 180: return RIGHT_HANDED_180;
- case 270: return RIGHT_HANDED_270;
- default: throw new IllegalArgumentException(
- "The orientation must be one of the values 0, 90, 180, 270");
- }
- }
- }
-
- /**
- * Represents a rotation value
- *
- */
- private enum Rotation {
-
- ROTATION_0(0),
- ROTATION_90(0x2D),
- ROTATION_180(0x5A),
- ROTATION_270(0x87);
-
- private final byte firstByte;
-
- public void writeTo(byte[] out, int offset) {
- out[offset] = firstByte;
- out[offset + 1] = (byte)0;
- }
-
- Rotation(int firstByte) {
- this.firstByte = (byte) firstByte;
- }
- }
-
}
diff --git a/src/java/org/apache/fop/afp/modca/Rotation.java b/src/java/org/apache/fop/afp/modca/Rotation.java
new file mode 100644
index 000000000..a307e1cf9
--- /dev/null
+++ b/src/java/org/apache/fop/afp/modca/Rotation.java
@@ -0,0 +1,46 @@
+/*
+ * 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;
+
+/**
+ * Represents a rotation value
+ *
+ */
+public enum Rotation {
+ ROTATION_0(0),
+ ROTATION_90(0x2D),
+ ROTATION_180(0x5A),
+ ROTATION_270(0x87);
+
+ private final byte firstByte;
+
+ public void writeTo(byte[] out, int offset) {
+ out[offset] = firstByte;
+ out[offset + 1] = (byte)0;
+ }
+
+ private Rotation(int firstByte) {
+ this.firstByte = (byte) firstByte;
+ }
+
+ public byte getByte() {
+ return firstByte;
+ }
+}
diff --git a/src/java/org/apache/fop/afp/ptoca/PtocaBuilder.java b/src/java/org/apache/fop/afp/ptoca/PtocaBuilder.java
index 1ea63c7f9..befd2cc1a 100644
--- a/src/java/org/apache/fop/afp/ptoca/PtocaBuilder.java
+++ b/src/java/org/apache/fop/afp/ptoca/PtocaBuilder.java
@@ -31,6 +31,8 @@ import org.apache.xmlgraphics.java2d.color.ColorUtil;
import org.apache.xmlgraphics.java2d.color.ColorWithAlternatives;
import org.apache.fop.afp.fonts.CharactersetEncoder.EncodedChars;
+import org.apache.fop.afp.modca.AxisOrientation;
+import org.apache.fop.afp.ptoca.TransparentDataControlSequence.TransparentData;
/**
* Generator class for PTOCA data structures.
@@ -87,8 +89,10 @@ public abstract class PtocaBuilder implements PtocaConstants {
baout.writeTo(out);
}
- private void writeByte(int data) {
- baout.write(data);
+ private void writeBytes(int... data) {
+ for (int d : data) {
+ baout.write(d);
+ }
}
private void writeShort(int data) {
@@ -123,7 +127,7 @@ public abstract class PtocaBuilder implements PtocaConstants {
}
newControlSequence();
- writeByte(font);
+ writeBytes(font);
commit(chained(SCFL));
}
@@ -187,26 +191,11 @@ public abstract class PtocaBuilder implements PtocaConstants {
* @throws IOException if an I/O error occurs
*/
public void addTransparentData(EncodedChars encodedChars) throws IOException {
-
- // data size greater than TRANSPARENT_MAX_SIZE, so slice
- int numTransData = encodedChars.getLength() / TRANSPARENT_DATA_MAX_SIZE;
- int currIndex = 0;
- for (int transDataCnt = 0; transDataCnt < numTransData; transDataCnt++) {
- addTransparentDataChunk(encodedChars, currIndex, TRANSPARENT_DATA_MAX_SIZE);
- currIndex += TRANSPARENT_DATA_MAX_SIZE;
+ for (TransparentData trn : new TransparentDataControlSequence(encodedChars)) {
+ newControlSequence();
+ trn.writeTo(baout);
+ commit(chained(TRN));
}
- int left = encodedChars.getLength() - currIndex;
- addTransparentDataChunk(encodedChars, currIndex, left);
-
- }
-
-
-
- private void addTransparentDataChunk(EncodedChars encodedChars, int offset, int length)
- throws IOException {
- newControlSequence();
- encodedChars.writeTo(baout, offset, length);
- commit(chained(TRN));
}
/**
@@ -222,7 +211,7 @@ public abstract class PtocaBuilder implements PtocaConstants {
newControlSequence();
writeShort(length); // Rule length
writeShort(width); // Rule width
- writeByte(0); // Rule width fraction is always null. enough?
+ writeBytes(0); // Rule width fraction is always null. enough?
commit(chained(DBR));
}
@@ -239,7 +228,7 @@ public abstract class PtocaBuilder implements PtocaConstants {
newControlSequence();
writeShort(length); // Rule length
writeShort(width); // Rule width
- writeByte(0); // Rule width fraction is always null. enough?
+ writeBytes(0); // Rule width fraction is always null. enough?
commit(chained(DIR));
}
@@ -260,32 +249,7 @@ public abstract class PtocaBuilder implements PtocaConstants {
return;
}
newControlSequence();
- switch (orientation) {
- case 90:
- writeByte(0x2D);
- writeByte(0x00);
- writeByte(0x5A);
- writeByte(0x00);
- break;
- case 180:
- writeByte(0x5A);
- writeByte(0x00);
- writeByte(0x87);
- writeByte(0x00);
- break;
- case 270:
- writeByte(0x87);
- writeByte(0x00);
- writeByte(0x00);
- writeByte(0x00);
- break;
- default:
- writeByte(0x00);
- writeByte(0x00);
- writeByte(0x2D);
- writeByte(0x00);
- break;
- }
+ AxisOrientation.getRightHandedAxisOrientationFor(orientation).writeTo(baout);
commit(chained(STO));
this.currentOrientation = orientation;
currentX = -1;
@@ -317,55 +281,30 @@ public abstract class PtocaBuilder implements PtocaConstants {
newControlSequence();
if (col.getColorSpace().getType() == ColorSpace.TYPE_CMYK) {
- writeByte(0x00); // Reserved; must be zero
- writeByte(0x04); // Color space - 0x04 = CMYK
- writeByte(0x00); // Reserved; must be zero
- writeByte(0x00); // Reserved; must be zero
- writeByte(0x00); // Reserved; must be zero
- writeByte(0x00); // Reserved; must be zero
- writeByte(8); // Number of bits in component 1
- writeByte(8); // Number of bits in component 2
- writeByte(8); // Number of bits in component 3
- writeByte(8); // Number of bits in component 4
+ // Color space - 0x04 = CMYK, all else are reserved and must be zero
+ writeBytes(0x00, 0x04, 0x00, 0x00, 0x00, 0x00);
+ writeBytes(8, 8, 8, 8); // Number of bits in component 1, 2, 3 & 4 respectively
float[] comps = col.getColorComponents(null);
assert comps.length == 4;
for (int i = 0; i < 4; i++) {
int component = Math.round(comps[i] * 255);
- writeByte(component);
+ writeBytes(component);
}
} else if (cs instanceof CIELabColorSpace) {
- writeByte(0x00); // Reserved; must be zero
- writeByte(0x08); // Color space - 0x08 = CIELAB
- writeByte(0x00); // Reserved; must be zero
- writeByte(0x00); // Reserved; must be zero
- writeByte(0x00); // Reserved; must be zero
- writeByte(0x00); // Reserved; must be zero
- writeByte(8); // Number of bits in component 1
- writeByte(8); // Number of bits in component 2
- writeByte(8); // Number of bits in component 3
- writeByte(0); // Number of bits in component 4
+ // Color space - 0x08 = CIELAB, all else are reserved and must be zero
+ writeBytes(0x00, 0x08, 0x00, 0x00, 0x00, 0x00);
+ writeBytes(8, 8, 8, 0); // Number of bits in component 1,2,3 & 4
//Sadly, 16 bit components don't seem to work
float[] colorComponents = col.getColorComponents(null);
int l = Math.round(colorComponents[0] * 255f);
int a = Math.round(colorComponents[1] * 255f) - 128;
int b = Math.round(colorComponents[2] * 255f) - 128;
- writeByte(l); // L*
- writeByte(a); // a*
- writeByte(b); // b*
+ writeBytes(l, a, b); // l*, a* and b*
} else {
- writeByte(0x00); // Reserved; must be zero
- writeByte(0x01); // Color space - 0x01 = RGB
- writeByte(0x00); // Reserved; must be zero
- writeByte(0x00); // Reserved; must be zero
- writeByte(0x00); // Reserved; must be zero
- writeByte(0x00); // Reserved; must be zero
- writeByte(8); // Number of bits in component 1
- writeByte(8); // Number of bits in component 2
- writeByte(8); // Number of bits in component 3
- writeByte(0); // Number of bits in component 4
- writeByte(col.getRed()); // Red intensity
- writeByte(col.getGreen()); // Green intensity
- writeByte(col.getBlue()); // Blue intensity
+ // Color space - 0x01 = RGB, all else are reserved and must be zero
+ writeBytes(0x00, 0x01, 0x00, 0x00, 0x00, 0x00);
+ writeBytes(8, 8, 8, 0); // Number of bits in component 1, 2, 3 & 4 respectively
+ writeBytes(col.getRed(), col.getGreen(), col.getBlue()); // RGB intensity
}
commit(chained(SEC));
this.currentColor = col;
@@ -407,7 +346,7 @@ public abstract class PtocaBuilder implements PtocaConstants {
assert incr >= Short.MIN_VALUE && incr <= Short.MAX_VALUE;
newControlSequence();
writeShort(Math.abs(incr)); //Increment
- writeByte(incr >= 0 ? 0 : 1); // Direction
+ writeBytes(incr >= 0 ? 0 : 1); // Direction
commit(chained(SIA));
this.currentInterCharacterAdjustment = incr;
diff --git a/src/java/org/apache/fop/afp/ptoca/PtocaConstants.java b/src/java/org/apache/fop/afp/ptoca/PtocaConstants.java
index 2e692af2c..c53b97fd0 100644
--- a/src/java/org/apache/fop/afp/ptoca/PtocaConstants.java
+++ b/src/java/org/apache/fop/afp/ptoca/PtocaConstants.java
@@ -64,6 +64,6 @@ public interface PtocaConstants {
byte NOP = (byte)0xF8;
/** Maximum size of transparent data chunks */
- int TRANSPARENT_DATA_MAX_SIZE = 253;
+ int TRANSPARENT_DATA_MAX_SIZE = 253; // max length = 255 (minus the ControlSequence length)
}
diff --git a/src/java/org/apache/fop/afp/ptoca/PtocaProducer.java b/src/java/org/apache/fop/afp/ptoca/PtocaProducer.java
index 9b6d97dec..5f29bef96 100644
--- a/src/java/org/apache/fop/afp/ptoca/PtocaProducer.java
+++ b/src/java/org/apache/fop/afp/ptoca/PtocaProducer.java
@@ -22,8 +22,8 @@ package org.apache.fop.afp.ptoca;
import java.io.IOException;
/**
- * Producer interface that is passed to a {@link PresentationTextObject} to produce PTOCA control
- * sequences using a {@link PtocaBuilder}.
+ * Producer interface that is passed to a {@link org.apache.fop.afp.modca.PresentationTextObject}
+ * to produce PTOCA control sequences using a {@link PtocaBuilder}.
*/
public interface PtocaProducer {
diff --git a/src/java/org/apache/fop/afp/ptoca/TextDataInfoProducer.java b/src/java/org/apache/fop/afp/ptoca/TextDataInfoProducer.java
index f7ed5a85c..4af21b12b 100644
--- a/src/java/org/apache/fop/afp/ptoca/TextDataInfoProducer.java
+++ b/src/java/org/apache/fop/afp/ptoca/TextDataInfoProducer.java
@@ -56,7 +56,7 @@ public class TextDataInfoProducer implements PtocaProducer, PtocaConstants {
// Add transparent data
String textString = textDataInfo.getString();
String encoding = textDataInfo.getEncoding();
- builder.addTransparentData(CharactersetEncoder.encodeSBCS(textString, encoding, false));
+ builder.addTransparentData(CharactersetEncoder.encodeSBCS(textString, encoding));
}
}
diff --git a/src/java/org/apache/fop/afp/ptoca/TransparentDataControlSequence.java b/src/java/org/apache/fop/afp/ptoca/TransparentDataControlSequence.java
new file mode 100644
index 000000000..4b4276880
--- /dev/null
+++ b/src/java/org/apache/fop/afp/ptoca/TransparentDataControlSequence.java
@@ -0,0 +1,89 @@
+/*
+ * 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.ptoca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.fop.afp.fonts.CharactersetEncoder.EncodedChars;
+import org.apache.fop.afp.ptoca.TransparentDataControlSequence.TransparentData;
+
+import static org.apache.fop.afp.ptoca.PtocaConstants.TRANSPARENT_DATA_MAX_SIZE;
+
+/**
+ * This object represents a series of PTOCA TransparentData (TRN) control sequences. This implements
+ * {@link Iterable} to enable iteration through the TRNs.
+ */
+final class TransparentDataControlSequence implements Iterable<TransparentData> {
+
+ private static final int MAX_SBCS_TRN_SIZE = TRANSPARENT_DATA_MAX_SIZE;
+ // The maximum size of a TRN must be an EVEN number so that we're splitting TRNs on character
+ // boundaries rather than in the middle of a double-byte character
+ private static final int MAX_DBCS_TRN_SIZE = MAX_SBCS_TRN_SIZE - 1;
+
+ static final class TransparentData {
+ private final int offset;
+ private final int length;
+ private final EncodedChars encodedChars;
+
+ private TransparentData(int offset, int length, EncodedChars encChars) {
+ this.offset = offset;
+ this.length = length;
+ this.encodedChars = encChars;
+ }
+
+ void writeTo(OutputStream outStream) throws IOException {
+ encodedChars.writeTo(outStream, offset, length);
+ }
+ }
+
+ private final List<TransparentData> trns;
+
+ /**
+ * Converts an encoded String wrapped in an {@link EncodedChars} into a series of
+ * {@link TransparentData} control sequences.
+ *
+ * @param encChars the encoded characters to convert to TRNs
+ */
+ public TransparentDataControlSequence(EncodedChars encChars) {
+ int maxTrnLength = encChars.isDBCS() ? MAX_DBCS_TRN_SIZE : MAX_SBCS_TRN_SIZE;
+ int numTransData = encChars.getLength() / maxTrnLength;
+ int currIndex = 0;
+ List<TransparentData> trns = new ArrayList<TransparentData>();
+ for (int transDataCnt = 0; transDataCnt < numTransData; transDataCnt++) {
+ trns.add(new TransparentData(currIndex, maxTrnLength, encChars));
+ currIndex += maxTrnLength;
+ }
+ int left = encChars.getLength() - currIndex;
+ trns.add(new TransparentData(currIndex, left, encChars));
+ this.trns = Collections.unmodifiableList(trns);
+ }
+
+ /**
+ * The {@link Iterator} for retrieving the series of TRN control sequences.
+ */
+ public Iterator<TransparentData> iterator() {
+ return trns.iterator();
+ }
+}
diff --git a/src/java/org/apache/fop/cli/CommandLineOptions.java b/src/java/org/apache/fop/cli/CommandLineOptions.java
index bfcdb163e..7d5752d6d 100644
--- a/src/java/org/apache/fop/cli/CommandLineOptions.java
+++ b/src/java/org/apache/fop/cli/CommandLineOptions.java
@@ -357,8 +357,11 @@ public class CommandLineOptions {
} else if (args[i].equals("-a")) {
this.renderingOptions.put(Accessibility.ACCESSIBILITY, Boolean.TRUE);
} else if (args[i].equals("-v")) {
- /* Currently just print the version */
+ /* verbose mode although users may expect version; currently just print the version */
printVersion();
+ if (args.length == 1) {
+ return false;
+ }
} else if (args[i].equals("-param")) {
if (i + 2 < args.length) {
String name = args[++i];
@@ -588,7 +591,7 @@ public class CommandLineOptions {
private int parsePrintOutputOption(String[] args, int i) throws FOPException {
setOutputMode(MimeConstants.MIME_FOP_PRINT);
- if ((i + 1 <= args.length)
+ if ((i + 1 < args.length)
&& (args[i + 1].charAt(0) != '-')) {
String arg = args[i + 1];
String[] parts = arg.split(",");
diff --git a/src/java/org/apache/fop/fo/expr/AbsFunction.java b/src/java/org/apache/fop/fo/expr/AbsFunction.java
index 0e8355faa..9c266da76 100644
--- a/src/java/org/apache/fop/fo/expr/AbsFunction.java
+++ b/src/java/org/apache/fop/fo/expr/AbsFunction.java
@@ -27,22 +27,13 @@ import org.apache.fop.fo.properties.Property;
*/
public class AbsFunction extends FunctionBase {
- /**
- * @return 1 (the number of arguments required for the abs function)
- */
- public int nbArgs() {
+ /** {@inheritDoc} */
+ public int getRequiredArgsCount() {
return 1;
}
- /**
- * @param args array of arguments to be evaluated, the first of which
- * should be a numeric value
- * @param propInfo the PropertyInfo object to be evaluated
- * @return the absolute value of the input
- * @throws PropertyException for non-numeric input
- */
- public Property eval(Property[] args,
- PropertyInfo propInfo) throws PropertyException {
+ /** {@inheritDoc} */
+ public Property eval(Property[] args, PropertyInfo propInfo) throws PropertyException {
Numeric num = args[0].getNumeric();
if (num == null) {
throw new PropertyException("Non numeric operand to abs function");
diff --git a/src/java/org/apache/fop/fo/expr/BodyStartFunction.java b/src/java/org/apache/fop/fo/expr/BodyStartFunction.java
index 5307e75b0..5177f8a51 100644
--- a/src/java/org/apache/fop/fo/expr/BodyStartFunction.java
+++ b/src/java/org/apache/fop/fo/expr/BodyStartFunction.java
@@ -31,22 +31,13 @@ import org.apache.fop.fo.properties.Property;
*/
public class BodyStartFunction extends FunctionBase {
- /**
- * @return 0 (there are no arguments for body-start)
- */
- public int nbArgs() {
+ /** {@inheritDoc} */
+ public int getRequiredArgsCount() {
return 0;
}
- /**
- * @param args array of arguments (none are used, but this is required by
- * the Function interface)
- * @param pInfo PropertyInfo object to be evaluated
- * @return numeric object containing the calculated body-start value
- * @throws PropertyException if called from outside of an fo:list-item
- */
- public Property eval(Property[] args,
- PropertyInfo pInfo) throws PropertyException {
+ /** {@inheritDoc} */
+ public Property eval(Property[] args, PropertyInfo pInfo) throws PropertyException {
Numeric distance
= pInfo.getPropertyList()
.get(Constants.PR_PROVISIONAL_DISTANCE_BETWEEN_STARTS).getNumeric();
diff --git a/src/java/org/apache/fop/fo/expr/CIELabColorFunction.java b/src/java/org/apache/fop/fo/expr/CIELabColorFunction.java
index d027a9571..9783f5384 100644
--- a/src/java/org/apache/fop/fo/expr/CIELabColorFunction.java
+++ b/src/java/org/apache/fop/fo/expr/CIELabColorFunction.java
@@ -30,29 +30,25 @@ import org.apache.fop.fo.properties.Property;
*/
class CIELabColorFunction extends FunctionBase {
- /**
- * cie-lab-color() takes 2 times 3 arguments.
- * {@inheritDoc}
- */
- public int nbArgs() {
- return 2 * 3;
+ /** {@inheritDoc} */
+ public int getRequiredArgsCount() {
+ return 6;
}
+ @Override
+ /** {@inheritDoc} */
public PercentBase getPercentBase() {
return new CIELabPercentBase();
}
/** {@inheritDoc} */
- public Property eval(Property[] args,
- PropertyInfo pInfo) throws PropertyException {
+ public Property eval(Property[] args, PropertyInfo pInfo) throws PropertyException {
float red = args[0].getNumber().floatValue();
float green = args[1].getNumber().floatValue();
float blue = args[2].getNumber().floatValue();
/* Verify sRGB replacement arguments */
- if ((red < 0 || red > 255)
- || (green < 0 || green > 255)
- || (blue < 0 || blue > 255)) {
+ if ((red < 0 || red > 255) || (green < 0 || green > 255) || (blue < 0 || blue > 255)) {
throw new PropertyException("sRGB color values out of range. "
+ "Arguments to cie-lab-color() must be [0..255] or [0%..100%]");
}
diff --git a/src/java/org/apache/fop/fo/expr/CMYKcolorFunction.java b/src/java/org/apache/fop/fo/expr/CMYKColorFunction.java
index fe86860f4..1ca8cfaa0 100644
--- a/src/java/org/apache/fop/fo/expr/CMYKcolorFunction.java
+++ b/src/java/org/apache/fop/fo/expr/CMYKColorFunction.java
@@ -25,19 +25,15 @@ import org.apache.fop.fo.properties.Property;
/**
* Implements the cmyk() function.
*/
-class CMYKcolorFunction extends FunctionBase {
+class CMYKColorFunction extends FunctionBase {
- /**
- * cmyk takes four arguments.
- * {@inheritDoc}
- */
- public int nbArgs() {
+ /** {@inheritDoc} */
+ public int getRequiredArgsCount() {
return 4;
}
/** {@inheritDoc} */
- public Property eval(Property[] args,
- PropertyInfo pInfo) throws PropertyException {
+ public Property eval(Property[] args, PropertyInfo pInfo) throws PropertyException {
StringBuffer sb = new StringBuffer();
sb.append("cmyk(" + args[0] + "," + args[1] + "," + args[2] + "," + args[3] + ")");
FOUserAgent ua = (pInfo == null)
diff --git a/src/java/org/apache/fop/fo/expr/CeilingFunction.java b/src/java/org/apache/fop/fo/expr/CeilingFunction.java
index 875c88751..9c69cd1bc 100644
--- a/src/java/org/apache/fop/fo/expr/CeilingFunction.java
+++ b/src/java/org/apache/fop/fo/expr/CeilingFunction.java
@@ -24,12 +24,13 @@ import org.apache.fop.fo.properties.Property;
class CeilingFunction extends FunctionBase {
- public int nbArgs() {
+ /** {@inheritDoc} */
+ public int getRequiredArgsCount() {
return 1;
}
- public Property eval(Property[] args,
- PropertyInfo pInfo) throws PropertyException {
+ /** {@inheritDoc} */
+ public Property eval(Property[] args, PropertyInfo pInfo) throws PropertyException {
Number dbl = args[0].getNumber();
if (dbl == null) {
throw new PropertyException("Non number operand to ceiling function");
diff --git a/src/java/org/apache/fop/fo/expr/FloorFunction.java b/src/java/org/apache/fop/fo/expr/FloorFunction.java
index 043473140..501b8d59d 100644
--- a/src/java/org/apache/fop/fo/expr/FloorFunction.java
+++ b/src/java/org/apache/fop/fo/expr/FloorFunction.java
@@ -25,12 +25,13 @@ import org.apache.fop.fo.properties.Property;
class FloorFunction extends FunctionBase {
- public int nbArgs() {
+ /** {@inheritDoc} */
+ public int getRequiredArgsCount() {
return 1;
}
- public Property eval(Property[] args,
- PropertyInfo pInfo) throws PropertyException {
+ /** {@inheritDoc} */
+ public Property eval(Property[] args, PropertyInfo pInfo) throws PropertyException {
Number dbl = args[0].getNumber();
if (dbl == null) {
throw new PropertyException("Non number operand to floor function");
diff --git a/src/java/org/apache/fop/fo/expr/NearestSpecPropFunction.java b/src/java/org/apache/fop/fo/expr/FromNearestSpecifiedValueFunction.java
index 3e0dda565..7eb463fb6 100644
--- a/src/java/org/apache/fop/fo/expr/NearestSpecPropFunction.java
+++ b/src/java/org/apache/fop/fo/expr/FromNearestSpecifiedValueFunction.java
@@ -26,32 +26,31 @@ import org.apache.fop.fo.properties.Property;
* Class modelling the from-nearest-specified-value function. See Sec. 5.10.4
* of the XSL-FO standard.
*/
-public class NearestSpecPropFunction extends FunctionBase {
+public class FromNearestSpecifiedValueFunction extends FunctionBase {
- /**
- * @return 1 (maximum number of arguments for from-nearest-specified-value
- * function)
- */
- public int nbArgs() {
+ /** {@inheritDoc} */
+ public int getRequiredArgsCount() {
+ return 0;
+ }
+
+ @Override
+ /** {@inheritDoc} */
+ public int getOptionalArgsCount() {
return 1;
}
- /**
- * @return true (allow padding of arglist with property name)
- */
- public boolean padArgsWithPropertyName() {
- return true;
+ @Override
+ /** {@inheritDoc} */
+ public Property getOptionalArgDefault(int index, PropertyInfo pi) throws PropertyException {
+ if ( index == 0 ) {
+ return getPropertyName ( pi );
+ } else {
+ return super.getOptionalArgDefault ( index, pi );
+ }
}
- /**
- *
- * @param args array of arguments for the function
- * @param pInfo PropertyInfo for the function
- * @return Property containing the nearest-specified-value
- * @throws PropertyException for invalid arguments to the function
- */
- public Property eval(Property[] args,
- PropertyInfo pInfo) throws PropertyException {
+ /** {@inheritDoc} */
+ public Property eval(Property[] args, PropertyInfo pInfo) throws PropertyException {
String propName = args[0].getString();
if (propName == null) {
throw new PropertyException(
diff --git a/src/java/org/apache/fop/fo/expr/FromParentFunction.java b/src/java/org/apache/fop/fo/expr/FromParentFunction.java
index b1e9d689d..e24074e9d 100644
--- a/src/java/org/apache/fop/fo/expr/FromParentFunction.java
+++ b/src/java/org/apache/fop/fo/expr/FromParentFunction.java
@@ -29,29 +29,29 @@ import org.apache.fop.fo.properties.Property;
*/
public class FromParentFunction extends FunctionBase {
- /**
- * @return 1 (maximum arguments for the from-parent function)
- */
- public int nbArgs() {
+ /** {@inheritDoc} */
+ public int getRequiredArgsCount() {
+ return 0;
+ }
+
+ @Override
+ /** {@inheritDoc} */
+ public int getOptionalArgsCount() {
return 1;
}
- /**
- * @return true (allow padding of arglist with property name)
- */
- public boolean padArgsWithPropertyName() {
- return true;
+ @Override
+ /** {@inheritDoc} */
+ public Property getOptionalArgDefault(int index, PropertyInfo pi) throws PropertyException {
+ if ( index == 0 ) {
+ return getPropertyName ( pi );
+ } else {
+ return super.getOptionalArgDefault ( index, pi );
+ }
}
- /**
- * @param args array of arguments, which should either be empty, or the
- * first of which should contain an NCName corresponding to property name
- * @param pInfo PropertyInfo object to be evaluated
- * @return property containing the computed value
- * @throws PropertyException if the arguments are incorrect
- */
- public Property eval(Property[] args,
- PropertyInfo pInfo) throws PropertyException {
+ /** {@inheritDoc} */
+ public Property eval(Property[] args, PropertyInfo pInfo) throws PropertyException {
String propName = args[0].getString();
if (propName == null) {
throw new PropertyException("Incorrect parameter to from-parent function");
diff --git a/src/java/org/apache/fop/fo/expr/FromTableColumnFunction.java b/src/java/org/apache/fop/fo/expr/FromTableColumnFunction.java
index 627459cf1..48ea4e152 100644
--- a/src/java/org/apache/fop/fo/expr/FromTableColumnFunction.java
+++ b/src/java/org/apache/fop/fo/expr/FromTableColumnFunction.java
@@ -37,32 +37,29 @@ import org.apache.fop.fo.properties.Property;
*/
public class FromTableColumnFunction extends FunctionBase {
- /**
- * @return 1 (maximum arguments for the from-table-column function)
- */
- public int nbArgs() {
+ /** {@inheritDoc} */
+ public int getRequiredArgsCount() {
+ return 0;
+ }
+
+ @Override
+ /** {@inheritDoc} */
+ public int getOptionalArgsCount() {
return 1;
}
- /**
- * @return true (allow padding of arglist with property name)
- */
- public boolean padArgsWithPropertyName() {
- return true;
+ @Override
+ /** {@inheritDoc} */
+ public Property getOptionalArgDefault(int index, PropertyInfo pi) throws PropertyException {
+ if ( index == 0 ) {
+ return getPropertyName ( pi );
+ } else {
+ return super.getOptionalArgDefault ( index, pi );
+ }
}
- /**
- *
- * @param args array of arguments, which should either be empty, or the
- * first of which should contain an NCName corresponding to a property name
- * @param pInfo PropertyInfo object to be evaluated
- * @return the Property corresponding to the property name specified, or, if
- * none, for the property for which the expression is being evaluated
- * @throws PropertyException for incorrect arguments, and (for now) in all
- * cases, because this function is not implemented
- */
- public Property eval(Property[] args,
- PropertyInfo pInfo) throws PropertyException {
+ /** {@inheritDoc} */
+ public Property eval(Property[] args, PropertyInfo pInfo) throws PropertyException {
FObj fo = pInfo.getPropertyList().getFObj();
diff --git a/src/java/org/apache/fop/fo/expr/Function.java b/src/java/org/apache/fop/fo/expr/Function.java
index 82ec1b7fd..f558543c0 100644
--- a/src/java/org/apache/fop/fo/expr/Function.java
+++ b/src/java/org/apache/fop/fo/expr/Function.java
@@ -28,11 +28,34 @@ import org.apache.fop.fo.properties.Property;
public interface Function {
/**
- * @return the number of arguments that must be passed to this function. For
- * example, if the function should determine the minimum of two numbers, it
- * must be passed two arguments, one for each of the two values.
+ * @return the number of required (non-optional) arguments that must be specified
+ * in the argument list
*/
- int nbArgs();
+ int getRequiredArgsCount();
+
+ /**
+ * @return the number of non-required (optional) arguments that may be specified
+ * in the argument list, which, if specified, must follow the required arguments
+ */
+ int getOptionalArgsCount();
+
+ /**
+ * @param index of optional argument
+ * @param pi property information instance that applies to property being evaluated
+ * @return the default property value for the optional argument at INDEX, where
+ * INDEX is with respect to optional arguments; i.e., the first optional argument
+ * position is index 0; if no default for a given index, then null is returned
+ * @throws PropertyException if index is greater than or equal to optional args count
+ */
+ Property getOptionalArgDefault(int index, PropertyInfo pi) throws PropertyException;
+
+ /**
+ * Determine if function allows variable arguments. If it does, then they must appear
+ * after required and optional arguments, and all optional arguments must be specified.
+ * @return true if function permits additional variable number of arguments after
+ * required and (completely specified) optional arguments
+ */
+ boolean hasVariableArgs();
/**
* @return the basis for percentage calculations
@@ -42,16 +65,10 @@ public interface Function {
/**
* Evaluate the function
* @param args an array of Properties that should be evaluated
- * @param propInfo the PropertyInfo
+ * @param pi property information instance that applies to property being evaluated
* @return the Property satisfying the function
* @throws PropertyException for problems when evaluating the function
*/
- Property eval(Property[] args,
- PropertyInfo propInfo) throws PropertyException;
+ Property eval(Property[] args, PropertyInfo pi) throws PropertyException;
- /**
- * @return if it is allowed to fill up the property list with
- * the property name if only one arg is missing.
- */
- boolean padArgsWithPropertyName();
}
diff --git a/src/java/org/apache/fop/fo/expr/FunctionBase.java b/src/java/org/apache/fop/fo/expr/FunctionBase.java
index b5040c635..6e0fd6702 100644
--- a/src/java/org/apache/fop/fo/expr/FunctionBase.java
+++ b/src/java/org/apache/fop/fo/expr/FunctionBase.java
@@ -20,23 +20,45 @@
package org.apache.fop.fo.expr;
import org.apache.fop.datatypes.PercentBase;
+import org.apache.fop.fo.properties.Property;
+import org.apache.fop.fo.properties.StringProperty;
/**
* Abstract Base class for XSL-FO functions
*/
public abstract class FunctionBase implements Function {
- /**
- * @return null (by default, functions have no percent-based arguments)
- */
+ /** {@inheritDoc} */
+ public int getOptionalArgsCount() {
+ return 0;
+ }
+
+ /** {@inheritDoc} */
+ public Property getOptionalArgDefault(int index, PropertyInfo pi) throws PropertyException {
+ if ( index >= getOptionalArgsCount() ) {
+ PropertyException e = new PropertyException ( new IndexOutOfBoundsException ( "illegal optional argument index" ) );
+ e.setPropertyInfo ( pi );
+ throw e;
+ } else {
+ return null;
+ }
+ }
+
+ /** {@inheritDoc} */
+ public boolean hasVariableArgs() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
public PercentBase getPercentBase() {
return null;
}
/**
- * @return false (by default don't pad arglist with property-name)
+ * @param pi property information instance that applies to property being evaluated
+ * @return string property whose value is name of property being evaluated
*/
- public boolean padArgsWithPropertyName() {
- return false;
+ protected final Property getPropertyName ( PropertyInfo pi ) {
+ return StringProperty.getInstance ( pi.getPropertyMaker().getName() );
}
}
diff --git a/src/java/org/apache/fop/fo/expr/InheritedPropFunction.java b/src/java/org/apache/fop/fo/expr/InheritedPropFunction.java
index 94c4fdf22..6e982bd31 100644
--- a/src/java/org/apache/fop/fo/expr/InheritedPropFunction.java
+++ b/src/java/org/apache/fop/fo/expr/InheritedPropFunction.java
@@ -28,30 +28,29 @@ import org.apache.fop.fo.properties.Property;
*/
public class InheritedPropFunction extends FunctionBase {
- /**
- * @return 1 (maximum number of arguments for the inherited-property-value
- * function)
- */
- public int nbArgs() {
+ /** {@inheritDoc} */
+ public int getRequiredArgsCount() {
+ return 0;
+ }
+
+ @Override
+ /** {@inheritDoc} */
+ public int getOptionalArgsCount() {
return 1;
}
- /**
- * @return true (allow padding of arglist with property name)
- */
- public boolean padArgsWithPropertyName() {
- return true;
+ @Override
+ /** {@inheritDoc} */
+ public Property getOptionalArgDefault(int index, PropertyInfo pi) throws PropertyException {
+ if ( index == 0 ) {
+ return getPropertyName ( pi );
+ } else {
+ return super.getOptionalArgDefault ( index, pi );
+ }
}
- /**
- *
- * @param args arguments to be evaluated
- * @param pInfo PropertyInfo object to be evaluated
- * @return Property satisfying the inherited-property-value
- * @throws PropertyException for invalid parameter
- */
- public Property eval(Property[] args,
- PropertyInfo pInfo) throws PropertyException {
+ /** {@inheritDoc} */
+ public Property eval(Property[] args, PropertyInfo pInfo) throws PropertyException {
String propName = args[0].getString();
if (propName == null) {
throw new PropertyException("Incorrect parameter to inherited-property-value function");
diff --git a/src/java/org/apache/fop/fo/expr/LabelEndFunction.java b/src/java/org/apache/fop/fo/expr/LabelEndFunction.java
index 5deb3ae30..57facc058 100644
--- a/src/java/org/apache/fop/fo/expr/LabelEndFunction.java
+++ b/src/java/org/apache/fop/fo/expr/LabelEndFunction.java
@@ -34,23 +34,13 @@ import org.apache.fop.fo.properties.Property;
*/
public class LabelEndFunction extends FunctionBase {
- /**
- * @return 0 (the number of arguments required for the label-end function)
- */
- public int nbArgs() {
+ /** {@inheritDoc} */
+ public int getRequiredArgsCount() {
return 0;
}
- /**
- *
- * @param args array of arguments for the function (none are needed, but
- * required for the Function interface)
- * @param pInfo PropertyInfo object for the function
- * @return the calculated label-end value for the list
- * @throws PropertyException if called from outside of an fo:list-item
- */
- public Property eval(Property[] args,
- PropertyInfo pInfo) throws PropertyException {
+ /** {@inheritDoc} */
+ public Property eval(Property[] args, PropertyInfo pInfo) throws PropertyException {
Length distance = pInfo.getPropertyList().get(
Constants.PR_PROVISIONAL_DISTANCE_BETWEEN_STARTS).getLength();
diff --git a/src/java/org/apache/fop/fo/expr/MaxFunction.java b/src/java/org/apache/fop/fo/expr/MaxFunction.java
index fd2fee0b1..442197de6 100644
--- a/src/java/org/apache/fop/fo/expr/MaxFunction.java
+++ b/src/java/org/apache/fop/fo/expr/MaxFunction.java
@@ -28,22 +28,13 @@ import org.apache.fop.fo.properties.Property;
*/
public class MaxFunction extends FunctionBase {
- /**
- * @return 2 (the number of arguments required for the max function)
- */
- public int nbArgs() {
+ /** {@inheritDoc} */
+ public int getRequiredArgsCount() {
return 2;
}
- /**
- * Handle "numerics" if no proportional/percent parts
- * @param args array of arguments to be processed
- * @param pInfo PropertyInfo to be processed
- * @return the maximum of the two args elements passed
- * @throws PropertyException for invalid operands
- */
- public Property eval(Property[] args,
- PropertyInfo pInfo) throws PropertyException {
+ /** {@inheritDoc} */
+ public Property eval(Property[] args, PropertyInfo pInfo) throws PropertyException {
Numeric n1 = args[0].getNumeric();
Numeric n2 = args[1].getNumeric();
if (n1 == null || n2 == null) {
diff --git a/src/java/org/apache/fop/fo/expr/MinFunction.java b/src/java/org/apache/fop/fo/expr/MinFunction.java
index 979d16b27..19a06ada1 100644
--- a/src/java/org/apache/fop/fo/expr/MinFunction.java
+++ b/src/java/org/apache/fop/fo/expr/MinFunction.java
@@ -28,22 +28,13 @@ import org.apache.fop.fo.properties.Property;
*/
public class MinFunction extends FunctionBase {
- /**
- * @return 2 (the number of arguments required for the min function)
- */
- public int nbArgs() {
+ /** {@inheritDoc} */
+ public int getRequiredArgsCount() {
return 2;
}
- /**
- * Handle "numerics" if no proportional/percent parts
- * @param args array of arguments to be processed
- * @param pInfo PropertyInfo to be processed
- * @return the minimum of the two args elements passed
- * @throws PropertyException for invalid operands
- */
- public Property eval(Property[] args,
- PropertyInfo pInfo) throws PropertyException {
+ /** {@inheritDoc} */
+ public Property eval(Property[] args, PropertyInfo pInfo) throws PropertyException {
Numeric n1 = args[0].getNumeric();
Numeric n2 = args[1].getNumeric();
if (n1 == null || n2 == null) {
diff --git a/src/java/org/apache/fop/fo/expr/PropertyParser.java b/src/java/org/apache/fop/fo/expr/PropertyParser.java
index 9ef45befe..f3e3e4a50 100644
--- a/src/java/org/apache/fop/fo/expr/PropertyParser.java
+++ b/src/java/org/apache/fop/fo/expr/PropertyParser.java
@@ -20,7 +20,6 @@
package org.apache.fop.fo.expr;
import java.util.HashMap;
-import java.util.LinkedList;
import java.util.List;
import org.apache.xmlgraphics.util.UnitConv;
@@ -59,19 +58,16 @@ public final class PropertyParser extends PropertyTokenizer {
FUNCTION_TABLE.put("rgb", new RGBColorFunction());
FUNCTION_TABLE.put("system-color", new SystemColorFunction());
FUNCTION_TABLE.put("from-table-column", new FromTableColumnFunction());
- FUNCTION_TABLE.put("inherited-property-value",
- new InheritedPropFunction());
+ FUNCTION_TABLE.put("inherited-property-value", new InheritedPropFunction());
+ FUNCTION_TABLE.put("from-nearest-specified-value", new FromNearestSpecifiedValueFunction());
FUNCTION_TABLE.put("from-parent", new FromParentFunction());
- FUNCTION_TABLE.put("from-nearest-specified-value",
- new NearestSpecPropFunction());
- FUNCTION_TABLE.put("proportional-column-width",
- new PPColWidthFunction());
+ FUNCTION_TABLE.put("proportional-column-width", new ProportionalColumnWidthFunction());
FUNCTION_TABLE.put("label-end", new LabelEndFunction());
FUNCTION_TABLE.put("body-start", new BodyStartFunction());
- FUNCTION_TABLE.put("rgb-icc", new ICCColorFunction());
- FUNCTION_TABLE.put("rgb-named-color", new NamedColorFunction()); //since XSL-FO 2.0
+ FUNCTION_TABLE.put("rgb-icc", new RGBICCColorFunction());
+ FUNCTION_TABLE.put("rgb-named-color", new RGBNamedColorFunction()); //since XSL-FO 2.0
FUNCTION_TABLE.put("cie-lab-color", new CIELabColorFunction()); //since XSL-FO 2.0
- FUNCTION_TABLE.put("cmyk", new CMYKcolorFunction()); //non-standard!!!
+ FUNCTION_TABLE.put("cmyk", new CMYKColorFunction()); //non-standard!!!
/**
* * NOT YET IMPLEMENTED!!!
@@ -341,12 +337,7 @@ public final class PropertyParser extends PropertyTokenizer {
next();
// Push new function (for function context: getPercentBase())
propInfo.pushFunction(function);
- if (function.nbArgs() < 0) {
- // Negative nbArgs --> function with variable number of arguments
- prop = function.eval(parseVarArgs(function), propInfo);
- } else {
- prop = function.eval(parseArgs(function), propInfo);
- }
+ prop = function.eval(parseArgs(function), propInfo);
propInfo.popFunction();
return prop;
@@ -362,27 +353,27 @@ public final class PropertyParser extends PropertyTokenizer {
* Parse a comma separated list of function arguments. Each argument
* may itself be an expression. This method consumes the closing right
* parenthesis of the argument list.
- * @param function The function object for which the arguments are
- * collected.
- * @return An array of Property objects representing the arguments
- * found.
+ * @param function The function object for which the arguments are collected.
+ * @return An array of Property objects representing the arguments found.
* @throws PropertyException If the number of arguments found isn't equal
- * to the number expected.
+ * to the number expected or if another argument parsing error occurs.
*/
Property[] parseArgs(Function function) throws PropertyException {
- int nbArgs = function.nbArgs();
- Property[] args = new Property[nbArgs];
- Property prop;
- int i = 0;
+ int numReq = function.getRequiredArgsCount(); // # required args
+ int numOpt = function.getOptionalArgsCount(); // # optional args
+ boolean hasVar = function.hasVariableArgs(); // has variable args
+ List<Property> args = new java.util.ArrayList<Property>(numReq + numOpt);
if (currentToken == TOK_RPAR) {
// No args: func()
next();
} else {
while (true) {
-
- prop = parseAdditiveExpr();
- if (i < nbArgs) {
- args[i++] = prop;
+ Property p = parseAdditiveExpr();
+ int i = args.size();
+ if ( ( i < numReq ) || ( ( i - numReq ) < numOpt ) || hasVar ) {
+ args.add ( p );
+ } else {
+ throw new PropertyException ( "Unexpected function argument at index " + i );
}
// ignore extra args
if (currentToken != TOK_COMMA) {
@@ -392,66 +383,19 @@ public final class PropertyParser extends PropertyTokenizer {
}
expectRpar();
}
- if (i == nbArgs - 1 && function.padArgsWithPropertyName()) {
- args[i++] = StringProperty.getInstance(
- propInfo.getPropertyMaker().getName());
- }
- if (nbArgs != i) {
- throw new PropertyException("Expected " + nbArgs
- + ", but got " + i + " args for function");
- }
- return args;
- }
-
- /**
- *
- * Parse a comma separated list of function arguments. Each argument
- * may itself be an expression. This method consumes the closing right
- * parenthesis of the argument list.
- *
- * The method differs from parseArgs in that it accepts a variable
- * number of arguments.
- *
- * @param function The function object for which the arguments are
- * collected.
- * @return An array of Property objects representing the arguments
- * found.
- * @throws PropertyException If the number of arguments found isn't equal
- * to the number expected.
- *
- * TODO Merge this with parseArgs?
- */
- Property[] parseVarArgs(Function function) throws PropertyException {
- // For variable argument functions the minimum number of arguments is returned as a
- // negative integer from the nbArgs method
- int nbArgs = -function.nbArgs();
- List args = new LinkedList();
- Property prop;
- if (currentToken == TOK_RPAR) {
- // No args: func()
- next();
+ int numArgs = args.size();
+ if ( numArgs < numReq ) {
+ throw new PropertyException("Expected " + numReq + " required arguments, but only " + numArgs + " specified");
} else {
- while (true) {
- prop = parseAdditiveExpr();
- args.add(prop);
- // ignore extra args
- if (currentToken != TOK_COMMA) {
- break;
+ for ( int i = 0; i < numOpt; i++ ) {
+ if ( args.size() < ( numReq + i + 1 ) ) {
+ args.add ( function.getOptionalArgDefault ( i, propInfo ) );
}
- next();
}
- expectRpar();
- }
- if (nbArgs > args.size()) {
- throw new PropertyException("Expected at least " + nbArgs
- + ", but got " + args.size() + " args for function");
}
- Property[] propArray = new Property[args.size()];
- args.toArray(propArray);
- return propArray;
+ return (Property[]) args.toArray ( new Property [ args.size() ] );
}
-
/**
* Evaluate an addition operation. If either of the arguments is null,
* this means that it wasn't convertible to a Numeric value.
diff --git a/src/java/org/apache/fop/fo/expr/PropertyTokenizer.java b/src/java/org/apache/fop/fo/expr/PropertyTokenizer.java
index e07f3c433..3c9c81d27 100644
--- a/src/java/org/apache/fop/fo/expr/PropertyTokenizer.java
+++ b/src/java/org/apache/fop/fo/expr/PropertyTokenizer.java
@@ -67,7 +67,7 @@ class PropertyTokenizer {
}
/**
- * Return the next token in the expression string.
+ * Parse the next token in the expression string.
* This sets the following package visible variables:
* currentToken An enumerated value identifying the recognized token
* currentTokenValue A String containing the token contents
diff --git a/src/java/org/apache/fop/fo/expr/PPColWidthFunction.java b/src/java/org/apache/fop/fo/expr/ProportionalColumnWidthFunction.java
index 5defda0fe..8f9df5d5f 100644
--- a/src/java/org/apache/fop/fo/expr/PPColWidthFunction.java
+++ b/src/java/org/apache/fop/fo/expr/ProportionalColumnWidthFunction.java
@@ -30,34 +30,21 @@ import org.apache.fop.fo.properties.TableColLength;
* Class modelling the proportional-column-width function. See Sec. 5.10.4 of
* the XSL-FO standard.
*/
-public class PPColWidthFunction extends FunctionBase {
+public class ProportionalColumnWidthFunction extends FunctionBase {
- /**
- * @return 1 (the number of arguments for the proportional-column-width
- * function)
- */
- public int nbArgs() {
+ /** {@inheritDoc} */
+ public int getRequiredArgsCount() {
return 1;
}
- /**
- * @return the {@link PercentBase} for the proportional-column-width()
- * function
- */
+ @Override
+ /** {@inheritDoc} */
public PercentBase getPercentBase() {
- return new PPColWidthPercentBase();
+ return new ProportionalColumnWidthPercentBase();
}
- /**
- *
- * @param args array of arguments for this function
- * @param pInfo PropertyInfo for this function
- * @return numeric Property containing the units of proportional measure
- * for this column
- * @throws PropertyException for non-numeric operand, or if the parent
- * element is not a table-column
- */
- public Property eval(Property[] args,
- PropertyInfo pInfo) throws PropertyException {
+
+ /** {@inheritDoc} */
+ public Property eval(Property[] args, PropertyInfo pInfo) throws PropertyException {
Number d = args[0].getNumber();
if (d == null) {
throw new PropertyException("Non numeric operand to "
@@ -78,7 +65,7 @@ public class PPColWidthFunction extends FunctionBase {
return new TableColLength(d.doubleValue(), pInfo.getFO());
}
- private static class PPColWidthPercentBase implements PercentBase {
+ private static class ProportionalColumnWidthPercentBase implements PercentBase {
/** {@inheritDoc} */
public int getBaseLength(PercentBaseContext context) throws PropertyException {
diff --git a/src/java/org/apache/fop/fo/expr/RGBColorFunction.java b/src/java/org/apache/fop/fo/expr/RGBColorFunction.java
index 868b9a8bf..9f8a7f600 100644
--- a/src/java/org/apache/fop/fo/expr/RGBColorFunction.java
+++ b/src/java/org/apache/fop/fo/expr/RGBColorFunction.java
@@ -30,22 +30,18 @@ import org.apache.fop.fo.properties.Property;
class RGBColorFunction extends FunctionBase {
/** {@inheritDoc} */
- public int nbArgs() {
+ public int getRequiredArgsCount() {
return 3;
}
- /**
- * @return an object which implements the PercentBase interface.
- * Percents in arguments to this function are interpreted relative
- * to 255.
- */
+ @Override
+ /** {@inheritDoc} */
public PercentBase getPercentBase() {
return new RGBPercentBase();
}
/** {@inheritDoc} */
- public Property eval(Property[] args,
- PropertyInfo pInfo) throws PropertyException {
+ public Property eval(Property[] args, PropertyInfo pInfo) throws PropertyException {
return ColorProperty.getInstance(pInfo.getUserAgent(),
"rgb(" + args[0] + ","
+ args[1] + "," + args[2] + ")");
diff --git a/src/java/org/apache/fop/fo/expr/ICCColorFunction.java b/src/java/org/apache/fop/fo/expr/RGBICCColorFunction.java
index 756de1b20..57cf6a949 100644
--- a/src/java/org/apache/fop/fo/expr/ICCColorFunction.java
+++ b/src/java/org/apache/fop/fo/expr/RGBICCColorFunction.java
@@ -29,26 +29,27 @@ import org.apache.fop.util.ColorUtil;
/**
* Implements the rgb-icc() function.
*/
-class ICCColorFunction extends FunctionBase {
+class RGBICCColorFunction extends FunctionBase {
- /**
- * rgb-icc takes a variable number of arguments.
- * At least 4 should be passed - returns -4
- * {@inheritDoc}
- */
- public int nbArgs() {
- return -4;
+ /** {@inheritDoc} */
+ public int getRequiredArgsCount() {
+ return 4;
}
+ @Override
/** {@inheritDoc} */
+ public boolean hasVariableArgs() {
+ return true;
+ }
+
@Override
+ /** {@inheritDoc} */
public PercentBase getPercentBase() {
return new ICCPercentBase();
}
/** {@inheritDoc} */
- public Property eval(Property[] args,
- PropertyInfo pInfo) throws PropertyException {
+ public Property eval(Property[] args, PropertyInfo pInfo) throws PropertyException {
// Map color profile NCNAME to src from declarations/color-profile element
String colorProfileName = args[3].getString();
Declarations decls = (pInfo.getFO() != null
@@ -86,9 +87,7 @@ class ICCColorFunction extends FunctionBase {
green = args[1].getNumber().floatValue();
blue = args[2].getNumber().floatValue();
/* Verify rgb replacement arguments */
- if ((red < 0 || red > 255)
- || (green < 0 || green > 255)
- || (blue < 0 || blue > 255)) {
+ if ((red < 0 || red > 255) || (green < 0 || green > 255) || (blue < 0 || blue > 255)) {
throw new PropertyException("Color values out of range. "
+ "Arguments to rgb-icc() must be [0..255] or [0%..100%]");
}
diff --git a/src/java/org/apache/fop/fo/expr/NamedColorFunction.java b/src/java/org/apache/fop/fo/expr/RGBNamedColorFunction.java
index f2ff19ef1..076900d68 100644
--- a/src/java/org/apache/fop/fo/expr/NamedColorFunction.java
+++ b/src/java/org/apache/fop/fo/expr/RGBNamedColorFunction.java
@@ -29,25 +29,21 @@ import org.apache.fop.fo.properties.Property;
* Implements the rgb-named-color() function.
* @since XSL-FO 2.0
*/
-class NamedColorFunction extends FunctionBase {
+class RGBNamedColorFunction extends FunctionBase {
- /**
- * rgb-named-color() takes a 5 arguments.
- * {@inheritDoc}
- */
- public int nbArgs() {
+ /** {@inheritDoc} */
+ public int getRequiredArgsCount() {
return 5;
}
/** {@inheritDoc} */
@Override
public PercentBase getPercentBase() {
- return new NamedPercentBase();
+ return new RGBNamedPercentBase();
}
/** {@inheritDoc} */
- public Property eval(Property[] args,
- PropertyInfo pInfo) throws PropertyException {
+ public Property eval(Property[] args, PropertyInfo pInfo) throws PropertyException {
// Map color profile NCNAME to src from declarations/color-profile element
String colorProfileName = args[3].getString();
String colorName = args[4].getString();
@@ -96,7 +92,7 @@ class NamedColorFunction extends FunctionBase {
return ColorProperty.getInstance(pInfo.getUserAgent(), sb.toString());
}
- private static final class NamedPercentBase implements PercentBase {
+ private static final class RGBNamedPercentBase implements PercentBase {
/** {@inheritDoc} */
public int getBaseLength(PercentBaseContext context) throws PropertyException {
diff --git a/src/java/org/apache/fop/fo/expr/RoundFunction.java b/src/java/org/apache/fop/fo/expr/RoundFunction.java
index a29c33e5b..201039b5a 100644
--- a/src/java/org/apache/fop/fo/expr/RoundFunction.java
+++ b/src/java/org/apache/fop/fo/expr/RoundFunction.java
@@ -24,12 +24,14 @@ import org.apache.fop.fo.properties.NumberProperty;
import org.apache.fop.fo.properties.Property;
class RoundFunction extends FunctionBase {
- public int nbArgs() {
+
+ /** {@inheritDoc} */
+ public int getRequiredArgsCount() {
return 1;
}
- public Property eval(Property[] args,
- PropertyInfo pInfo) throws PropertyException {
+ /** {@inheritDoc} */
+ public Property eval(Property[] args, PropertyInfo pInfo) throws PropertyException {
Number dbl = args[0].getNumber();
if (dbl == null) {
throw new PropertyException("Non number operand to round function");
diff --git a/src/java/org/apache/fop/fo/expr/SystemColorFunction.java b/src/java/org/apache/fop/fo/expr/SystemColorFunction.java
index eeb1870f7..8ec88e983 100644
--- a/src/java/org/apache/fop/fo/expr/SystemColorFunction.java
+++ b/src/java/org/apache/fop/fo/expr/SystemColorFunction.java
@@ -29,13 +29,12 @@ import org.apache.fop.fo.properties.Property;
class SystemColorFunction extends FunctionBase {
/** {@inheritDoc} */
- public int nbArgs() {
+ public int getRequiredArgsCount() {
return 1;
}
/** {@inheritDoc} */
- public Property eval(Property[] args,
- PropertyInfo pInfo) throws PropertyException {
+ public Property eval(Property[] args, PropertyInfo pInfo) throws PropertyException {
FOUserAgent ua = (pInfo == null)
? null
: (pInfo.getFO() == null ? null : pInfo.getFO().getUserAgent());
diff --git a/src/java/org/apache/fop/fo/flow/table/ConditionalBorder.java b/src/java/org/apache/fop/fo/flow/table/ConditionalBorder.java
index b5cd56d47..e69439276 100644
--- a/src/java/org/apache/fop/fo/flow/table/ConditionalBorder.java
+++ b/src/java/org/apache/fop/fo/flow/table/ConditionalBorder.java
@@ -60,6 +60,7 @@ public class ConditionalBorder {
private ConditionalBorder(BorderSpecification normal,
BorderSpecification leadingTrailing, BorderSpecification rest,
CollapsingBorderModel collapsingBorderModel) {
+ assert collapsingBorderModel != null;
this.normal = normal;
this.leadingTrailing = leadingTrailing;
this.rest = rest;
@@ -74,14 +75,10 @@ public class ConditionalBorder {
*/
ConditionalBorder(BorderSpecification borderSpecification,
CollapsingBorderModel collapsingBorderModel) {
- normal = borderSpecification;
- leadingTrailing = normal;
- if (borderSpecification.getBorderInfo().getWidth().isDiscard()) {
- rest = BorderSpecification.getDefaultBorder();
- } else {
- rest = leadingTrailing;
- }
- this.collapsingBorderModel = collapsingBorderModel;
+ this ( borderSpecification, borderSpecification,
+ borderSpecification.getBorderInfo().getWidth().isDiscard()
+ ? BorderSpecification.getDefaultBorder() : borderSpecification,
+ collapsingBorderModel );
}
/**
diff --git a/src/java/org/apache/fop/fo/flow/table/Table.java b/src/java/org/apache/fop/fo/flow/table/Table.java
index b14326af5..a574723b1 100644
--- a/src/java/org/apache/fop/fo/flow/table/Table.java
+++ b/src/java/org/apache/fop/fo/flow/table/Table.java
@@ -20,11 +20,14 @@
package org.apache.fop.fo.flow.table;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
+import java.util.Stack;
import org.xml.sax.Locator;
import org.apache.fop.apps.FOPException;
+import org.apache.fop.complexscripts.bidi.DelimitedTextRange;
import org.apache.fop.datatypes.Length;
import org.apache.fop.datatypes.ValidationPercentBaseContext;
import org.apache.fop.fo.FONode;
@@ -40,12 +43,16 @@ import org.apache.fop.fo.properties.KeepProperty;
import org.apache.fop.fo.properties.LengthPairProperty;
import org.apache.fop.fo.properties.LengthRangeProperty;
import org.apache.fop.fo.properties.TableColLength;
+import org.apache.fop.traits.Direction;
+import org.apache.fop.traits.WritingMode;
+import org.apache.fop.traits.WritingModeTraits;
+import org.apache.fop.traits.WritingModeTraitsGetter;
/**
* Class modelling the <a href="http://www.w3.org/TR/xsl/#fo_table">
* <code>fo:table</code></a> object.
*/
-public class Table extends TableFObj implements ColumnNumberManagerHolder, BreakPropertySet,
+public class Table extends TableFObj implements ColumnNumberManagerHolder, BreakPropertySet, WritingModeTraitsGetter,
CommonAccessibilityHolder {
// The value of FO traits (refined properties) that apply to fo:table.
@@ -64,7 +71,7 @@ public class Table extends TableFObj implements ColumnNumberManagerHolder, Break
private int tableLayout;
private int tableOmitFooterAtBreak;
private int tableOmitHeaderAtBreak;
- private int writingMode;
+ private WritingModeTraits writingModeTraits;
// Unused but valid items, commented out for performance:
// private CommonAural commonAural;
// private CommonRelativePosition commonRelativePosition;
@@ -131,7 +138,8 @@ public class Table extends TableFObj implements ColumnNumberManagerHolder, Break
tableLayout = pList.get(PR_TABLE_LAYOUT).getEnum();
tableOmitFooterAtBreak = pList.get(PR_TABLE_OMIT_FOOTER_AT_BREAK).getEnum();
tableOmitHeaderAtBreak = pList.get(PR_TABLE_OMIT_HEADER_AT_BREAK).getEnum();
- writingMode = pList.get(PR_WRITING_MODE).getEnum();
+ writingModeTraits = new WritingModeTraits
+ ( WritingMode.valueOf(pList.get(PR_WRITING_MODE).getEnum()) );
//Bind extension properties
widowContentLimit = pList.get(PR_X_WIDOW_CONTENT_LIMIT).getLength();
@@ -147,13 +155,19 @@ public class Table extends TableFObj implements ColumnNumberManagerHolder, Break
getFOValidationEventProducer().unimplementedFeature(this, getName(),
"table-layout=\"auto\"", getLocator());
}
- if (!isSeparateBorderModel()
- && getCommonBorderPaddingBackground().hasPadding(
- ValidationPercentBaseContext.getPseudoContext())) {
- //See "17.6.2 The collapsing border model" in CSS2
- TableEventProducer eventProducer = TableEventProducer.Provider.get(
- getUserAgent().getEventBroadcaster());
- eventProducer.noTablePaddingWithCollapsingBorderModel(this, getLocator());
+ if (!isSeparateBorderModel()) {
+ if (borderCollapse == EN_COLLAPSE_WITH_PRECEDENCE) {
+ getFOValidationEventProducer().unimplementedFeature(this, getName(),
+ "border-collapse=\"collapse-with-precedence\"; defaulting to \"collapse\"", getLocator());
+ borderCollapse = EN_COLLAPSE;
+ }
+ if (getCommonBorderPaddingBackground().hasPadding(
+ ValidationPercentBaseContext.getPseudoContext())) {
+ //See "17.6.2 The collapsing border model" in CSS2
+ TableEventProducer eventProducer = TableEventProducer.Provider.get(
+ getUserAgent().getEventBroadcaster());
+ eventProducer.noTablePaddingWithCollapsingBorderModel(this, getLocator());
+ }
}
/* Store reference to the property list, so
@@ -510,9 +524,34 @@ public class Table extends TableFObj implements ColumnNumberManagerHolder, Break
return borderSeparation;
}
- /** @return the "writing-mode" FO trait */
- public int getWritingMode() {
- return writingMode;
+ /** {@inheritDoc} */
+ public Direction getInlineProgressionDirection() {
+ return writingModeTraits.getInlineProgressionDirection();
+ }
+
+ /** {@inheritDoc} */
+ public Direction getBlockProgressionDirection() {
+ return writingModeTraits.getBlockProgressionDirection();
+ }
+
+ /** {@inheritDoc} */
+ public Direction getColumnProgressionDirection() {
+ return writingModeTraits.getColumnProgressionDirection();
+ }
+
+ /** {@inheritDoc} */
+ public Direction getRowProgressionDirection() {
+ return writingModeTraits.getRowProgressionDirection();
+ }
+
+ /** {@inheritDoc} */
+ public Direction getShiftDirection() {
+ return writingModeTraits.getShiftDirection();
+ }
+
+ /** {@inheritDoc} */
+ public WritingMode getWritingMode() {
+ return writingModeTraits.getWritingMode();
}
/** @return the "fox:widow-content-limit" extension FO trait */
@@ -561,4 +600,24 @@ public class Table extends TableFObj implements ColumnNumberManagerHolder, Break
RowGroupBuilder getRowGroupBuilder() {
return rowGroupBuilder;
}
+
+ @Override
+ protected Stack collectDelimitedTextRanges ( Stack ranges, DelimitedTextRange currentRange ) {
+ // header sub-tree
+ TableHeader header = getTableHeader();
+ if ( header != null ) {
+ ranges = header.collectDelimitedTextRanges ( ranges );
+ }
+ // footer sub-tree
+ TableFooter footer = getTableFooter();
+ if ( footer != null ) {
+ ranges = footer.collectDelimitedTextRanges ( ranges );
+ }
+ // body sub-tree
+ for ( Iterator it = getChildNodes(); ( it != null ) && it.hasNext();) {
+ ranges = ( (FONode) it.next() ).collectDelimitedTextRanges ( ranges );
+ }
+ return ranges;
+ }
+
}
diff --git a/src/java/org/apache/fop/fo/pagination/AbstractPageSequence.java b/src/java/org/apache/fop/fo/pagination/AbstractPageSequence.java
index 8640ab19b..d1ccf7273 100644
--- a/src/java/org/apache/fop/fo/pagination/AbstractPageSequence.java
+++ b/src/java/org/apache/fop/fo/pagination/AbstractPageSequence.java
@@ -24,6 +24,8 @@ import org.apache.fop.datatypes.Numeric;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.PropertyList;
+import org.apache.fop.fo.properties.CommonAccessibility;
+import org.apache.fop.fo.properties.CommonAccessibilityHolder;
/**
* Abstract base class for the <a href="http://www.w3.org/TR/xsl/#fo_page-sequence">
@@ -31,9 +33,8 @@ import org.apache.fop.fo.PropertyList;
* <a href="http://xmlgraphics.apache.org/fop/0.95/extensions.html#external-document">
* <code>fox:external-document</code></a> extension object.
*/
-public abstract class AbstractPageSequence extends FObj {
+public abstract class AbstractPageSequence extends FObj implements CommonAccessibilityHolder {
- // The value of properties relevant for fo:page-sequence.
/** initial page number */
protected Numeric initialPageNumber;
/** forced page count */
@@ -42,11 +43,12 @@ public abstract class AbstractPageSequence extends FObj {
private int letterValue;
private char groupingSeparator;
private int groupingSize;
- private Numeric referenceOrientation; //XSL 1.1
+ private Numeric referenceOrientation;
private String language;
private String country;
private String numberConversionFeatures;
- // End of property values
+
+ private CommonAccessibility commonAccessibility;
private PageNumberGenerator pageNumberGenerator;
@@ -76,6 +78,7 @@ public abstract class AbstractPageSequence extends FObj {
language = pList.get(PR_LANGUAGE).getString();
country = pList.get(PR_COUNTRY).getString();
numberConversionFeatures = pList.get(PR_X_NUMBER_CONVERSION_FEATURES).getString();
+ commonAccessibility = CommonAccessibility.getInstance(pList);
}
/** {@inheritDoc} */
@@ -130,6 +133,10 @@ public abstract class AbstractPageSequence extends FObj {
return pageNumberGenerator.makeFormattedPageNumber(pageNumber);
}
+ public CommonAccessibility getCommonAccessibility() {
+ return commonAccessibility;
+ }
+
/**
* Public accessor for the ancestor Root.
* @return the ancestor Root
diff --git a/src/java/org/apache/fop/fo/pagination/Flow.java b/src/java/org/apache/fop/fo/pagination/Flow.java
index 153f06fc1..981485e32 100644
--- a/src/java/org/apache/fop/fo/pagination/Flow.java
+++ b/src/java/org/apache/fop/fo/pagination/Flow.java
@@ -26,16 +26,19 @@ import org.apache.fop.fo.FONode;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.ValidationException;
+import org.apache.fop.fo.properties.CommonAccessibility;
+import org.apache.fop.fo.properties.CommonAccessibilityHolder;
/**
* Class modelling the <a href="http://www.w3.org/TR/xsl/#fo_flow">
* <code>fo:flow</code></a> object.
*
*/
-public class Flow extends FObj {
- // The value of properties relevant for fo:flow.
+public class Flow extends FObj implements CommonAccessibilityHolder {
+
private String flowName;
- // End of property values
+
+ private CommonAccessibility commonAccessibility;
/** used for FO validation */
private boolean blockItemFound = false;
@@ -52,6 +55,7 @@ public class Flow extends FObj {
public void bind(PropertyList pList) throws FOPException {
super.bind(pList);
flowName = pList.get(PR_FLOW_NAME).getString();
+ commonAccessibility = CommonAccessibility.getInstance(pList);
}
/** {@inheritDoc} */
@@ -120,6 +124,10 @@ public class Flow extends FObj {
return flowName;
}
+ public CommonAccessibility getCommonAccessibility() {
+ return commonAccessibility;
+ }
+
/** {@inheritDoc} */
public String getLocalName() {
return "flow";
diff --git a/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java b/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java
index 789b8d4ed..0e7f3d978 100644
--- a/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java
+++ b/src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java
@@ -348,9 +348,7 @@ public class CommonBorderPaddingBackground {
*/
public static CommonBorderPaddingBackground getInstance(PropertyList pList)
throws PropertyException {
-
- CommonBorderPaddingBackground newInstance
- = new CommonBorderPaddingBackground(pList);
+ CommonBorderPaddingBackground newInstance = new CommonBorderPaddingBackground(pList);
CommonBorderPaddingBackground cachedInstance = null;
/* if padding-* and background-position-* resolve to absolute lengths
* the whole instance can be cached */
@@ -368,33 +366,33 @@ public class CommonBorderPaddingBackground {
|| newInstance.backgroundPositionVertical.isAbsolute())) {
cachedInstance = CACHE.fetch(newInstance);
}
-
- /* for non-cached, or not-yet-cached instances, preload the image */
- if ((cachedInstance == null
- || cachedInstance == newInstance)
+ synchronized (newInstance.backgroundImage.intern()) {
+ /* for non-cached, or not-yet-cached instances, preload the image */
+ if ((cachedInstance == null || cachedInstance == newInstance)
&& !("".equals(newInstance.backgroundImage))) {
- //Additional processing: preload image
- String uri = URISpecification.getURL(newInstance.backgroundImage);
- FObj fobj = pList.getFObj();
- FOUserAgent userAgent = pList.getFObj().getUserAgent();
- ImageManager manager = userAgent.getFactory().getImageManager();
- ImageSessionContext sessionContext = userAgent.getImageSessionContext();
- ImageInfo info;
- try {
- info = manager.getImageInfo(uri, sessionContext);
- newInstance.backgroundImageInfo = info;
- } catch (ImageException e) {
- ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
- fobj.getUserAgent().getEventBroadcaster());
- eventProducer.imageError(fobj, uri, e, fobj.getLocator());
- } catch (FileNotFoundException fnfe) {
- ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
- fobj.getUserAgent().getEventBroadcaster());
- eventProducer.imageNotFound(fobj, uri, fnfe, fobj.getLocator());
- } catch (IOException ioe) {
- ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
- fobj.getUserAgent().getEventBroadcaster());
- eventProducer.imageIOError(fobj, uri, ioe, fobj.getLocator());
+ //Additional processing: preload image
+ String uri = URISpecification.getURL(newInstance.backgroundImage);
+ FObj fobj = pList.getFObj();
+ FOUserAgent userAgent = pList.getFObj().getUserAgent();
+ ImageManager manager = userAgent.getFactory().getImageManager();
+ ImageSessionContext sessionContext = userAgent.getImageSessionContext();
+ ImageInfo info;
+ try {
+ info = manager.getImageInfo(uri, sessionContext);
+ newInstance.backgroundImageInfo = info;
+ } catch (ImageException e) {
+ ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
+ fobj.getUserAgent().getEventBroadcaster());
+ eventProducer.imageError(fobj, uri, e, fobj.getLocator());
+ } catch (FileNotFoundException fnfe) {
+ ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
+ fobj.getUserAgent().getEventBroadcaster());
+ eventProducer.imageNotFound(fobj, uri, fnfe, fobj.getLocator());
+ } catch (IOException ioe) {
+ ResourceEventProducer eventProducer = ResourceEventProducer.Provider.get(
+ fobj.getUserAgent().getEventBroadcaster());
+ eventProducer.imageIOError(fobj, uri, ioe, fobj.getLocator());
+ }
}
}
diff --git a/src/java/org/apache/fop/fo/properties/FontFamilyProperty.java b/src/java/org/apache/fop/fo/properties/FontFamilyProperty.java
index ff7619928..b59c22de6 100644
--- a/src/java/org/apache/fop/fo/properties/FontFamilyProperty.java
+++ b/src/java/org/apache/fop/fo/properties/FontFamilyProperty.java
@@ -19,8 +19,6 @@
package org.apache.fop.fo.properties;
-import java.util.Iterator;
-
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.expr.PropertyException;
@@ -34,8 +32,6 @@ public final class FontFamilyProperty extends ListProperty {
private static final PropertyCache<FontFamilyProperty> CACHE
= new PropertyCache<FontFamilyProperty>();
- private int hash = 0;
-
/**
* Inner class for creating instances of ListProperty
*/
@@ -151,30 +147,4 @@ public final class FontFamilyProperty extends ListProperty {
}
}
- /** {@inheritDoc} */
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
-
- if (o instanceof FontFamilyProperty) {
- FontFamilyProperty ffp = (FontFamilyProperty) o;
- return (this.list != null
- && this.list.equals(ffp.list));
- }
- return false;
- }
-
- /** {@inheritDoc} */
- public int hashCode() {
- if (this.hash == 0) {
- int hash = 17;
- for (Iterator i = list.iterator(); i.hasNext();) {
- Property p = (Property) i.next();
- hash = 37 * hash + (p == null ? 0 : p.hashCode());
- }
- this.hash = hash;
- }
- return this.hash;
- }
}
diff --git a/src/java/org/apache/fop/fo/properties/SpaceProperty.java b/src/java/org/apache/fop/fo/properties/SpaceProperty.java
index 641ec3baf..f7bdc60d7 100644
--- a/src/java/org/apache/fop/fo/properties/SpaceProperty.java
+++ b/src/java/org/apache/fop/fo/properties/SpaceProperty.java
@@ -23,6 +23,7 @@ import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.PropertyList;
import org.apache.fop.fo.expr.PropertyException;
+import org.apache.fop.util.CompareUtil;
/**
* Base class used for handling properties of the fo:space-before and
@@ -168,4 +169,27 @@ public class SpaceProperty extends LengthRangeProperty {
return this;
}
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = super.hashCode();
+ result = prime * result + CompareUtil.getHashCode(precedence);
+ result = prime * result + CompareUtil.getHashCode(conditionality);
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof SpaceProperty)) {
+ return false;
+ }
+ SpaceProperty other = (SpaceProperty) obj;
+ return super.equals(obj)
+ && CompareUtil.equal(precedence, other.precedence)
+ && CompareUtil.equal(conditionality, other.conditionality);
+ }
+
}
diff --git a/src/java/org/apache/fop/fonts/autodetect/FontFileFinder.java b/src/java/org/apache/fop/fonts/autodetect/FontFileFinder.java
index 3c1a94f63..8100c4b9b 100644
--- a/src/java/org/apache/fop/fonts/autodetect/FontFileFinder.java
+++ b/src/java/org/apache/fop/fonts/autodetect/FontFileFinder.java
@@ -168,7 +168,6 @@ public class FontFileFinder extends DirectoryWalker implements FontFinder {
*/
public List<URL> find(String dir) throws IOException {
List<URL> results = new java.util.ArrayList<URL>();
- super.walk(new File(dir), results);
File directory = new File(dir);
if (!directory.isDirectory()) {
eventListener.fontDirectoryNotFound(this, dir);
diff --git a/src/java/org/apache/fop/fonts/truetype/TTFFile.java b/src/java/org/apache/fop/fonts/truetype/TTFFile.java
index 5860e5cd5..f80226e26 100644
--- a/src/java/org/apache/fop/fonts/truetype/TTFFile.java
+++ b/src/java/org/apache/fop/fonts/truetype/TTFFile.java
@@ -533,18 +533,6 @@ public class TTFFile {
unicodeMappings.add(new UnicodeMapping(glyphIdx, j));
mtxTab[glyphIdx].getUnicodeIndex().add(new Integer(j));
- if (encodingID == 0 && j >= 0xF020 && j <= 0xF0FF) {
- //Experimental: Mapping 0xF020-0xF0FF to 0x0020-0x00FF
- //Tested with Wingdings and Symbol TTF fonts which map their
- //glyphs in the region 0xF020-0xF0FF.
- int mapped = j - 0xF000;
- if (!eightBitGlyphs.get(mapped)) {
- //Only map if Unicode code point hasn't been mapped before
- unicodeMappings.add(new UnicodeMapping(glyphIdx, mapped));
- mtxTab[glyphIdx].getUnicodeIndex().add(new Integer(mapped));
- }
- }
-
// Also add winAnsiWidth
List<Integer> v = ansiIndex.get(new Integer(j));
if (v != null) {
diff --git a/src/java/org/apache/fop/fonts/type1/AFMParser.java b/src/java/org/apache/fop/fonts/type1/AFMParser.java
index 3117f3bcb..f2711be3c 100644
--- a/src/java/org/apache/fop/fonts/type1/AFMParser.java
+++ b/src/java/org/apache/fop/fonts/type1/AFMParser.java
@@ -20,11 +20,12 @@
package org.apache.fop.fonts.type1;
import java.awt.Rectangle;
-import java.beans.Statement;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
@@ -313,20 +314,24 @@ public class AFMParser {
}
private abstract static class BeanSetter extends AbstractValueHandler {
- private String method;
+ protected String method;
public BeanSetter(String variable) {
this.method = "set" + variable;
}
- protected void setValue(Object target, Object value) {
- //Uses Java Beans API
- Statement statement = new Statement(target, method, new Object[] {value});
+ protected void setValue(Object target, Class<?> argType, Object value) {
+ Class<?> c = target.getClass();
+
try {
- statement.execute();
- } catch (Exception e) {
- //Should never happen
- throw new RuntimeException("Bean error: " + e.getMessage());
+ Method mth = c.getMethod(method, argType);
+ mth.invoke(target, value);
+ } catch ( NoSuchMethodException e ) {
+ throw new RuntimeException("Bean error: " + e.getMessage(), e);
+ } catch ( IllegalAccessException e ) {
+ throw new RuntimeException("Bean error: " + e.getMessage(), e);
+ } catch ( InvocationTargetException e ) {
+ throw new RuntimeException("Bean error: " + e.getMessage(), e);
}
}
}
@@ -340,7 +345,7 @@ public class AFMParser {
public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
String s = getStringValue(line, startpos);
Object obj = stack.peek();
- setValue(obj, s);
+ setValue(obj, String.class, s);
}
}
@@ -353,7 +358,7 @@ public class AFMParser {
public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
NamedCharacter ch = new NamedCharacter(getStringValue(line, startpos));
Object obj = stack.peek();
- setValue(obj, ch);
+ setValue(obj, NamedCharacter.class, ch);
}
}
@@ -368,7 +373,7 @@ public class AFMParser {
public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
Number num = getNumberValue(line, startpos);
- setValue(getContextObject(stack), num);
+ setValue(getContextObject(stack), Number.class, num);
}
}
@@ -379,7 +384,7 @@ public class AFMParser {
public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
int value = getIntegerValue(line, startpos);
- setValue(getContextObject(stack), new Integer(value));
+ setValue(getContextObject(stack), int.class, new Integer(value));
}
}
@@ -390,7 +395,7 @@ public class AFMParser {
public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
double value = getDoubleValue(line, startpos);
- setValue(getContextObject(stack), new Double(value));
+ setValue(getContextObject(stack), double.class, new Double(value));
}
}
@@ -424,7 +429,7 @@ public class AFMParser {
public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
double value = getDoubleValue(line, startpos);
- setValue(getContextObject(stack), new Double(value));
+ setValue(getContextObject(stack), double.class, new Double(value));
}
}
@@ -441,14 +446,18 @@ public class AFMParser {
public void parse(String line, int startpos, Stack<Object> stack) throws IOException {
Boolean b = getBooleanValue(line, startpos);
- //Uses Java Beans API
- Statement statement = new Statement(getContextObject(stack),
- method, new Object[] {b});
+
+ Object target = getContextObject(stack);
+ Class<?> c = target.getClass();
try {
- statement.execute();
- } catch (Exception e) {
- //Should never happen
- throw new RuntimeException("Bean error: " + e.getMessage());
+ Method mth = c.getMethod(method, boolean.class);
+ mth.invoke(target, b);
+ } catch ( NoSuchMethodException e ) {
+ throw new RuntimeException("Bean error: " + e.getMessage(), e);
+ } catch ( IllegalAccessException e ) {
+ throw new RuntimeException("Bean error: " + e.getMessage(), e);
+ } catch ( InvocationTargetException e ) {
+ throw new RuntimeException("Bean error: " + e.getMessage(), e);
}
}
}
diff --git a/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java b/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
index dc87f9f1d..5fa411101 100644
--- a/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
+++ b/src/java/org/apache/fop/layoutmgr/AbstractBreaker.java
@@ -420,7 +420,7 @@ public abstract class AbstractBreaker {
alg.setConstantLineWidth(flowBPD);
int optimalPageCount = alg.findBreakingPoints(effectiveList, 1, true,
BreakingAlgorithm.ALL_BREAKS);
- if (alg.getIPDdifference() != 0) {
+ if ( Math.abs ( alg.getIPDdifference() ) > 1 ) {
addAreas(alg, optimalPageCount, blockList, effectiveList);
// *** redo Phase 1 ***
log.trace("IPD changes after page " + optimalPageCount);
diff --git a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java
index d227b7060..0089f228f 100644
--- a/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/AbstractLayoutManager.java
@@ -41,8 +41,7 @@ import org.apache.fop.fo.flow.RetrieveMarker;
/**
* The base class for most LayoutManagers.
*/
-public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager
- implements Constants {
+public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager implements Constants {
/** logging instance */
private static Log log = LogFactory.getLog(AbstractLayoutManager.class);
diff --git a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
index aab505d8b..adce89ac0 100644
--- a/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/BlockContainerLayoutManager.java
@@ -44,8 +44,8 @@ import org.apache.fop.traits.SpaceVal;
/**
* LayoutManager for a block-container FO.
*/
-public class BlockContainerLayoutManager extends BlockStackingLayoutManager
- implements ConditionalElementListener {
+public class BlockContainerLayoutManager extends BlockStackingLayoutManager implements
+ ConditionalElementListener, BreakOpportunity {
/**
* logging instance
@@ -86,6 +86,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
private MinOptMax effSpaceBefore;
private MinOptMax effSpaceAfter;
+ private int horizontalOverflow;
private double contentRectOffsetX = 0;
private double contentRectOffsetY = 0;
@@ -401,7 +402,7 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider.get(
getBlockContainerFO().getUserAgent().getEventBroadcaster());
boolean canRecover = (getBlockContainerFO().getOverflow() != EN_ERROR_IF_OVERFLOW);
- eventProducer.viewportOverflow(this, getBlockContainerFO().getName(),
+ eventProducer.viewportBPDOverflow(this, getBlockContainerFO().getName(),
breaker.getOverflowAmount(), needClip(), canRecover,
getBlockContainerFO().getLocator());
}
@@ -553,10 +554,18 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider.get(
getBlockContainerFO().getUserAgent().getEventBroadcaster());
boolean canRecover = (getBlockContainerFO().getOverflow() != EN_ERROR_IF_OVERFLOW);
- eventProducer.viewportOverflow(this, getBlockContainerFO().getName(),
+ eventProducer.viewportBPDOverflow(this, getBlockContainerFO().getName(),
breaker.getOverflowAmount(), needClip(), canRecover,
getBlockContainerFO().getLocator());
}
+ // this handles the IPD (horizontal) overflow
+ if (this.horizontalOverflow > 0) {
+ BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider
+ .get(getBlockContainerFO().getUserAgent().getEventBroadcaster());
+ boolean canRecover = (getBlockContainerFO().getOverflow() != EN_ERROR_IF_OVERFLOW);
+ eventProducer.viewportIPDOverflow(this, getBlockContainerFO().getName(),
+ this.horizontalOverflow, needClip(), canRecover, getBlockContainerFO().getLocator());
+ }
}
setFinished(true);
@@ -1027,6 +1036,18 @@ public class BlockContainerLayoutManager extends BlockStackingLayoutManager
}
}
+ /** {@inheritDoc} */
+ public boolean handleOverflow(int milliPoints) {
+ if (milliPoints > this.horizontalOverflow) {
+ this.horizontalOverflow = milliPoints;
+ }
+ return true;
+ }
+
+ public int getBreakBefore() {
+ return BreakOpportunityHelper.getBreakBefore(this);
+ }
+
}
diff --git a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
index 9c3639f93..03b2d380c 100644
--- a/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/BlockLayoutManager.java
@@ -43,8 +43,8 @@ import org.apache.fop.traits.SpaceVal;
/**
* LayoutManager for a block FO.
*/
-public class BlockLayoutManager extends BlockStackingLayoutManager
- implements ConditionalElementListener {
+public class BlockLayoutManager extends BlockStackingLayoutManager implements ConditionalElementListener,
+ BreakOpportunity {
/** logging instance */
private static Log log = LogFactory.getLog(BlockLayoutManager.class);
@@ -504,4 +504,8 @@ public class BlockLayoutManager extends BlockStackingLayoutManager
return true;
}
+ public int getBreakBefore() {
+ return BreakOpportunityHelper.getBreakBefore(this);
+ }
+
}
diff --git a/src/java/org/apache/fop/layoutmgr/BlockLevelEventProducer.java b/src/java/org/apache/fop/layoutmgr/BlockLevelEventProducer.java
index 7d3964181..d9de09a46 100644
--- a/src/java/org/apache/fop/layoutmgr/BlockLevelEventProducer.java
+++ b/src/java/org/apache/fop/layoutmgr/BlockLevelEventProducer.java
@@ -89,19 +89,30 @@ public interface BlockLevelEventProducer extends EventProducer {
void overconstrainedAdjustEndIndent(Object source, String elementName, int amount, Locator loc);
/**
- * Contents overflow a viewport.
+ * Contents IPD overflow a viewport.
* @param source the event source
* @param elementName the formatting object
* @param amount the amount by which the contents overflow (in mpt)
* @param clip true if the content will be clipped
* @param canRecover indicates whether FOP can recover from this problem and continue working
* @param loc the location of the error or null
- * @throws LayoutException the layout error provoked by the method call
- * @event.severity FATAL
+ * @event.severity ERROR
*/
- void viewportOverflow(Object source, String elementName,
- int amount, boolean clip, boolean canRecover,
- Locator loc) throws LayoutException;
+ void viewportIPDOverflow(Object source, String elementName, int amount, boolean clip,
+ boolean canRecover, Locator loc);
+
+ /**
+ * Contents BPD overflow a viewport.
+ * @param source the event source
+ * @param elementName the formatting object
+ * @param amount the amount by which the contents overflow (in mpt)
+ * @param clip true if the content will be clipped
+ * @param canRecover indicates whether FOP can recover from this problem and continue working
+ * @param loc the location of the error or null
+ * @event.severity ERROR
+ */
+ void viewportBPDOverflow(Object source, String elementName, int amount, boolean clip,
+ boolean canRecover, Locator loc);
/**
* Contents overflow a region viewport.
diff --git a/src/java/org/apache/fop/layoutmgr/BlockLevelEventProducer.xml b/src/java/org/apache/fop/layoutmgr/BlockLevelEventProducer.xml
index a89f9ed32..d3e243a63 100644
--- a/src/java/org/apache/fop/layoutmgr/BlockLevelEventProducer.xml
+++ b/src/java/org/apache/fop/layoutmgr/BlockLevelEventProducer.xml
@@ -22,7 +22,8 @@
<message key="tableFixedAutoWidthNotSupported">table-layout="fixed" and width="auto", but auto-layout not supported =&gt; assuming width="100%".{{locator}}</message>
<message key="objectTooWide">The extent in inline-progression-direction (width) of a {elementName} is bigger than the available space ({effIPD}mpt &gt; {maxIPD}mpt).{{locator}}</message>
<message key="overconstrainedAdjustEndIndent">An {elementName} {{locator}} is wider than the available room in inline-progression-dimension. Adjusting end-indent based on overconstrained geometry rules (XSL 1.1, ch. 5.3.4)</message>
- <message key="viewportOverflow">Content overflows the viewport of an {elementName} in block-progression direction by {amount} millipoints.{clip,if, Content will be clipped.}{{locator}}</message>
+ <message key="viewportIPDOverflow">Content overflows the viewport of an {elementName} in inline-progression direction by {amount} millipoints.{clip,if, Content will be clipped.}{{locator}}</message>
+ <message key="viewportBPDOverflow">Content overflows the viewport of an {elementName} in block-progression direction by {amount} millipoints.{clip,if, Content will be clipped.}{{locator}}</message>
<message key="regionOverflow">Content overflows the viewport of the {elementName} on page {page} in block-progression direction by {amount} millipoints.{clip,if, Content will be clipped.}{{locator}}</message>
<message key="flowNotMappingToRegionBody">Flow "{flowName}" does not map to the region-body in page-master "{masterName}". FOP presently does not support this.{{locator}}</message>
<message key="pageSequenceMasterExhausted">Subsequences exhausted in page-sequence-master "{pageSequenceMasterName}", {canRecover,if,using previous subsequence,cannot recover}.{{locator}}</message>
diff --git a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
index 56c02795c..78ab6711a 100644
--- a/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/BlockStackingLayoutManager.java
@@ -38,7 +38,6 @@ import org.apache.fop.fo.properties.KeepProperty;
import org.apache.fop.fo.properties.SpaceProperty;
import org.apache.fop.layoutmgr.inline.InlineLayoutManager;
import org.apache.fop.traits.MinOptMax;
-import org.apache.fop.util.BreakUtil;
import org.apache.fop.util.ListUtil;
/**
@@ -1036,7 +1035,7 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
* @return true if an element has been added due to a break-before.
*/
protected boolean addKnuthElementsForBreakBefore(List returnList, LayoutContext context) {
- int breakBefore = getBreakBefore();
+ int breakBefore = BreakOpportunityHelper.getBreakBefore(this);
if (breakBefore == EN_PAGE
|| breakBefore == EN_COLUMN
|| breakBefore == EN_EVEN_PAGE
@@ -1051,27 +1050,6 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
}
/**
- * Returns the break-before value of the current formatting object.
- * @return the break-before value (Constants.EN_*)
- */
- private int getBreakBefore() {
- int breakBefore = EN_AUTO;
- if (fobj instanceof BreakPropertySet) {
- breakBefore = ((BreakPropertySet)fobj).getBreakBefore();
- }
- if (true /* uncomment to only partially merge: && breakBefore != EN_AUTO*/) {
- LayoutManager lm = getChildLM();
- //It is assumed this is only called when the first LM is active.
- if (lm instanceof BlockStackingLayoutManager) {
- BlockStackingLayoutManager bslm = (BlockStackingLayoutManager)lm;
- breakBefore = BreakUtil.compareBreakClasses(
- breakBefore, bslm.getBreakBefore());
- }
- }
- return breakBefore;
- }
-
- /**
* Creates Knuth elements for break-after and adds them to the return list.
* @param returnList return list to add the additional elements to
* @param context the layout context
@@ -1249,5 +1227,16 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager
// TODO startIndent, endIndent
}
+ /**
+ * Whether this LM can handle horizontal overflow error messages (only a BlockContainerLayoutManager can).
+ * @param milliPoints horizontal overflow
+ * @return true if handled by a BlockContainerLayoutManager
+ */
+ public boolean handleOverflow(int milliPoints) {
+ if (getParent() instanceof BlockStackingLayoutManager) {
+ return ((BlockStackingLayoutManager) getParent()).handleOverflow(milliPoints);
+ }
+ return false;
+ }
}
diff --git a/src/java/org/apache/fop/layoutmgr/BreakOpportunity.java b/src/java/org/apache/fop/layoutmgr/BreakOpportunity.java
new file mode 100644
index 000000000..668f112c9
--- /dev/null
+++ b/src/java/org/apache/fop/layoutmgr/BreakOpportunity.java
@@ -0,0 +1,36 @@
+/*
+ * 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.layoutmgr;
+
+/**
+ * Defines methods to evaluate break opportunities at a particular location in the tree of
+ * layout managers.
+ */
+public interface BreakOpportunity {
+
+ /**
+ * Returns the highest priority break-before value on this layout manager or its
+ * relevant descendants.
+ *
+ * @return the break-before value (Constants.EN_*)
+ */
+ int getBreakBefore();
+
+}
diff --git a/src/java/org/apache/fop/layoutmgr/BreakOpportunityHelper.java b/src/java/org/apache/fop/layoutmgr/BreakOpportunityHelper.java
new file mode 100644
index 000000000..a3992567f
--- /dev/null
+++ b/src/java/org/apache/fop/layoutmgr/BreakOpportunityHelper.java
@@ -0,0 +1,54 @@
+/*
+ * 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.layoutmgr;
+
+import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.properties.BreakPropertySet;
+import org.apache.fop.util.BreakUtil;
+
+/**
+ * Helper implementations of the {@link BreakOpportunity} methods.
+ */
+public final class BreakOpportunityHelper {
+
+ private BreakOpportunityHelper() { }
+
+ /**
+ * Returns the break opportunity before the given layout manager. There is a break
+ * opportunity if the LM's FO has the break-before property set, or if there is a
+ * break opportunity before its first child LM.
+ *
+ * @return the break-before value (Constants.EN_*)
+ */
+ public static int getBreakBefore(AbstractLayoutManager layoutManager) {
+ int breakBefore = Constants.EN_AUTO;
+ if (layoutManager.getFObj() instanceof BreakPropertySet) {
+ breakBefore = ((BreakPropertySet) layoutManager.getFObj()).getBreakBefore();
+ }
+ LayoutManager childLM = layoutManager.getChildLM();
+ // It is assumed this is only called when the first LM is active.
+ if (childLM instanceof BreakOpportunity) {
+ BreakOpportunity bo = (BreakOpportunity) childLM;
+ breakBefore = BreakUtil.compareBreakClasses(breakBefore, bo.getBreakBefore());
+ }
+ return breakBefore;
+ }
+
+}
diff --git a/src/java/org/apache/fop/layoutmgr/inline/ImageLayout.java b/src/java/org/apache/fop/layoutmgr/inline/ImageLayout.java
index 4c6bc1f3f..31ede9aee 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/ImageLayout.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/ImageLayout.java
@@ -228,6 +228,9 @@ public class ImageLayout implements Constants {
} else if (rat1 > rat2) {
adjusted.width = (int)(rat2 * size.width);
adjusted.height = effHeight;
+ } else {
+ adjusted.width = effWidth;
+ adjusted.height = effHeight;
}
} else {
adjusted.width = effWidth;
diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java
index 1eb91e0ab..e87b29b2d 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/InlineLayoutManager.java
@@ -388,6 +388,13 @@ public class InlineLayoutManager extends InlineStackingLayoutManager {
}
lastSequence = ListUtil.getLast(returnList);
lastChildLM = curLM;
+ // the context used to create this childLC above was applied a LayoutContext.SUPPRESS_BREAK_BEFORE
+ // in the getNextChildElements() method of the parent BlockLayoutManger; as a consequence all
+ // line breaks in blocks nested inside the inline associated with this ILM are being supressed;
+ // here we revert that supression; we do not need to do that for the first element since that
+ // is handled by the getBreakBefore() method of the wrapping BlockStackingLayoutManager.
+ // Note: this fix seems to work but is far from being the ideal way to do this
+ childLC.setFlags(LayoutContext.SUPPRESS_BREAK_BEFORE, false);
}
if (lastSequence != null) {
diff --git a/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java
index 4a203d55e..3e9b85742 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/InlineStackingLayoutManager.java
@@ -28,6 +28,8 @@ import org.apache.fop.area.inline.Space;
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.properties.SpaceProperty;
import org.apache.fop.layoutmgr.AbstractLayoutManager;
+import org.apache.fop.layoutmgr.BreakOpportunity;
+import org.apache.fop.layoutmgr.BreakOpportunityHelper;
import org.apache.fop.layoutmgr.KnuthElement;
import org.apache.fop.layoutmgr.LayoutContext;
import org.apache.fop.layoutmgr.NonLeafPosition;
@@ -39,8 +41,8 @@ import org.apache.fop.traits.MinOptMax;
* which stack children in the inline direction, such as Inline or
* Line. It should not be instantiated directly.
*/
-public abstract class InlineStackingLayoutManager extends AbstractLayoutManager
- implements InlineLevelLayoutManager {
+public abstract class InlineStackingLayoutManager extends AbstractLayoutManager implements
+ InlineLevelLayoutManager, BreakOpportunity {
/**
* Size of border and padding in BPD (ie, before and after).
@@ -385,4 +387,9 @@ public abstract class InlineStackingLayoutManager extends AbstractLayoutManager
return returnList;
}
+
+ public int getBreakBefore() {
+ return BreakOpportunityHelper.getBreakBefore(this);
+ }
+
}
diff --git a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
index 3b2f11ea2..27958f7e0 100644
--- a/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/inline/LineLayoutManager.java
@@ -45,6 +45,7 @@ import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.hyphenation.Hyphenation;
import org.apache.fop.hyphenation.Hyphenator;
import org.apache.fop.layoutmgr.Adjustment;
+import org.apache.fop.layoutmgr.BlockLayoutManager;
import org.apache.fop.layoutmgr.BlockLevelLayoutManager;
import org.apache.fop.layoutmgr.BreakElement;
import org.apache.fop.layoutmgr.BreakingAlgorithm;
@@ -389,7 +390,10 @@ public class LineLayoutManager extends InlineStackingLayoutManager
if (log.isWarnEnabled()) {
int lack = difference + bestActiveNode.availableShrink;
- if (lack < 0) {
+ // if this LLM is nested inside a BlockContainerLayoutManager that is constraining
+ // the available width and thus responsible for the overflow then we do not issue
+ // warning event here and instead let the BCLM handle that at a later stage
+ if (lack < 0 && !handleOverflow(-lack)) {
InlineLevelEventProducer eventProducer
= InlineLevelEventProducer.Provider.get(
getFObj().getUserAgent().getEventBroadcaster());
@@ -1635,4 +1639,15 @@ public class LineLayoutManager extends InlineStackingLayoutManager
return true;
}
+ /**
+ * Whether this LM can handle horizontal overflow error messages (only a BlockContainerLayoutManager can).
+ * @param milliPoints horizontal overflow
+ * @return true if handled by a BlockContainerLayoutManager
+ */
+ public boolean handleOverflow(int milliPoints) {
+ if (getParent() instanceof BlockLayoutManager) {
+ return ((BlockLayoutManager) getParent()).handleOverflow(milliPoints);
+ }
+ return false;
+ }
}
diff --git a/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModel.java b/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModel.java
index 7221d4fee..88b89e1db 100644
--- a/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModel.java
+++ b/src/java/org/apache/fop/layoutmgr/table/CollapsingBorderModel.java
@@ -49,7 +49,7 @@ public abstract class CollapsingBorderModel {
//These statics are used singleton-style. No MT issues here.
private static CollapsingBorderModel collapse = null;
- private static CollapsingBorderModel collapseWithPrecedence = null;
+ // private static CollapsingBorderModel collapseWithPrecedence = null;
/**
* @param borderCollapse border collapse control
@@ -63,10 +63,7 @@ public abstract class CollapsingBorderModel {
}
return collapse;
case Constants.EN_COLLAPSE_WITH_PRECEDENCE:
- if (collapseWithPrecedence == null) {
- //collapseWithPrecedence = new CollapsingBorderModelWithPrecedence();
- }
- return collapseWithPrecedence;
+ throw new UnsupportedOperationException ( "collapse-with-precedence not yet supported" );
default:
throw new IllegalArgumentException("Illegal border-collapse mode.");
}
diff --git a/src/java/org/apache/fop/layoutmgr/table/ColumnSetup.java b/src/java/org/apache/fop/layoutmgr/table/ColumnSetup.java
index aaccbd0d3..b0ad22386 100644
--- a/src/java/org/apache/fop/layoutmgr/table/ColumnSetup.java
+++ b/src/java/org/apache/fop/layoutmgr/table/ColumnSetup.java
@@ -245,13 +245,14 @@ public class ColumnSetup {
* the left-most column; otherwise, the first column is the left-most
* column.
* @param col column index (1 is first column)
+ * @param nrColSpan number columns spanned (for calculating offset in rtl mode)
* @param context the context for percentage based calculations
* @return the X offset of the requested column
*/
- public int getXOffset(int col, PercentBaseContext context) {
+ public int getXOffset(int col, int nrColSpan, PercentBaseContext context) {
// TODO handle vertical WMs [GA]
if ( (wmTraits != null) && (wmTraits.getColumnProgressionDirection() == Direction.RL) ) {
- return getXOffsetRTL(col, context);
+ return getXOffsetRTL(col, nrColSpan, context);
} else {
return getXOffsetLTR(col, context);
}
@@ -262,9 +263,9 @@ public class ColumnSetup {
* column; i.e., those columns whose column numbers are greater than the
* specified column number.
*/
- private int getXOffsetRTL(int col, PercentBaseContext context) {
+ private int getXOffsetRTL(int col, int nrColSpan, PercentBaseContext context) {
int xoffset = 0;
- for (int i = col, nc = colWidths.size(); ++i < nc;) {
+ for (int i = (col + nrColSpan - 1), nc = colWidths.size(); ++i < nc;) {
int effCol = i;
if (colWidths.get(effCol) != null) {
xoffset += ((Length) colWidths.get(effCol)).getValue(context);
diff --git a/src/java/org/apache/fop/layoutmgr/table/RowPainter.java b/src/java/org/apache/fop/layoutmgr/table/RowPainter.java
index f6c831b3f..955dafabd 100644
--- a/src/java/org/apache/fop/layoutmgr/table/RowPainter.java
+++ b/src/java/org/apache/fop/layoutmgr/table/RowPainter.java
@@ -468,7 +468,7 @@ class RowPainter {
block.addTrait(Trait.IS_REFERENCE_AREA, Boolean.TRUE);
block.setIPD(ipd);
block.setBPD(bpd);
- block.setXOffset(tclm.getXOffsetOfGridUnit(colIndex)
+ block.setXOffset(tclm.getXOffsetOfGridUnit(colIndex, 1)
+ (borderStart.getRetainedWidth() / 2));
block.setYOffset(getRowOffset(rowIndex)
- (borderBefore.getRetainedWidth() / 2));
diff --git a/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java
index db5b4736c..f5e7500e2 100644
--- a/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/table/TableContentLayoutManager.java
@@ -317,16 +317,17 @@ public class TableContentLayoutManager implements PercentBaseContext {
* @return the requested X offset
*/
protected int getXOffsetOfGridUnit(PrimaryGridUnit gu) {
- return getXOffsetOfGridUnit(gu.getColIndex());
+ return getXOffsetOfGridUnit(gu.getColIndex(), gu.getCell().getNumberColumnsSpanned());
}
/**
* Returns the X offset of the grid unit in the given column.
* @param colIndex the column index (zero-based)
+ * @param nrColSpan number columns spanned
* @return the requested X offset
*/
- protected int getXOffsetOfGridUnit(int colIndex) {
- return startXOffset + getTableLM().getColumns().getXOffset(colIndex + 1, getTableLM());
+ protected int getXOffsetOfGridUnit(int colIndex, int nrColSpan) {
+ return startXOffset + getTableLM().getColumns().getXOffset(colIndex + 1, nrColSpan, getTableLM());
}
/**
diff --git a/src/java/org/apache/fop/pdf/PDFColorHandler.java b/src/java/org/apache/fop/pdf/PDFColorHandler.java
index a15349212..8dfcf7f24 100644
--- a/src/java/org/apache/fop/pdf/PDFColorHandler.java
+++ b/src/java/org/apache/fop/pdf/PDFColorHandler.java
@@ -23,7 +23,6 @@ import java.awt.Color;
import java.awt.color.ColorSpace;
import java.awt.color.ICC_ColorSpace;
import java.awt.color.ICC_Profile;
-import java.text.DecimalFormat;
import java.util.Map;
import org.apache.commons.logging.Log;
@@ -36,7 +35,7 @@ import org.apache.xmlgraphics.java2d.color.DeviceCMYKColorSpace;
import org.apache.xmlgraphics.java2d.color.NamedColorSpace;
import org.apache.xmlgraphics.java2d.color.profile.ColorProfileUtil;
-import org.apache.fop.util.DecimalFormatCache;
+import org.apache.xmlgraphics.util.DoubleFormatUtil;
/**
* This class handles the registration of color spaces and the generation of PDF code to select
@@ -225,9 +224,9 @@ public class PDFColorHandler {
if (comps.length != componentCount) {
throw new IllegalStateException("Color with unexpected component count encountered");
}
- DecimalFormat df = DecimalFormatCache.getDecimalFormat(4);
for (int i = 0, c = comps.length; i < c; i++) {
- codeBuffer.append(df.format(comps[i])).append(" ");
+ DoubleFormatUtil.formatDouble(comps[i], 4, 4, codeBuffer);
+ codeBuffer.append(" ");
}
codeBuffer.append(command).append("\n");
}
diff --git a/src/java/org/apache/fop/pdf/PDFInfo.java b/src/java/org/apache/fop/pdf/PDFInfo.java
index d457c2888..2cfcc7d3b 100644
--- a/src/java/org/apache/fop/pdf/PDFInfo.java
+++ b/src/java/org/apache/fop/pdf/PDFInfo.java
@@ -21,12 +21,11 @@ package org.apache.fop.pdf;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
import java.util.Date;
-import java.util.Locale;
import java.util.TimeZone;
+import org.apache.xmlgraphics.util.DateFormatUtil;
+
/**
* class representing an /Info object
*/
@@ -236,57 +235,13 @@ public class PDFInfo extends PDFObject {
}
/**
- * Returns a SimpleDateFormat instance for formatting PDF date-times.
- * @return a new SimpleDateFormat instance
- */
- protected static SimpleDateFormat getPDFDateFormat() {
- SimpleDateFormat df = new SimpleDateFormat("'D:'yyyyMMddHHmmss", Locale.ENGLISH);
- df.setTimeZone(TimeZone.getTimeZone("GMT"));
- return df;
- }
-
- /**
* Formats a date/time according to the PDF specification (D:YYYYMMDDHHmmSSOHH'mm').
* @param time date/time value to format
* @param tz the time zone
* @return the requested String representation
*/
- protected static String formatDateTime(Date time, TimeZone tz) {
- Calendar cal = Calendar.getInstance(tz, Locale.ENGLISH);
- cal.setTime(time);
-
- int offset = cal.get(Calendar.ZONE_OFFSET);
- offset += cal.get(Calendar.DST_OFFSET);
-
- // DateFormat is operating on GMT so adjust for time zone offset
- Date dt1 = new Date(time.getTime() + offset);
- StringBuffer sb = new StringBuffer();
- sb.append(getPDFDateFormat().format(dt1));
-
- offset /= (1000 * 60); // Convert to minutes
-
- if (offset == 0) {
- sb.append('Z');
- } else {
- if (offset > 0) {
- sb.append('+');
- } else {
- sb.append('-');
- }
- int offsetHour = Math.abs(offset / 60);
- int offsetMinutes = Math.abs(offset % 60);
- if (offsetHour < 10) {
- sb.append('0');
- }
- sb.append(Integer.toString(offsetHour));
- sb.append('\'');
- if (offsetMinutes < 10) {
- sb.append('0');
- }
- sb.append(Integer.toString(offsetMinutes));
- sb.append('\'');
- }
- return sb.toString();
+ protected static String formatDateTime(final Date time, TimeZone tz) {
+ return DateFormatUtil.formatPDFDate(time, tz);
}
/**
@@ -294,7 +249,7 @@ public class PDFInfo extends PDFObject {
* @param time date/time value to format
* @return the requested String representation
*/
- protected static String formatDateTime(Date time) {
+ protected static String formatDateTime(final Date time) {
return formatDateTime(time, TimeZone.getDefault());
}
}
diff --git a/src/java/org/apache/fop/pdf/PDFJavaScriptLaunchAction.java b/src/java/org/apache/fop/pdf/PDFJavaScriptLaunchAction.java
index dcd3c6fea..0926b4e75 100644
--- a/src/java/org/apache/fop/pdf/PDFJavaScriptLaunchAction.java
+++ b/src/java/org/apache/fop/pdf/PDFJavaScriptLaunchAction.java
@@ -43,10 +43,9 @@ public class PDFJavaScriptLaunchAction extends PDFAction {
/** {@inheritDoc} */
public String toPDFString() {
StringBuffer sb = new StringBuffer(64);
- sb.append(getObjectID());
sb.append("<<\n/S /JavaScript\n/JS (");
sb.append(this.script);
- sb.append(")\n>>\nendobj\n");
+ sb.append(")\n>>");
return sb.toString();
}
diff --git a/src/java/org/apache/fop/pdf/PDFNumber.java b/src/java/org/apache/fop/pdf/PDFNumber.java
index 95242305c..e638a51b1 100644
--- a/src/java/org/apache/fop/pdf/PDFNumber.java
+++ b/src/java/org/apache/fop/pdf/PDFNumber.java
@@ -19,7 +19,7 @@
package org.apache.fop.pdf;
-import org.apache.fop.util.DecimalFormatCache;
+import org.apache.xmlgraphics.util.DoubleFormatUtil;
/**
* This class represents a simple number object. It also contains contains some
@@ -75,7 +75,12 @@ public class PDFNumber extends PDFObject {
* @return the value as a string
*/
public static String doubleOut(double doubleDown, int dec) {
- return DecimalFormatCache.getDecimalFormat(dec).format(doubleDown);
+ if (dec < 0 || dec > 16) {
+ throw new IllegalArgumentException("Parameter dec must be between 1 and 16");
+ }
+ StringBuffer buf = new StringBuffer();
+ DoubleFormatUtil.formatDouble(doubleDown, dec, dec, buf);
+ return buf.toString();
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/pdf/PDFStructElem.java b/src/java/org/apache/fop/pdf/PDFStructElem.java
index 90a41fb72..a77111170 100644
--- a/src/java/org/apache/fop/pdf/PDFStructElem.java
+++ b/src/java/org/apache/fop/pdf/PDFStructElem.java
@@ -50,7 +50,6 @@ public class PDFStructElem extends PDFDictionary implements StructureTreeElement
if (parent instanceof PDFStructElem) {
parentElement = (PDFStructElem) parent;
}
- put("Type", new PDFName("StructElem"));
put("S", structureType);
setParent(parent);
}
diff --git a/src/java/org/apache/fop/render/afp/AFPCustomizable.java b/src/java/org/apache/fop/render/afp/AFPCustomizable.java
index 6eca86458..e0924c0d0 100644
--- a/src/java/org/apache/fop/render/afp/AFPCustomizable.java
+++ b/src/java/org/apache/fop/render/afp/AFPCustomizable.java
@@ -90,6 +90,13 @@ public interface AFPCustomizable {
void setResolution(int resolution);
/**
+ * Sets the line width correction
+ *
+ * @param correction the line width multiplying factor correction
+ */
+ void setLineWidthCorrection(float correction);
+
+ /**
* Sets whether FS11 and FS45 non-inline images should be wrapped in a page segment
* @param pSeg true iff images should be wrapped
*/
diff --git a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
index 0c778303c..7823a2ce6 100644
--- a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
+++ b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java
@@ -443,6 +443,11 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler
}
/** {@inheritDoc} */
+ public void setLineWidthCorrection(float correction) {
+ paintingState.setLineWidthCorrection(correction);
+ }
+
+ /** {@inheritDoc} */
public int getResolution() {
return paintingState.getResolution();
}
diff --git a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
index bf7fbde4a..e93d8b6aa 100644
--- a/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
+++ b/src/java/org/apache/fop/render/afp/AFPRendererConfigurator.java
@@ -29,6 +29,7 @@ import java.util.List;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.fop.afp.AFPConstants;
import org.apache.fop.afp.AFPEventProducer;
import org.apache.fop.afp.AFPResourceLevel;
import org.apache.fop.afp.AFPResourceLevelDefaults;
@@ -37,6 +38,7 @@ import org.apache.fop.afp.fonts.AFPFontCollection;
import org.apache.fop.afp.fonts.AFPFontInfo;
import org.apache.fop.afp.fonts.CharacterSet;
import org.apache.fop.afp.fonts.CharacterSetBuilder;
+import org.apache.fop.afp.fonts.CharacterSetType;
import org.apache.fop.afp.fonts.DoubleByteFont;
import org.apache.fop.afp.fonts.OutlineFont;
import org.apache.fop.afp.fonts.RasterFont;
@@ -220,7 +222,7 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator
}
} else {
font.addCharacterSet(sizeMpt, CharacterSetBuilder.getSingleByteInstance()
- .build(characterset, codepage, encoding, accessor, eventProducer));
+ .buildSBCS(characterset, codepage, encoding, accessor, eventProducer));
}
}
return font;
@@ -254,7 +256,7 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator
log.error(msg);
}
} else {
- characterSet = CharacterSetBuilder.getSingleByteInstance().build(
+ characterSet = CharacterSetBuilder.getSingleByteInstance().buildSBCS(
characterset, codepage, encoding, accessor, eventProducer);
}
// Return new font object
@@ -269,10 +271,10 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator
}
String name = afpFontCfg.getAttribute("name", characterset);
CharacterSet characterSet = null;
- boolean ebcdicDBCS = afpFontCfg.getAttributeAsBoolean("ebcdic-dbcs", false);
-
+ CharacterSetType charsetType = afpFontCfg.getAttributeAsBoolean("ebcdic-dbcs", false)
+ ? CharacterSetType.DOUBLE_BYTE_LINE_DATA : CharacterSetType.DOUBLE_BYTE;
characterSet = CharacterSetBuilder.getDoubleByteInstance().buildDBCS(characterset,
- codepage, encoding, ebcdicDBCS, accessor, eventProducer);
+ codepage, encoding, charsetType, accessor, eventProducer);
// Create a new font object
DoubleByteFont font = new DoubleByteFont(name, characterSet);
@@ -322,7 +324,7 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator
}
List<FontTriplet> fontTriplets = afi.getFontTriplets();
for (int j = 0; j < fontTriplets.size(); ++j) {
- FontTriplet triplet = (FontTriplet) fontTriplets.get(j);
+ FontTriplet triplet = fontTriplets.get(j);
if (log.isDebugEnabled()) {
log.debug(" Font triplet "
+ triplet.getName() + ", "
@@ -445,6 +447,13 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator
customizable.setResolution(rendererResolutionCfg.getValueAsInteger(240));
}
+ // renderer resolution
+ Configuration lineWidthCorrectionCfg = cfg.getChild("line-width-correction", false);
+ if (lineWidthCorrectionCfg != null) {
+ customizable.setLineWidthCorrection(lineWidthCorrectionCfg
+ .getValueAsFloat(AFPConstants.LINE_WIDTH_CORRECTION));
+ }
+
// a default external resource group file setting
Configuration resourceGroupFileCfg
= cfg.getChild("resource-group-file", false);
diff --git a/src/java/org/apache/fop/render/intermediate/IFParser.java b/src/java/org/apache/fop/render/intermediate/IFParser.java
index 33e6931de..827eec820 100644
--- a/src/java/org/apache/fop/render/intermediate/IFParser.java
+++ b/src/java/org/apache/fop/render/intermediate/IFParser.java
@@ -156,7 +156,7 @@ public class IFParser implements IFConstants {
private ContentHandler navParser;
- private ContentHandler structureTreeHandler;
+ private StructureTreeHandler structureTreeHandler;
private Attributes pageSequenceAttributes;
@@ -165,12 +165,18 @@ public class IFParser implements IFConstants {
private final class StructureTreeHandler extends DefaultHandler {
+ private final Locale pageSequenceLanguage;
+
private final StructureTreeEventHandler structureTreeEventHandler;
private StructureTreeHandler(StructureTreeEventHandler structureTreeEventHandler,
Locale pageSequenceLanguage) throws SAXException {
+ this.pageSequenceLanguage = pageSequenceLanguage;
this.structureTreeEventHandler = structureTreeEventHandler;
- structureTreeEventHandler.startPageSequence(pageSequenceLanguage);
+ }
+
+ void startStructureTree(String type) {
+ structureTreeEventHandler.startPageSequence(pageSequenceLanguage, type);
}
public void endDocument() throws SAXException {
@@ -263,6 +269,8 @@ public class IFParser implements IFConstants {
} else if (localName.equals(EL_STRUCTURE_TREE)) {
if (userAgent.isAccessibilityEnabled()) {
+ String type = attributes.getValue("type");
+ structureTreeHandler.startStructureTree(type);
delegate = structureTreeHandler;
} else {
/* Delegate to a handler that does nothing */
diff --git a/src/java/org/apache/fop/render/intermediate/IFSerializer.java b/src/java/org/apache/fop/render/intermediate/IFSerializer.java
index f8f286cb3..7114f51e3 100644
--- a/src/java/org/apache/fop/render/intermediate/IFSerializer.java
+++ b/src/java/org/apache/fop/render/intermediate/IFSerializer.java
@@ -64,6 +64,15 @@ import org.apache.fop.util.XMLUtil;
public class IFSerializer extends AbstractXMLWritingIFDocumentHandler
implements IFConstants, IFPainter, IFDocumentNavigationHandler {
+ /**
+ * Intermediate Format (IF) version, used to express an @version attribute
+ * in the root element of the IF document, the initial value of which
+ * is set to '2.0' to signify that something preceded it (but didn't
+ * happen to be marked as such), and that this version is not necessarily
+ * backwards compatible with the unmarked (<2.0) version.
+ */
+ public static final String VERSION = "2.0";
+
private IFDocumentHandler mimicHandler;
private int pageSequenceIndex; // used for accessibility
@@ -167,7 +176,9 @@ public class IFSerializer extends AbstractXMLWritingIFDocumentHandler
DocumentNavigationExtensionConstants.NAMESPACE);
handler.startPrefixMapping(InternalElementMapping.STANDARD_PREFIX,
InternalElementMapping.URI);
- handler.startElement(EL_DOCUMENT);
+ AttributesImpl atts = new AttributesImpl();
+ addAttribute(atts, "version", VERSION);
+ handler.startElement(EL_DOCUMENT, atts);
} catch (SAXException e) {
throw new IFException("SAX error in startDocument()", e);
}
diff --git a/src/java/org/apache/fop/render/intermediate/IFStructureTreeBuilder.java b/src/java/org/apache/fop/render/intermediate/IFStructureTreeBuilder.java
index 3d9885914..9ba9afd81 100644
--- a/src/java/org/apache/fop/render/intermediate/IFStructureTreeBuilder.java
+++ b/src/java/org/apache/fop/render/intermediate/IFStructureTreeBuilder.java
@@ -189,11 +189,11 @@ final class IFStructureTreeBuilder implements StructureTreeEventHandler {
pageSequenceEventRecorders.get(pageSequenceIndex).replay(handler);
}
- public void startPageSequence(Locale locale) {
+ public void startPageSequence(Locale locale, String role) {
SAXEventRecorder eventRecorder = new SAXEventRecorder();
pageSequenceEventRecorders.add(eventRecorder);
delegate = StructureTree2SAXEventAdapter.newInstance(eventRecorder);
- delegate.startPageSequence(locale);
+ delegate.startPageSequence(locale, role);
}
public void endPageSequence() {
diff --git a/src/java/org/apache/fop/render/intermediate/IFUtil.java b/src/java/org/apache/fop/render/intermediate/IFUtil.java
index a384461ac..e8651a3df 100644
--- a/src/java/org/apache/fop/render/intermediate/IFUtil.java
+++ b/src/java/org/apache/fop/render/intermediate/IFUtil.java
@@ -22,9 +22,10 @@ package org.apache.fop.render.intermediate;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
+import org.apache.xmlgraphics.util.DoubleFormatUtil;
+
import org.apache.fop.apps.FOPException;
import org.apache.fop.fonts.FontInfo;
-import org.apache.fop.util.DecimalFormatCache;
/**
* Utility functions for the intermediate format.
@@ -40,7 +41,9 @@ public final class IFUtil {
//See http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2.3
value = 0.0;
}
- return DecimalFormatCache.getDecimalFormat(6).format(value);
+ StringBuffer buf = new StringBuffer();
+ DoubleFormatUtil.formatDouble(value, 6, 6, buf);
+ return buf.toString();
}
/**
diff --git a/src/java/org/apache/fop/render/pdf/FOToPDFRoleMap.java b/src/java/org/apache/fop/render/pdf/FOToPDFRoleMap.java
index 9b76d0620..0f752e886 100644
--- a/src/java/org/apache/fop/render/pdf/FOToPDFRoleMap.java
+++ b/src/java/org/apache/fop/render/pdf/FOToPDFRoleMap.java
@@ -103,9 +103,9 @@ final class FOToPDFRoleMap {
addStructureType("Formula");
addStructureType("Form");
- NON_STRUCT = (PDFName) STANDARD_STRUCTURE_TYPES.get("NonStruct");
+ NON_STRUCT = STANDARD_STRUCTURE_TYPES.get("NonStruct");
assert NON_STRUCT != null;
- THEAD = (PDFName) STANDARD_STRUCTURE_TYPES.get("THead");
+ THEAD = STANDARD_STRUCTURE_TYPES.get("THead");
assert THEAD != null;
// Create the standard mappings
@@ -155,7 +155,7 @@ final class FOToPDFRoleMap {
}
private static void addMapping(String fo, String structureType) {
- PDFName type = (PDFName) STANDARD_STRUCTURE_TYPES.get(structureType);
+ PDFName type = STANDARD_STRUCTURE_TYPES.get(structureType);
assert type != null;
addMapping(fo, new SimpleMapper(type));
}
@@ -168,21 +168,6 @@ final class FOToPDFRoleMap {
/**
* Maps a Formatting Object to a PDFName representing the associated structure type.
* @param fo the formatting object's local name
- * @param parent the parent of the structure element to be mapped
- * @return the structure type or null if no match could be found
- */
- public static PDFName mapFormattingObject(String fo, PDFObject parent) {
- Mapper mapper = (Mapper) DEFAULT_MAPPINGS.get(fo);
- if (mapper != null) {
- return mapper.getStructureType(parent);
- } else {
- return NON_STRUCT;
- }
- }
-
- /**
- * Maps a Formatting Object to a PDFName representing the associated structure type.
- * @param fo the formatting object's local name
* @param role the value of the formatting object's role property
* @param parent the parent of the structure element to be mapped
* @param eventBroadcaster the event broadcaster
@@ -192,11 +177,11 @@ final class FOToPDFRoleMap {
PDFObject parent, EventBroadcaster eventBroadcaster) {
PDFName type = null;
if (role == null) {
- type = mapFormattingObject(fo, parent);
+ type = getDefaultMappingFor(fo, parent);
} else {
- type = (PDFName) STANDARD_STRUCTURE_TYPES.get(role);
+ type = STANDARD_STRUCTURE_TYPES.get(role);
if (type == null) {
- type = mapFormattingObject(fo, parent);
+ type = getDefaultMappingFor(fo, parent);
PDFEventProducer.Provider.get(eventBroadcaster).nonStandardStructureType(fo,
fo, role, type.toString().substring(1));
}
@@ -205,6 +190,21 @@ final class FOToPDFRoleMap {
return type;
}
+ /**
+ * Maps a Formatting Object to a PDFName representing the associated structure type.
+ * @param fo the formatting object's local name
+ * @param parent the parent of the structure element to be mapped
+ * @return the structure type or NonStruct if no match could be found
+ */
+ private static PDFName getDefaultMappingFor(String fo, PDFObject parent) {
+ Mapper mapper = DEFAULT_MAPPINGS.get(fo);
+ if (mapper != null) {
+ return mapper.getStructureType(parent);
+ } else {
+ return NON_STRUCT;
+ }
+ }
+
private interface Mapper {
PDFName getStructureType(PDFObject parent);
}
@@ -226,14 +226,13 @@ final class FOToPDFRoleMap {
private static class TableCellMapper implements Mapper {
public PDFName getStructureType(PDFObject parent) {
- PDFStructElem grandParent = (PDFStructElem)
- ((PDFStructElem) parent).getParentStructElem();
+ PDFStructElem grandParent = ((PDFStructElem) parent).getParentStructElem();
//TODO What to do with cells from table-footer? Currently they are mapped on TD.
PDFName type;
if (THEAD.equals(grandParent.getStructureType())) {
- type = (PDFName) STANDARD_STRUCTURE_TYPES.get("TH");
+ type = STANDARD_STRUCTURE_TYPES.get("TH");
} else {
- type = (PDFName) STANDARD_STRUCTURE_TYPES.get("TD");
+ type = STANDARD_STRUCTURE_TYPES.get("TD");
}
assert type != null;
return type;
diff --git a/src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java b/src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java
index 1c9f9b49d..6559e8d56 100644
--- a/src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java
+++ b/src/java/org/apache/fop/render/pdf/PDFLogicalStructureHandler.java
@@ -19,8 +19,6 @@
package org.apache.fop.render.pdf;
-import java.util.Locale;
-
import org.apache.fop.pdf.PDFArray;
import org.apache.fop.pdf.PDFDictionary;
import org.apache.fop.pdf.PDFDocument;
@@ -29,7 +27,6 @@ import org.apache.fop.pdf.PDFName;
import org.apache.fop.pdf.PDFPage;
import org.apache.fop.pdf.PDFParentTree;
import org.apache.fop.pdf.PDFStructElem;
-import org.apache.fop.pdf.PDFStructTreeRoot;
/**
@@ -59,8 +56,6 @@ class PDFLogicalStructureHandler {
*/
private PDFArray pageParentTreeArray;
- private PDFStructElem rootStructureElement;
-
/**
* Class providing the necessary information for bracketing content
* associated to a structure element as a marked-content sequence.
@@ -95,22 +90,10 @@ class PDFLogicalStructureHandler {
*/
PDFLogicalStructureHandler(PDFDocument pdfDoc) {
this.pdfDoc = pdfDoc;
- PDFStructTreeRoot structTreeRoot = pdfDoc.makeStructTreeRoot(parentTree);
- rootStructureElement = pdfDoc.makeStructureElement(
- FOToPDFRoleMap.mapFormattingObject("root", structTreeRoot), structTreeRoot);
- structTreeRoot.addKid(rootStructureElement);
}
-
- PDFStructElem createPageSequence(Locale language) {
- PDFStructElem structElemPart = pdfDoc.makeStructureElement(
- FOToPDFRoleMap.mapFormattingObject("page-sequence", rootStructureElement),
- rootStructureElement);
- rootStructureElement.addKid(structElemPart);
- if (language != null) {
- structElemPart.setLanguage(language);
- }
- return structElemPart;
+ PDFParentTree getParentTree() {
+ return parentTree;
}
private int getNextParentTreeKey() {
diff --git a/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java b/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java
index 2a2a4a392..3839d47bc 100644
--- a/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java
+++ b/src/java/org/apache/fop/render/pdf/PDFStructureTreeBuilder.java
@@ -29,7 +29,11 @@ import org.apache.fop.accessibility.StructureTreeEventHandler;
import org.apache.fop.events.EventBroadcaster;
import org.apache.fop.fo.extensions.ExtensionElementMapping;
import org.apache.fop.pdf.PDFFactory;
+import org.apache.fop.pdf.PDFName;
+import org.apache.fop.pdf.PDFObject;
+import org.apache.fop.pdf.PDFParentTree;
import org.apache.fop.pdf.PDFStructElem;
+import org.apache.fop.pdf.PDFStructTreeRoot;
class PDFStructureTreeBuilder implements StructureTreeEventHandler {
@@ -41,21 +45,42 @@ class PDFStructureTreeBuilder implements StructureTreeEventHandler {
private LinkedList<PDFStructElem> ancestors = new LinkedList<PDFStructElem>();
+ private PDFStructElem rootStructureElement;
+
void setPdfFactory(PDFFactory pdfFactory) {
this.pdfFactory = pdfFactory;
}
void setLogicalStructureHandler(PDFLogicalStructureHandler logicalStructureHandler) {
this.logicalStructureHandler = logicalStructureHandler;
+ createRootStructureElement();
+ }
+
+ private void createRootStructureElement() {
+ assert rootStructureElement == null;
+ PDFParentTree parentTree = logicalStructureHandler.getParentTree();
+ PDFStructTreeRoot structTreeRoot = pdfFactory.getDocument().makeStructTreeRoot(parentTree);
+ rootStructureElement = createStructureElement("root", structTreeRoot, null);
+ structTreeRoot.addKid(rootStructureElement);
}
void setEventBroadcaster(EventBroadcaster eventBroadcaster) {
this.eventBroadcaster = eventBroadcaster;
}
- public void startPageSequence(Locale locale) {
+ public void startPageSequence(Locale language, String role) {
ancestors = new LinkedList<PDFStructElem>();
- ancestors.add(logicalStructureHandler.createPageSequence(locale));
+ PDFStructElem structElem = createStructureElement("page-sequence", rootStructureElement, role);
+ if (language != null) {
+ structElem.setLanguage(language);
+ }
+ rootStructureElement.addKid(structElem);
+ ancestors.add(structElem);
+ }
+
+ private PDFStructElem createStructureElement(String name, PDFObject parent, String role) {
+ PDFName structureType = FOToPDFRoleMap.mapFormattingObject(name, role, parent, eventBroadcaster);
+ return pdfFactory.getDocument().makeStructureElement(structureType, parent);
}
public void endPageSequence() {
@@ -64,12 +89,10 @@ class PDFStructureTreeBuilder implements StructureTreeEventHandler {
public StructureTreeElement startNode(String name, Attributes attributes) {
PDFStructElem parent = ancestors.getFirst();
String role = attributes.getValue("role");
- PDFStructElem created;
- created = pdfFactory.getDocument().makeStructureElement(
- FOToPDFRoleMap.mapFormattingObject(name, role, parent, eventBroadcaster), parent);
- parent.addKid(created);
- ancestors.addFirst(created);
- return created;
+ PDFStructElem structElem = createStructureElement(name, parent, role);
+ parent.addKid(structElem);
+ ancestors.addFirst(structElem);
+ return structElem;
}
public void endNode(String name) {
@@ -83,34 +106,30 @@ class PDFStructureTreeBuilder implements StructureTreeEventHandler {
public StructureTreeElement startImageNode(String name, Attributes attributes) {
PDFStructElem parent = ancestors.getFirst();
String role = attributes.getValue("role");
- PDFStructElem created;
- created = pdfFactory.getDocument().makeStructureElement(
- FOToPDFRoleMap.mapFormattingObject(name, role, parent, eventBroadcaster), parent);
- parent.addKid(created);
+ PDFStructElem structElem = createStructureElement(name, parent, role);
+ parent.addKid(structElem);
String altTextNode = attributes.getValue(ExtensionElementMapping.URI, "alt-text");
if (altTextNode != null) {
- created.put("Alt", altTextNode);
+ structElem.put("Alt", altTextNode);
} else {
- created.put("Alt", "No alternate text specified");
+ structElem.put("Alt", "No alternate text specified");
}
- ancestors.addFirst(created);
- return created;
+ ancestors.addFirst(structElem);
+ return structElem;
}
public StructureTreeElement startReferencedNode(String name, Attributes attributes) {
PDFStructElem parent = ancestors.getFirst();
String role = attributes.getValue("role");
- PDFStructElem created;
+ PDFStructElem structElem;
if ("#PCDATA".equals(name)) {
- created = new PDFStructElem.Placeholder(parent, name);
+ structElem = new PDFStructElem.Placeholder(parent, name);
} else {
- created = pdfFactory.getDocument().makeStructureElement(
- FOToPDFRoleMap.mapFormattingObject(name, role, parent,
- eventBroadcaster), parent);
+ structElem = createStructureElement(name, parent, role);
}
- parent.addKid(created);
- ancestors.addFirst(created);
- return created;
+ parent.addKid(structElem);
+ ancestors.addFirst(structElem);
+ return structElem;
}
}
diff --git a/src/java/org/apache/fop/render/ps/PSDocumentHandler.java b/src/java/org/apache/fop/render/ps/PSDocumentHandler.java
index 01c93cb2d..de82a3098 100644
--- a/src/java/org/apache/fop/render/ps/PSDocumentHandler.java
+++ b/src/java/org/apache/fop/render/ps/PSDocumentHandler.java
@@ -26,6 +26,7 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -58,6 +59,7 @@ import org.apache.fop.render.intermediate.IFException;
import org.apache.fop.render.intermediate.IFPainter;
import org.apache.fop.render.ps.extensions.PSCommentAfter;
import org.apache.fop.render.ps.extensions.PSCommentBefore;
+import org.apache.fop.render.ps.extensions.PSPageTrailerCodeBefore;
import org.apache.fop.render.ps.extensions.PSSetPageDevice;
import org.apache.fop.render.ps.extensions.PSSetupCode;
@@ -99,10 +101,11 @@ public class PSDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
private PSPageDeviceDictionary pageDeviceDictionary;
/** This is a collection holding all document header comments */
- private Collection[] comments = new Collection[3];
+ private Collection[] comments = new Collection[4];
private static final int COMMENT_DOCUMENT_HEADER = 0;
private static final int COMMENT_DOCUMENT_TRAILER = 1;
private static final int COMMENT_PAGE_TRAILER = 2;
+ private static final int PAGE_TRAILER_CODE_BEFORE = 3;
private PSEventProducer eventProducer;
@@ -448,8 +451,9 @@ public class PSDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
/** {@inheritDoc} */
public void startPageTrailer() throws IFException {
- super.startPageTrailer();
try {
+ writeExtensions(PAGE_TRAILER_CODE_BEFORE);
+ super.startPageTrailer();
gen.writeDSCComment(DSCConstants.PAGE_TRAILER);
} catch (IOException ioe) {
throw new IFException("I/O error in startPageTrailer()", ioe);
@@ -531,6 +535,11 @@ public class PSDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
comments[targetCollection] = new java.util.ArrayList();
}
comments[targetCollection].add(extension);
+ } else if (extension instanceof PSPageTrailerCodeBefore) {
+ if (comments[PAGE_TRAILER_CODE_BEFORE] == null) {
+ comments[PAGE_TRAILER_CODE_BEFORE] = new ArrayList();
+ }
+ comments[PAGE_TRAILER_CODE_BEFORE].add(extension);
}
} catch (IOException ioe) {
throw new IFException("I/O error in handleExtensionObject()", ioe);
diff --git a/src/java/org/apache/fop/render/ps/PSPainter.java b/src/java/org/apache/fop/render/ps/PSPainter.java
index 27963ca07..c2288019a 100644
--- a/src/java/org/apache/fop/render/ps/PSPainter.java
+++ b/src/java/org/apache/fop/render/ps/PSPainter.java
@@ -76,10 +76,14 @@ public class PSPainter extends AbstractIFPainter {
* @param documentHandler the parent document handler
*/
public PSPainter(PSDocumentHandler documentHandler) {
+ this(documentHandler, IFState.create());
+ }
+
+ protected PSPainter(PSDocumentHandler documentHandler, IFState state) {
super();
this.documentHandler = documentHandler;
this.borderPainter = new PSBorderPainter(documentHandler.gen);
- this.state = IFState.create();
+ this.state = state;
}
/** {@inheritDoc} */
@@ -348,6 +352,10 @@ public class PSPainter extends AbstractIFPainter {
public void drawText(int x, int y, int letterSpacing, int wordSpacing,
int[][] dp, String text) throws IFException {
try {
+ //Do not draw text if font-size is 0 as it creates an invalid PostScript file
+ if (state.getFontSize() == 0) {
+ return;
+ }
PSGenerator generator = getGenerator();
generator.useColor(state.getTextColor());
beginTextObject();
diff --git a/src/java/org/apache/fop/render/ps/extensions/PSExtensionElementMapping.java b/src/java/org/apache/fop/render/ps/extensions/PSExtensionElementMapping.java
index 00d0594f2..5721afaf6 100644
--- a/src/java/org/apache/fop/render/ps/extensions/PSExtensionElementMapping.java
+++ b/src/java/org/apache/fop/render/ps/extensions/PSExtensionElementMapping.java
@@ -41,6 +41,7 @@ public class PSExtensionElementMapping extends ElementMapping {
foObjs = new java.util.HashMap<String, Maker>();
foObjs.put(PSSetupCodeElement.ELEMENT, new PSSetupCodeMaker());
foObjs.put(PSPageSetupCodeElement.ELEMENT, new PSPageSetupCodeMaker());
+ foObjs.put(PSPageTrailerCodeBefore.ELEMENT, new PSPageTrailerCodeBeforeMaker());
foObjs.put(PSSetPageDeviceElement.ELEMENT, new PSSetPageDeviceMaker());
foObjs.put(PSCommentBefore.ELEMENT, new PSCommentBeforeMaker());
foObjs.put(PSCommentAfter.ELEMENT, new PSCommentAfterMaker());
@@ -59,6 +60,12 @@ public class PSExtensionElementMapping extends ElementMapping {
}
}
+ static class PSPageTrailerCodeBeforeMaker extends ElementMapping.Maker {
+ public FONode make(FONode parent) {
+ return new PSPageTrailerCodeBeforeElement(parent);
+ }
+ }
+
static class PSSetPageDeviceMaker extends ElementMapping.Maker {
public FONode make(FONode parent) {
return new PSSetPageDeviceElement(parent);
diff --git a/src/java/org/apache/fop/render/ps/extensions/PSExtensionHandler.java b/src/java/org/apache/fop/render/ps/extensions/PSExtensionHandler.java
index d499ef6ab..b520d8736 100644
--- a/src/java/org/apache/fop/render/ps/extensions/PSExtensionHandler.java
+++ b/src/java/org/apache/fop/render/ps/extensions/PSExtensionHandler.java
@@ -53,6 +53,7 @@ public class PSExtensionHandler extends DefaultHandler
lastAttributes = new AttributesImpl(attributes);
handled = false;
if (localName.equals(PSSetupCode.ELEMENT)
+ || localName.equals(PSPageTrailerCodeBefore.ELEMENT)
|| localName.equals(PSSetPageDevice.ELEMENT)
|| localName.equals(PSCommentBefore.ELEMENT)
|| localName.equals(PSCommentAfter.ELEMENT)) {
@@ -84,6 +85,8 @@ public class PSExtensionHandler extends DefaultHandler
this.returnedObject = new PSCommentBefore(content.toString());
} else if (PSCommentAfter.ELEMENT.equals(localName)) {
this.returnedObject = new PSCommentAfter(content.toString());
+ } else if (PSPageTrailerCodeBefore.ELEMENT.equals(localName)) {
+ this.returnedObject = new PSPageTrailerCodeBefore(content.toString());
}
}
content.setLength(0); //Reset text buffer (see characters())
diff --git a/src/java/org/apache/fop/render/ps/extensions/PSPageTrailerCodeBefore.java b/src/java/org/apache/fop/render/ps/extensions/PSPageTrailerCodeBefore.java
new file mode 100644
index 000000000..f28f0003e
--- /dev/null
+++ b/src/java/org/apache/fop/render/ps/extensions/PSPageTrailerCodeBefore.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.ps.extensions;
+
+
+public class PSPageTrailerCodeBefore extends PSExtensionAttachment {
+
+ /** The element name */
+ protected static final String ELEMENT = "ps-page-trailer-code-before";
+
+ /**
+ * Default constructor
+ * @param content the actual comment
+ */
+ public PSPageTrailerCodeBefore(String content) {
+ super(content);
+ }
+
+ /**
+ * Constructor
+ */
+ public PSPageTrailerCodeBefore() {
+ super();
+ }
+
+ /**
+ * @return element name
+ */
+ protected String getElement() {
+ return ELEMENT;
+ }
+
+}
diff --git a/src/java/org/apache/fop/render/ps/extensions/PSPageTrailerCodeBeforeElement.java b/src/java/org/apache/fop/render/ps/extensions/PSPageTrailerCodeBeforeElement.java
new file mode 100644
index 000000000..65a22eadd
--- /dev/null
+++ b/src/java/org/apache/fop/render/ps/extensions/PSPageTrailerCodeBeforeElement.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.ps.extensions;
+
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.extensions.ExtensionAttachment;
+
+/**
+ * Comment before element
+ */
+public class PSPageTrailerCodeBeforeElement extends AbstractPSCommentElement {
+
+ /** the element name */
+ protected static final String ELEMENT = "ps-page-trailer-code-before";
+
+ /**
+ * Main constructor
+ * @param parent parent node
+ */
+ public PSPageTrailerCodeBeforeElement(FONode parent) {
+ super(parent);
+ }
+
+ /**
+ * @return local name
+ * @see org.apache.fop.fo.FONode#getLocalName()
+ */
+ public String getLocalName() {
+ return PSPageTrailerCodeBefore.ELEMENT;
+ }
+
+ /**
+ * @return instance of its extension attachment object
+ */
+ protected ExtensionAttachment instantiateExtensionAttachment() {
+ return new PSPageTrailerCodeBefore();
+ }
+}
diff --git a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfSection.java b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfSection.java
index e85da98af..150a46986 100644
--- a/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfSection.java
+++ b/src/java/org/apache/fop/render/rtf/rtflib/rtfdoc/RtfSection.java
@@ -28,6 +28,7 @@ package org.apache.fop.render.rtf.rtflib.rtfdoc;
import java.io.IOException;
import java.io.Writer;
+import java.util.List;
/**
* <p>Models a section in an RTF document</p>
@@ -192,7 +193,11 @@ implements
* @throws IOException for I/O problems
*/
protected void writeRtfSuffix() throws IOException {
- writeControlWord("sect");
+ // write suffix /sect only if this section is not last section (see bug #51484)
+ List siblings = parent.getChildren();
+ if ( ( siblings.indexOf ( this ) + 1 ) < siblings.size() ) {
+ writeControlWord("sect");
+ }
}
private void closeCurrentTable() throws IOException {
diff --git a/src/java/org/apache/fop/render/txt/TXTRenderer.java b/src/java/org/apache/fop/render/txt/TXTRenderer.java
index dd3d883f6..9492018fc 100644
--- a/src/java/org/apache/fop/render/txt/TXTRenderer.java
+++ b/src/java/org/apache/fop/render/txt/TXTRenderer.java
@@ -195,7 +195,7 @@ public class TXTRenderer extends AbstractPathOrientedRenderer {
*/
protected void renderText(TextArea area) {
int col = Helper.ceilPosition(this.currentIPPosition, CHAR_WIDTH);
- int row = Helper.ceilPosition(this.currentBPPosition - LINE_LEADING, CHAR_HEIGHT + 2*LINE_LEADING);
+ int row = Helper.ceilPosition(this.currentBPPosition - LINE_LEADING, CHAR_HEIGHT + 2 * LINE_LEADING);
String s = area.getText();
@@ -219,7 +219,7 @@ public class TXTRenderer extends AbstractPathOrientedRenderer {
double height = bounds.getHeight();
pageWidth = Helper.ceilPosition((int) width, CHAR_WIDTH);
- pageHeight = Helper.ceilPosition((int) height, CHAR_HEIGHT + 2*LINE_LEADING);
+ pageHeight = Helper.ceilPosition((int) height, CHAR_HEIGHT + 2 * LINE_LEADING);
// init buffers
charData = new StringBuffer[pageHeight];
@@ -463,9 +463,9 @@ public class TXTRenderer extends AbstractPathOrientedRenderer {
*/
public void renderImage(Image image, Rectangle2D pos) {
int x1 = Helper.ceilPosition(currentIPPosition, CHAR_WIDTH);
- int y1 = Helper.ceilPosition(currentBPPosition - LINE_LEADING, CHAR_HEIGHT + 2*LINE_LEADING);
+ int y1 = Helper.ceilPosition(currentBPPosition - LINE_LEADING, CHAR_HEIGHT + 2 * LINE_LEADING);
int width = Helper.ceilPosition((int) pos.getWidth(), CHAR_WIDTH);
- int height = Helper.ceilPosition((int) pos.getHeight(), CHAR_HEIGHT + 2*LINE_LEADING);
+ int height = Helper.ceilPosition((int) pos.getHeight(), CHAR_HEIGHT + 2 * LINE_LEADING);
fillRect(x1, y1, width, height, IMAGE_CHAR);
}
@@ -562,9 +562,9 @@ public class TXTRenderer extends AbstractPathOrientedRenderer {
protected void drawBackAndBorders(Area area, float startx, float starty,
float width, float height) {
bm.setWidth(Helper.ceilPosition(toMilli(width), CHAR_WIDTH));
- bm.setHeight(Helper.ceilPosition(toMilli(height), CHAR_HEIGHT + 2*LINE_LEADING));
+ bm.setHeight(Helper.ceilPosition(toMilli(height), CHAR_HEIGHT + 2 * LINE_LEADING));
bm.setStartX(Helper.ceilPosition(toMilli(startx), CHAR_WIDTH));
- bm.setStartY(Helper.ceilPosition(toMilli(starty), CHAR_HEIGHT + 2*LINE_LEADING));
+ bm.setStartY(Helper.ceilPosition(toMilli(starty), CHAR_HEIGHT + 2 * LINE_LEADING));
super.drawBackAndBorders(area, startx, starty, width, height);
}
diff --git a/src/java/org/apache/fop/render/xml/XMLRenderer.java b/src/java/org/apache/fop/render/xml/XMLRenderer.java
index 4ac650269..cf3cbe5a2 100644
--- a/src/java/org/apache/fop/render/xml/XMLRenderer.java
+++ b/src/java/org/apache/fop/render/xml/XMLRenderer.java
@@ -97,6 +97,15 @@ import org.apache.fop.util.XMLUtil;
*/
public class XMLRenderer extends AbstractXMLRenderer {
+ /**
+ * Area Tree (AT) version, used to express an @version attribute
+ * in the root element of the AT document, the initial value of which
+ * is set to '2.0' to signify that something preceded it (but didn't
+ * happen to be marked as such), and that this version is not necessarily
+ * backwards compatible with the unmarked (<2.0) version.
+ */
+ public static final String VERSION = "2.0";
+
/** XML MIME type */
public static final String XML_MIME_TYPE = MimeConstants.MIME_FOP_AREA_TREE;
@@ -365,7 +374,9 @@ public class XMLRenderer extends AbstractXMLRenderer {
if (userAgent.getProducer() != null) {
comment("Produced by " + userAgent.getProducer());
}
- startElement("areaTree");
+ atts.clear();
+ addAttribute("version", VERSION);
+ startElement("areaTree", atts);
}
/** {@inheritDoc} */
@@ -825,11 +836,10 @@ public class XMLRenderer extends AbstractXMLRenderer {
}
maybeAddLevelAttribute(word);
maybeAddPositionAdjustAttribute(word);
- if ( word.isReversed() ) {
- addAttribute("reversed", "true");
- }
+ String text = word.getWord();
+ maybeAddReversedAttribute(word, text);
startElement("word", atts);
- characters(word.getWord());
+ characters(text);
endElement("word");
super.renderWord(word);
}
@@ -917,5 +927,11 @@ public class XMLRenderer extends AbstractXMLRenderer {
}
}
+ private void maybeAddReversedAttribute ( WordArea w, String text ) {
+ if ( w.isReversed() && ( text.length() > 1 ) ) {
+ addAttribute("reversed", "true");
+ }
+ }
+
}
diff --git a/src/java/org/apache/fop/svg/PDFGraphics2D.java b/src/java/org/apache/fop/svg/PDFGraphics2D.java
index ef81180ce..67fc5d860 100644
--- a/src/java/org/apache/fop/svg/PDFGraphics2D.java
+++ b/src/java/org/apache/fop/svg/PDFGraphics2D.java
@@ -1171,8 +1171,8 @@ public class PDFGraphics2D extends AbstractGraphics2D implements NativeImageHand
currentStream.write("q\n");
writeClip(shape);
- currentStream.write("" + usrW + " 0 0 " + (-usrH) + " " + usrX
- + " " + (usrY + usrH) + " cm\n"
+ currentStream.write("" + PDFNumber.doubleOut(usrW) + " 0 0 " + PDFNumber.doubleOut(-usrH) + " "
+ + PDFNumber.doubleOut(usrX) + " " + PDFNumber.doubleOut(usrY + usrH) + " cm\n"
+ imageInfo.getName() + " Do\nQ\n");
return true;
}
diff --git a/src/java/org/apache/fop/util/DecimalFormatCache.java b/src/java/org/apache/fop/util/DecimalFormatCache.java
deleted file mode 100644
index a6634f50b..000000000
--- a/src/java/org/apache/fop/util/DecimalFormatCache.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-
-package org.apache.fop.util;
-
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
-import java.util.Locale;
-
-/**
- * This class provides a cache for {@link DecimalFormat} instance. {@link DecimalFormat} itself
- * is not thread-safe but since FOP needs to format a lot of numbers the same way, it shall
- * be cached in a {@link ThreadLocal}.
- */
-public final class DecimalFormatCache {
-
- private DecimalFormatCache() {
- }
-
- private static final String BASE_FORMAT = "0.################";
-
- private static class DecimalFormatThreadLocal extends ThreadLocal {
-
- private int dec;
-
- public DecimalFormatThreadLocal(int dec) {
- this.dec = dec;
- }
-
- protected synchronized Object initialValue() {
- String s = "0";
- if (dec > 0) {
- s = BASE_FORMAT.substring(0, dec + 2);
- }
- DecimalFormat df = new DecimalFormat(s, new DecimalFormatSymbols(Locale.US));
- return df;
- }
- };
-
- //DecimalFormat is not thread-safe!
- private static final ThreadLocal[] DECIMAL_FORMAT_CACHE = new DecimalFormatThreadLocal[17];
- static {
- for (int i = 0, c = DECIMAL_FORMAT_CACHE.length; i < c; i++) {
- DECIMAL_FORMAT_CACHE[i] = new DecimalFormatThreadLocal(i);
- }
- }
-
- /**
- * Returns a cached {@link DecimalFormat} instance for the given number of decimal digits.
- * @param dec the number of decimal digits.
- * @return the DecimalFormat instance
- */
- public static DecimalFormat getDecimalFormat(int dec) {
- if (dec < 0 || dec >= DECIMAL_FORMAT_CACHE.length) {
- throw new IllegalArgumentException("Parameter dec must be between 1 and "
- + (DECIMAL_FORMAT_CACHE.length + 1));
- }
- return (DecimalFormat)DECIMAL_FORMAT_CACHE[dec].get();
- }
-
-}