aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org
diff options
context:
space:
mode:
authorAdrian Cumiskey <acumiskey@apache.org>2008-10-22 13:42:56 +0000
committerAdrian Cumiskey <acumiskey@apache.org>2008-10-22 13:42:56 +0000
commit82f8cd4c3a02919eb554776059f051623e2ac683 (patch)
tree8bc5cf28cf041ec50f840f5bfdfc907cc1fcce38 /src/java/org
parent69e12c0a1cec260629c5034abb609beb671bf09b (diff)
downloadxmlgraphics-fop-82f8cd4c3a02919eb554776059f051623e2ac683.tar.gz
xmlgraphics-fop-82f8cd4c3a02919eb554776059f051623e2ac683.zip
Default to inline resource level for GOCA graphic objects (when no afp:resource-level extension is provided).
This is due to a bug in the IBM AFP Workbench Viewer (2.04.01.07) (hard copy works just fine with default print-file level) git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AFPGOCAResources@707075 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org')
-rw-r--r--src/java/org/apache/fop/fonts/CachedFontInfo.java.pres114
-rw-r--r--src/java/org/apache/fop/fonts/FontInfo.java9
-rw-r--r--src/java/org/apache/fop/fonts/svn-commit.2.tmp4
-rw-r--r--src/java/org/apache/fop/fonts/svn-commit.tmp4
-rw-r--r--src/java/org/apache/fop/fonts/type1/PFMFile.java.pres490
-rw-r--r--src/java/org/apache/fop/image/TIFFImage.java.pres216
-rw-r--r--src/java/org/apache/fop/render/AbstractRenderer.java6
-rw-r--r--src/java/org/apache/fop/render/afp/AFPImageGraphics2DFactory.java9
-rw-r--r--src/java/org/apache/fop/render/afp/AFPResourceInfo.java13
-rw-r--r--src/java/org/apache/fop/render/afp/extensions/AFPResourceInfo.java188
-rw-r--r--src/java/org/apache/fop/render/afp/extensions/AFPResourceInfoElement.java93
-rw-r--r--src/java/org/apache/fop/render/afp/goca/GraphicsSetMix.java55
-rw-r--r--src/java/org/apache/fop/render/afp/modca/DocumentIndex.java69
-rw-r--r--src/java/org/apache/fop/render/afp/svn-commit.2.tmp25
-rw-r--r--src/java/org/apache/fop/render/afp/svn-commit.3.tmp25
-rw-r--r--src/java/org/apache/fop/render/afp/svn-commit.tmp25
-rw-r--r--src/java/org/apache/fop/svg/patch.diff44
17 files changed, 1381 insertions, 8 deletions
diff --git a/src/java/org/apache/fop/fonts/CachedFontInfo.java.pres b/src/java/org/apache/fop/fonts/CachedFontInfo.java.pres
new file mode 100644
index 000000000..7e698af6a
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/CachedFontInfo.java.pres
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id: $ */
+
+package org.apache.fop.fonts;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.List;
+
+import org.apache.commons.io.FileUtils;
+
+/**
+ * Font info stored in the cache
+ */
+public class CachedFontInfo extends EmbedFontInfo {
+
+ /** Serialization Version UID */
+ private static final long serialVersionUID = 240028291961081894L;
+
+ /** file modify date (if available) */
+ private long lastModified = -1;
+
+ /**
+ * Returns a file given a list of urls
+ * @param urls array of possible font urls
+ * @return file font file
+ */
+ public static File getFileFromUrls(String[] urls) {
+ for (int i = 0; i < urls.length; i++) {
+ try {
+ URL url = new URL(urls[i]);
+ url.getFile();
+ File fontFile = FileUtils.toFile(url);
+ if (fontFile.exists() && fontFile.canRead()) {
+ return fontFile;
+ }
+ } catch (IllegalArgumentException e) {
+ // do nothing
+ } catch (MalformedURLException e) {
+ // do nothing
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Default constructor
+ * @param metricsFile metrics file
+ * @param kerning kerning
+ * @param fontTriplets font triplets
+ * @param embedFile embed file
+ * @param lastModified timestamp that this font was last modified
+ */
+ public CachedFontInfo(String metricsFile, boolean kerning, List fontTriplets,
+ String embedFile, long lastModified) {
+ super(metricsFile, kerning, fontTriplets, embedFile);
+ this.lastModified = lastModified;
+ }
+
+ /**
+ * Constructor
+ * @param fontInfo an existing embed font info
+ */
+ public CachedFontInfo(EmbedFontInfo fontInfo) {
+ super(fontInfo.metricsFile, fontInfo.kerning, fontInfo.fontTriplets, fontInfo.embedFile);
+ // try and determine modified date
+ File fontFile = getFileFromUrls(new String[] {embedFile, metricsFile});
+ if (fontFile != null ) {
+ this.lastModified = fontFile.lastModified();
+ }
+ }
+
+ /**
+ * Gets the modified timestamp for font file (not always available)
+ * @return modified timestamp
+ */
+ public long lastModified() {
+ return this.lastModified;
+ }
+
+ /**
+ * Gets the modified timestamp for font file
+ * (used for the purposes of font info caching)
+ * @param lastModified modified font file timestamp
+ */
+ public void setLastModified(long lastModified) {
+ this.lastModified = lastModified;
+ }
+
+ /**
+ * @return string representation of this object
+ * {@inheritDoc}
+ */
+ public String toString() {
+ return super.toString() + ", lastModified=" + lastModified;
+ }
+}
diff --git a/src/java/org/apache/fop/fonts/FontInfo.java b/src/java/org/apache/fop/fonts/FontInfo.java
index d9f2e0de8..ad838708d 100644
--- a/src/java/org/apache/fop/fonts/FontInfo.java
+++ b/src/java/org/apache/fop/fonts/FontInfo.java
@@ -206,7 +206,8 @@ public class FontInfo {
private FontTriplet fontLookup(String family, String style,
int weight, boolean substitutable) {
if (log.isTraceEnabled()) {
- log.trace("Font lookup: " + family + " " + style + " " + weight);
+ log.trace("Font lookup: " + family + " " + style + " " + weight
+ + (substitutable ? " substitutable" : ""));
}
FontTriplet startKey = createFontKey(family, style, weight);
@@ -288,7 +289,7 @@ public class FontInfo {
}
// last resort: use default
- if (internalFontKey == null) {
+ if (key == null && internalFontKey == null) {
key = Font.DEFAULT_FONT;
internalFontKey = getInternalFontKey(key);
}
@@ -359,7 +360,7 @@ public class FontInfo {
private List/*<FontTriplet>*/ fontLookup(String[] families, String style,
int weight, boolean substitutable) {
- List matchingTriplets = new java.util.ArrayList();
+ List/*<FontTriplet>*/ matchingTriplets = new java.util.ArrayList/*<FontTriplet>*/();
FontTriplet triplet = null;
for (int i = 0; i < families.length; i++) {
triplet = fontLookup(families[i], style, weight, substitutable);
@@ -569,7 +570,7 @@ public class FontInfo {
List/*<FontTriplet>*/ foundTriplets = new java.util.ArrayList();
for (Iterator iter = triplets.entrySet().iterator(); iter.hasNext();) {
Map.Entry tripletEntry = (Map.Entry) iter.next();
- if (fontName.equals(((String)tripletEntry.getValue()))) {
+ if (fontName.equals((tripletEntry.getValue()))) {
foundTriplets.add(tripletEntry.getKey());
}
}
diff --git a/src/java/org/apache/fop/fonts/svn-commit.2.tmp b/src/java/org/apache/fop/fonts/svn-commit.2.tmp
new file mode 100644
index 000000000..9492437ed
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/svn-commit.2.tmp
@@ -0,0 +1,4 @@
+Url is actually a Uri
+--This line, and those below, will be ignored--
+
+M FontLoader.java
diff --git a/src/java/org/apache/fop/fonts/svn-commit.tmp b/src/java/org/apache/fop/fonts/svn-commit.tmp
new file mode 100644
index 000000000..d0cb89ebd
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/svn-commit.tmp
@@ -0,0 +1,4 @@
+Url is really a Uri
+--This line, and those below, will be ignored--
+
+M FontLoader.java
diff --git a/src/java/org/apache/fop/fonts/type1/PFMFile.java.pres b/src/java/org/apache/fop/fonts/type1/PFMFile.java.pres
new file mode 100644
index 000000000..f888cf050
--- /dev/null
+++ b/src/java/org/apache/fop/fonts/type1/PFMFile.java.pres
@@ -0,0 +1,490 @@
+/*
+ * 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: PFMFile.java 595297 2007-11-15 13:28:58Z jeremias $ */
+
+package org.apache.fop.fonts.type1;
+
+// Java
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.fonts.Glyphs;
+
+/**
+ * This class represents a PFM file (or parts of it) as a Java object.
+ */
+public class PFMFile {
+
+ // Header stuff
+ private String windowsName;
+ private String postscriptName;
+ private short dfItalic;
+ private int dfWeight;
+ private short dfCharSet;
+ private short dfPitchAndFamily;
+ private int dfAvgWidth;
+ private int dfMaxWidth;
+ private int dfMinWidth;
+ private short dfFirstChar;
+ private short dfLastChar;
+
+ // Extension stuff
+ // ---
+
+ // Extend Text Metrics
+ private int etmCapHeight;
+ private int etmXHeight;
+ private int etmLowerCaseAscent;
+ private int etmLowerCaseDescent;
+
+ // Extent table
+ private int[] extentTable;
+
+ private Map kerningTab = new java.util.HashMap();
+
+ /**
+ * logging instance
+ */
+ protected Log log = LogFactory.getLog(PFMFile.class);
+
+ /**
+ * Parses a PFM file
+ *
+ * @param inStream The stream from which to read the PFM file.
+ * @throws IOException In case of an I/O problem
+ */
+ public void load(InputStream inStream) throws IOException {
+ byte[] pfmBytes = IOUtils.toByteArray(inStream);
+ InputStream bufin = inStream;
+ bufin = new ByteArrayInputStream(pfmBytes);
+ PFMInputStream in = new PFMInputStream(bufin);
+ bufin.mark(512);
+ short sh1 = in.readByte();
+ short sh2 = in.readByte();
+ if (sh1 == 128 && sh2 == 1) {
+ //Found the first section header of a PFB file!
+ throw new IOException("Cannot parse PFM file. You probably specified the PFB file"
+ + " of a Type 1 font as parameter instead of the PFM.");
+ }
+ bufin.reset();
+ byte[] b = new byte[16];
+ bufin.read(b);
+ if (new String(b, "US-ASCII").equalsIgnoreCase("StartFontMetrics")) {
+ //Found the header of a AFM file!
+ throw new IOException("Cannot parse PFM file. You probably specified the AFM file"
+ + " of a Type 1 font as parameter instead of the PFM.");
+ }
+ bufin.reset();
+ final int version = in.readShort();
+ if (version != 256) {
+ log.warn("PFM version expected to be '256' but got '" + version + "'."
+ + " Please make sure you specify the PFM as parameter"
+ + " and not the PFB or the AFM.");
+ }
+ //final long filesize = in.readInt();
+ bufin.reset();
+
+ loadHeader(in);
+ loadExtension(in);
+ }
+
+ /**
+ * Parses the header of the PFM file.
+ *
+ * @param inStream The stream from which to read the PFM file.
+ * @throws IOException In case of an I/O problem
+ */
+ private void loadHeader(PFMInputStream inStream) throws IOException {
+ inStream.skip(80);
+ dfItalic = inStream.readByte();
+ inStream.skip(2);
+ dfWeight = inStream.readShort();
+ dfCharSet = inStream.readByte();
+ inStream.skip(4);
+ dfPitchAndFamily = inStream.readByte();
+ dfAvgWidth = inStream.readShort();
+ dfMaxWidth = inStream.readShort();
+ dfFirstChar = inStream.readByte();
+ dfLastChar = inStream.readByte();
+ inStream.skip(8);
+ long faceOffset = inStream.readInt();
+
+ inStream.reset();
+ inStream.skip(faceOffset);
+ windowsName = inStream.readString();
+
+ inStream.reset();
+ inStream.skip(117);
+ }
+
+ /**
+ * Parses the extension part of the PFM file.
+ *
+ * @param inStream The stream from which to read the PFM file.
+ */
+ private void loadExtension(PFMInputStream inStream) throws IOException {
+ final int size = inStream.readShort();
+ if (size != 30) {
+ log.warn("Size of extension block was expected to be "
+ + "30 bytes, but was " + size + " bytes.");
+ }
+ final long extMetricsOffset = inStream.readInt();
+ final long extentTableOffset = inStream.readInt();
+ inStream.skip(4); //Skip dfOriginTable
+ final long kernPairOffset = inStream.readInt();
+ inStream.skip(4); //Skip dfTrackKernTable
+ long driverInfoOffset = inStream.readInt();
+
+ if (kernPairOffset > 0) {
+ inStream.reset();
+ inStream.skip(kernPairOffset);
+ loadKernPairs(inStream);
+ }
+
+ inStream.reset();
+ inStream.skip(driverInfoOffset);
+ postscriptName = inStream.readString();
+
+ if (extMetricsOffset != 0) {
+ inStream.reset();
+ inStream.skip(extMetricsOffset);
+ loadExtMetrics(inStream);
+ }
+ if (extentTableOffset != 0) {
+ inStream.reset();
+ inStream.skip(extentTableOffset);
+ loadExtentTable(inStream);
+ }
+
+ }
+
+ /**
+ * Parses the kernPairs part of the pfm file
+ *
+ * @param inStream The stream from which to read the PFM file.
+ */
+ private void loadKernPairs(PFMInputStream inStream) throws IOException {
+ int i = inStream.readShort();
+
+
+ if (log.isTraceEnabled()) {
+ log.trace(i + " kerning pairs");
+ }
+ while (i > 0) {
+ int g1 = (int)inStream.readByte();
+ i--;
+
+ int g2 = (int)inStream.readByte();
+
+ int adj = inStream.readShort();
+ if (adj > 0x8000) {
+ adj = -(0x10000 - adj);
+ }
+
+ if (log.isTraceEnabled()) {
+ log.trace("Char no: (" + g1 + ", " + g2 + ") kern: " + adj);
+ final String glyph1 = Glyphs.TEX8R_GLYPH_NAMES[g1];
+ final String glyph2 = Glyphs.TEX8R_GLYPH_NAMES[g2];
+ log.trace("glyphs: " + glyph1 + ", " + glyph2);
+ }
+
+ Map adjTab = (Map)kerningTab.get(new Integer(g1));
+ if (adjTab == null) {
+ adjTab = new java.util.HashMap();
+ }
+ adjTab.put(new Integer(g2), new Integer(adj));
+ kerningTab.put(new Integer(g1), adjTab);
+ }
+ }
+
+ /**
+ * Parses the extended metrics part of the PFM file.
+ *
+ * @param inStream The stream from which to read the PFM file.
+ */
+ private void loadExtMetrics(PFMInputStream inStream) throws IOException {
+ final int size = inStream.readShort();
+ if (size != 52) {
+ log.warn("Size of extension block was expected to be "
+ + "52 bytes, but was " + size + " bytes.");
+ }
+ inStream.skip(12); //Skip etmPointSize, etmOrientation, etmMasterHeight,
+ //etmMinScale, etmMaxScale, emtMasterUnits
+ etmCapHeight = inStream.readShort();
+ etmXHeight = inStream.readShort();
+ etmLowerCaseAscent = inStream.readShort();
+ etmLowerCaseDescent = -(inStream.readShort());
+ //Ignore the rest of the values
+ }
+
+ /**
+ * Parses the extent table of the PFM file.
+ *
+ * @param inStream The stream from which to read the PFM file.
+ */
+ private void loadExtentTable(PFMInputStream inStream) throws IOException {
+ extentTable = new int[dfLastChar - dfFirstChar + 1];
+ dfMinWidth = dfMaxWidth;
+ for (short i = dfFirstChar; i <= dfLastChar; i++) {
+ extentTable[i - dfFirstChar] = inStream.readShort();
+ if (extentTable[i - dfFirstChar] < dfMinWidth) {
+ dfMinWidth = extentTable[i - dfFirstChar];
+ }
+ }
+ }
+
+ /**
+ * Returns the Windows name of the font.
+ *
+ * @return The Windows name.
+ */
+ public String getWindowsName() {
+ return windowsName;
+ }
+
+ /**
+ * Return the kerning table. The kerning table is a Map with
+ * strings with glyphnames as keys, containing Maps as value.
+ * The value map contains a glyph name string key and an Integer value
+ *
+ * @return A Map containing the kerning table
+ */
+ public Map getKerning() {
+ return kerningTab;
+ }
+
+ /**
+ * Returns the Postscript name of the font.
+ *
+ * @return The Postscript name.
+ */
+ public String getPostscriptName() {
+ return postscriptName;
+ }
+
+ /**
+ * Returns the charset used for the font.
+ *
+ * @return The charset (0=WinAnsi).
+ */
+ public short getCharSet() {
+ return dfCharSet;
+ }
+
+ /**
+ * Returns the charset of the font as a string.
+ *
+ * @return The name of the charset.
+ */
+ public String getCharSetName() {
+ //TODO Had to remove the detection for Expert(Subset) encoding. The PFM is not suitable
+ //for detecting these character sets. We have to parse the AFM for that.
+ switch (dfCharSet) {
+ case 0:
+ return "WinAnsi"; // AKA ISOAdobe
+ case 1:
+ return "Expert";
+ case 2:
+ if ("Symbol".equals(getPostscriptName())) {
+ return "Symbol";
+ } else {
+ return "ExpertSubset";
+ }
+ case 128:
+ return "Shift-JIS (Japanese)";
+ default:
+ log.warn("Unknown charset detected (" + dfCharSet
+ + ", 0x" + Integer.toHexString(dfCharSet)
+ + "). Trying fallback to WinAnsi.");
+ }
+ return "WinAnsi";
+ }
+
+ /**
+ * Returns the number of the character that defines
+ * the first entry in the widths list.
+ *
+ * @return The number of the first character.
+ */
+ public short getFirstChar() {
+ return dfFirstChar;
+ }
+
+ /**
+ * Returns the number of the character that defines
+ * the last entry in the widths list.
+ *
+ * @return The number of the last character.
+ */
+ public short getLastChar() {
+ return dfLastChar;
+ }
+
+ /**
+ * Returns the CapHeight parameter for the font (height of uppercase H).
+ *
+ * @return The CapHeight parameter.
+ */
+ public int getCapHeight() {
+ return etmCapHeight;
+ }
+
+ /**
+ * Returns the XHeight parameter for the font (height of lowercase x).
+ *
+ * @return The CapHeight parameter.
+ */
+ public int getXHeight() {
+ return etmXHeight;
+ }
+
+ /**
+ * Returns the LowerCaseAscent parameter for the font (height of lowercase d).
+ *
+ * @return The LowerCaseAscent parameter.
+ */
+ public int getLowerCaseAscent() {
+ return etmLowerCaseAscent;
+ }
+
+ /**
+ * Returns the LowerCaseDescent parameter for the font (height of lowercase p).
+ *
+ * @return The LowerCaseDescent parameter.
+ */
+ public int getLowerCaseDescent() {
+ return etmLowerCaseDescent;
+ }
+
+ /**
+ * Tells whether the font has proportional character spacing.
+ *
+ * @return ex. true for Times, false for Courier.
+ */
+ public boolean getIsProportional() {
+ return ((dfPitchAndFamily & 1) == 1);
+ }
+
+ /**
+ * Returns the bounding box for the font.
+ * Note: this value is just an approximation,
+ * it does not really exist in the PFM file.
+ *
+ * @return The calculated Font BBox.
+ */
+ public int[] getFontBBox() {
+ int[] bbox = new int[4];
+
+ // Just guessing....
+ if (!getIsProportional() && (dfAvgWidth == dfMaxWidth)) {
+ bbox[0] = -20;
+ } else {
+ bbox[0] = -100;
+ }
+ bbox[1] = getLowerCaseDescent() - 5;
+ bbox[2] = dfMaxWidth + 10;
+ bbox[3] = getLowerCaseAscent() + 5;
+ return bbox;
+ }
+
+ /**
+ * Indicates whether the font is non-symbolic (Font uses the Adobe standard Latin character
+ * set or a subset of it).
+ * @return true if the font is non-symbolic
+ */
+ public boolean isNonSymbolic() {
+ return (dfCharSet != 2); //!= Symbol fonts
+ }
+
+ /**
+ * Returns the characteristics flags for the font as
+ * needed for a PDF font descriptor (See PDF specs).
+ *
+ * @return The characteristics flags.
+ */
+ public int getFlags() {
+ int flags = 0;
+ if (!getIsProportional()) {
+ flags |= 1; //bit 1: FixedPitch
+ }
+ if (isNonSymbolic()) {
+ flags |= 32; //bit 6: Nonsymbolic
+ } else {
+ flags |= 4; //bit 3: Symbolic
+ }
+ //int serif = dfPitchAndFamily & 0xFFFE;
+ if ((dfPitchAndFamily & 16) != 0) {
+ flags |= 2; //bit 2: Serif
+ }
+ if ((dfPitchAndFamily & 64) != 0) {
+ flags |= 8; //bit 4: Script
+ }
+ if (dfItalic != 0) {
+ flags |= 64; //bit 7: Italic
+ }
+ return flags;
+ }
+
+ /**
+ * Returns the width of the dominant vertical stems of the font.
+ * Note: this value is just an approximation,
+ * it does not really exist in the PFM file.
+ *
+ * @return The vertical stem width.
+ */
+ public int getStemV() {
+ // Just guessing....
+ if (dfItalic != 0) {
+ return (int)Math.round(dfMinWidth * 0.25);
+ } else {
+ return (int)Math.round(dfMinWidth * 0.6);
+ }
+ }
+
+ /**
+ * Returns the italic angle of the font.
+ * Note: this value is just an approximation,
+ * it does not really exist in the PFM file.
+ *
+ * @return The italic angle.
+ */
+ public int getItalicAngle() {
+ if (dfItalic != 0) {
+ return -16; // Just guessing....
+ } else {
+ return 0;
+ }
+ }
+
+ /**
+ * Returns the width of a character
+ *
+ * @param which The number of the character for which the width is requested.
+ * @return The width of a character.
+ */
+ public int getCharWidth(short which) {
+ return extentTable[which - dfFirstChar];
+ }
+
+}
diff --git a/src/java/org/apache/fop/image/TIFFImage.java.pres b/src/java/org/apache/fop/image/TIFFImage.java.pres
new file mode 100644
index 000000000..703692cf5
--- /dev/null
+++ b/src/java/org/apache/fop/image/TIFFImage.java.pres
@@ -0,0 +1,216 @@
+/*
+ * 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: TIFFImage.java 557337 2007-07-18 17:37:14Z adelmelle $ */
+
+package org.apache.fop.image;
+
+import java.awt.color.ColorSpace;
+import java.io.IOException;
+
+import org.apache.xmlgraphics.image.codec.util.SeekableStream;
+import org.apache.xmlgraphics.image.codec.tiff.TIFFDirectory;
+import org.apache.xmlgraphics.image.codec.tiff.TIFFField;
+import org.apache.xmlgraphics.image.codec.tiff.TIFFImageDecoder;
+import org.apache.xmlgraphics.image.rendered.CachableRed;
+import org.apache.commons.io.IOUtils;
+
+/**
+ * TIFF implementation using the Batik codecs.
+ */
+public class TIFFImage extends XmlGraphicsCommonsImage {
+
+ private int compression = 0;
+ private int stripCount = 0;
+ private long stripOffset = 0;
+ private long stripLength = 0;
+ private int fillOrder = 1;
+
+ /**
+ * Constructs a new BatikImage instance.
+ * @param imgReader basic metadata for the image
+ */
+ public TIFFImage(FopImage.ImageInfo imgReader) {
+ super(imgReader);
+ }
+
+ /**
+ * The compression type set in the TIFF directory
+ * @return the TIFF compression type
+ */
+ public int getCompression() {
+ return compression;
+ }
+
+ /**
+ * The number of strips in the image
+ * @return the number of strips in the image
+ */
+ public int getStripCount() {
+ return stripCount;
+ }
+
+ /**
+ * {@inheritDoc}
+ * org.apache.xmlgraphics.image.codec.util.SeekableStream)
+ */
+ protected CachableRed decodeImage(SeekableStream stream) throws IOException {
+ org.apache.xmlgraphics.image.codec.tiff.TIFFImage img
+ = new org.apache.xmlgraphics.image.codec.tiff.TIFFImage
+ (stream, null, 0);
+ TIFFDirectory dir = (TIFFDirectory)img.getProperty("tiff_directory");
+ TIFFField fld = dir.getField(TIFFImageDecoder.TIFF_X_RESOLUTION);
+ if (fld != null) {
+ log.debug("x resolution = " + fld.getAsDouble(0));
+ this.dpiHorizontal = fld.getAsDouble(0);
+ } else {
+ log.warn("Cannot determine x resolution.");
+ }
+ fld = dir.getField(TIFFImageDecoder.TIFF_Y_RESOLUTION);
+ if (fld != null) {
+ log.debug("y resolution = " + fld.getAsDouble(0));
+ this.dpiVertical = fld.getAsDouble(0);
+ } else {
+ log.warn("Cannot determine y resolution.");
+ }
+ fld = dir.getField(TIFFImageDecoder.TIFF_RESOLUTION_UNIT);
+ if (fld != null) {
+ int resUnit = fld.getAsInt(0);
+ if (resUnit == 3) {
+ //cm
+ this.dpiHorizontal *= 2.54f;
+ this.dpiVertical *= 2.54f;
+ } else if (resUnit != 2) {
+ //ignored
+ log.warn("Cannot determine bitmap resolution."
+ + " Unimplemented resolution unit: " + resUnit);
+ }
+ } else {
+ log.warn("Cannot determine bitmap resolution unit.");
+ }
+ fld = dir.getField(TIFFImageDecoder.TIFF_COMPRESSION);
+ if (fld != null) {
+ compression = fld.getAsInt(0);
+ }
+ fld = dir.getField(TIFFImageDecoder.TIFF_BITS_PER_SAMPLE);
+ if (fld != null) {
+ bitsPerPixel = fld.getAsInt(0);
+ }
+ fld = dir.getField(TIFFImageDecoder.TIFF_ROWS_PER_STRIP);
+ if (fld == null) {
+ stripCount = 1;
+ } else {
+ stripCount = (int)(dir.getFieldAsLong(TIFFImageDecoder.TIFF_IMAGE_LENGTH)
+ / fld.getAsLong(0));
+ }
+
+ fld = dir.getField(TIFFImageDecoder.TIFF_FILL_ORDER);
+ if (fld != null) {
+ fillOrder = fld.getAsInt(0);
+ }
+
+ stripOffset = dir.getField(TIFFImageDecoder.TIFF_STRIP_OFFSETS).getAsLong(0);
+ stripLength = dir.getField(TIFFImageDecoder.TIFF_STRIP_BYTE_COUNTS).getAsLong(0);
+
+ if (this.bitsPerPixel == 1) {
+ this.colorSpace = ColorSpace.getInstance(ColorSpace.CS_GRAY);
+ }
+ return img;
+ }
+
+ /**
+ * Load the original TIFF data.
+ * This loads only strip 1 of the original TIFF data.
+ *
+ * @return true if loaded false for any error
+ * {@inheritDoc}
+ */
+ protected boolean loadOriginalData() {
+ if (loadDimensions()) {
+ byte[] readBuf = new byte[(int)stripLength];
+ int bytesRead;
+
+ try {
+ this.seekableInput.reset();
+ this.seekableInput.skip(stripOffset);
+ bytesRead = seekableInput.read(readBuf);
+ if (bytesRead != stripLength) {
+ log.error("Error while loading image: length mismatch on read");
+ return false;
+ }
+
+ // need to invert bytes if fill order = 2
+ if (fillOrder == 2) {
+ for (int i = 0; i < (int)stripLength; i++) {
+ readBuf[i] = flipTable[readBuf[i] & 0xff];
+ }
+ }
+ this.raw = readBuf;
+
+ return true;
+ } catch (IOException ioe) {
+ log.error("Error while loading image strip 1 (TIFF): ", ioe);
+ return false;
+ } finally {
+ IOUtils.closeQuietly(seekableInput);
+ IOUtils.closeQuietly(inputStream);
+ this.seekableInput = null;
+ this.inputStream = null;
+ this.cr = null;
+ }
+ }
+ return false;
+ }
+
+ // Table to be used when fillOrder = 2, for flipping bytes.
+ // Copied from XML Graphics Commons' TIFFFaxDecoder class
+ private static byte[] flipTable = {
+ 0, -128, 64, -64, 32, -96, 96, -32,
+ 16, -112, 80, -48, 48, -80, 112, -16,
+ 8, -120, 72, -56, 40, -88, 104, -24,
+ 24, -104, 88, -40, 56, -72, 120, -8,
+ 4, -124, 68, -60, 36, -92, 100, -28,
+ 20, -108, 84, -44, 52, -76, 116, -12,
+ 12, -116, 76, -52, 44, -84, 108, -20,
+ 28, -100, 92, -36, 60, -68, 124, -4,
+ 2, -126, 66, -62, 34, -94, 98, -30,
+ 18, -110, 82, -46, 50, -78, 114, -14,
+ 10, -118, 74, -54, 42, -86, 106, -22,
+ 26, -102, 90, -38, 58, -70, 122, -6,
+ 6, -122, 70, -58, 38, -90, 102, -26,
+ 22, -106, 86, -42, 54, -74, 118, -10,
+ 14, -114, 78, -50, 46, -82, 110, -18,
+ 30, -98, 94, -34, 62, -66, 126, -2,
+ 1, -127, 65, -63, 33, -95, 97, -31,
+ 17, -111, 81, -47, 49, -79, 113, -15,
+ 9, -119, 73, -55, 41, -87, 105, -23,
+ 25, -103, 89, -39, 57, -71, 121, -7,
+ 5, -123, 69, -59, 37, -91, 101, -27,
+ 21, -107, 85, -43, 53, -75, 117, -11,
+ 13, -115, 77, -51, 45, -83, 109, -19,
+ 29, -99, 93, -35, 61, -67, 125, -3,
+ 3, -125, 67, -61, 35, -93, 99, -29,
+ 19, -109, 83, -45, 51, -77, 115, -13,
+ 11, -117, 75, -53, 43, -85, 107, -21,
+ 27, -101, 91, -37, 59, -69, 123, -5,
+ 7, -121, 71, -57, 39, -89, 103, -25,
+ 23, -105, 87, -41, 55, -73, 119, -9,
+ 15, -113, 79, -49, 47, -81, 111, -17,
+ 31, -97, 95, -33, 63, -65, 127, -1,
+ };
+ // end
+}
diff --git a/src/java/org/apache/fop/render/AbstractRenderer.java b/src/java/org/apache/fop/render/AbstractRenderer.java
index c29dbea15..9e977cd80 100644
--- a/src/java/org/apache/fop/render/AbstractRenderer.java
+++ b/src/java/org/apache/fop/render/AbstractRenderer.java
@@ -28,11 +28,8 @@ import java.util.Iterator;
import java.util.List;
import java.util.Set;
-import org.w3c.dom.Document;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.area.Area;
@@ -68,6 +65,7 @@ import org.apache.fop.area.inline.WordArea;
import org.apache.fop.events.ResourceEventProducer;
import org.apache.fop.fo.Constants;
import org.apache.fop.fonts.FontInfo;
+import org.w3c.dom.Document;
/**
* Abstract base class for all renderers. The Abstract renderer does all the
@@ -504,7 +502,7 @@ public abstract class AbstractRenderer
*/
protected void renderBlocks(Block parent, List blocks) {
int saveIP = currentIPPosition;
- int saveBP = currentBPPosition;
+// int saveBP = currentBPPosition;
// Calculate the position of the content rectangle.
if (parent != null && !parent.getTraitAsBoolean(Trait.IS_VIEWPORT_AREA)) {
diff --git a/src/java/org/apache/fop/render/afp/AFPImageGraphics2DFactory.java b/src/java/org/apache/fop/render/afp/AFPImageGraphics2DFactory.java
index 2febe7171..ab9cf7ef7 100644
--- a/src/java/org/apache/fop/render/afp/AFPImageGraphics2DFactory.java
+++ b/src/java/org/apache/fop/render/afp/AFPImageGraphics2DFactory.java
@@ -51,11 +51,20 @@ public class AFPImageGraphics2DFactory extends AFPDataObjectInfoFactory {
return new AFPGraphicsObjectInfo();
}
+ private static final AFPResourceLevel inlineResourceLevel = new AFPResourceLevel(AFPResourceLevel.INLINE);
+
/** {@inheritDoc} */
public AFPDataObjectInfo create(AFPImageInfo afpImageInfo) throws IOException {
AFPGraphicsObjectInfo graphicsObjectInfo
= (AFPGraphicsObjectInfo)super.create(afpImageInfo);
+ AFPResourceInfo resourceInfo = graphicsObjectInfo.getResourceInfo();
+ // level not explicitly set/changed so default to inline for GOCA graphic objects
+ // (due to a bug in the IBM AFP Workbench Viewer (2.04.01.07) - hard copy works just fine)
+ if (!resourceInfo.levelChanged()) {
+ resourceInfo.setLevel(inlineResourceLevel);
+ }
+
// set mime type (unsupported by MOD:CA registry)
graphicsObjectInfo.setMimeType(MimeConstants.MIME_AFP_GOCA);
diff --git a/src/java/org/apache/fop/render/afp/AFPResourceInfo.java b/src/java/org/apache/fop/render/afp/AFPResourceInfo.java
index cdb7c0961..f52a3cd0b 100644
--- a/src/java/org/apache/fop/render/afp/AFPResourceInfo.java
+++ b/src/java/org/apache/fop/render/afp/AFPResourceInfo.java
@@ -35,6 +35,9 @@ public class AFPResourceInfo {
/** the resource level of this resource */
private AFPResourceLevel level = DEFAULT_LEVEL;
+ /** true when the resource level was changed */
+ private boolean levelChanged = false;
+
/**
* Sets the data object uri
*
@@ -90,6 +93,16 @@ public class AFPResourceInfo {
*/
public void setLevel(AFPResourceLevel resourceLevel) {
this.level = resourceLevel;
+ levelChanged = true;
+ }
+
+ /**
+ * Returns true when the resource level was set
+ *
+ * @return true when the resource level was set
+ */
+ public boolean levelChanged() {
+ return levelChanged;
}
/** {@inheritDoc} */
diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPResourceInfo.java b/src/java/org/apache/fop/render/afp/extensions/AFPResourceInfo.java
new file mode 100644
index 000000000..66d9555d6
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/extensions/AFPResourceInfo.java
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.extensions;
+
+import org.xml.sax.helpers.AttributesImpl;
+
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+//import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * An AFP resource group configuration definition for a document
+ */
+public class AFPResourceInfo extends AFPExtensionAttachment {
+ private static final long serialVersionUID = -7333967815112216396L;
+
+ /** AFP resource groups are stored in an external resource file */
+ private static final int LEVEL_INLINE = 0;
+
+ /** AFP resource groups are stored at page level */
+ private static final int LEVEL_PAGE = 1;
+
+ /** AFP resource groups are stored at page group level */
+ private static final int LEVEL_PAGE_GROUP = 2;
+
+ /** AFP resource groups are stored within the document at document level */
+ private static final int LEVEL_DOCUMENT = 3;
+
+ /** AFP resource groups are stored outside the document at print file level */
+ private static final int LEVEL_PRINT_FILE = 4;
+
+ /** AFP resource groups are stored in an external resource file */
+ private static final int LEVEL_EXTERNAL = 5;
+
+
+ private static final String LEVEL_NAME_INLINE = "inline";
+
+ private static final String LEVEL_NAME_PAGE = "page";
+
+ private static final String LEVEL_NAME_PAGE_GROUP = "page-group";
+
+ private static final String LEVEL_NAME_DOCUMENT = "document";
+
+ private static final String LEVEL_NAME_PRINT_FILE = "print-file";
+
+ private static final String LEVEL_NAME_EXTERNAL = "external";
+
+
+ /**
+ * level token/name mapping
+ */
+ private static final String[] LEVEL_NAME_MAP = {
+ LEVEL_NAME_INLINE, LEVEL_NAME_PAGE, LEVEL_NAME_PAGE_GROUP,
+ LEVEL_NAME_DOCUMENT, LEVEL_NAME_PRINT_FILE, LEVEL_NAME_EXTERNAL
+ };
+
+ /**
+ * the <afp:resource-info/> element name
+ */
+ public static final String ELEMENT = "resource-info";
+
+ /**
+ * the level at which resource groups are placed
+ */
+ private int level = -1;
+
+ /**
+ * the destination filename for resource groups with level = "external"
+ */
+ private String dest;
+
+ /**
+ * Default constructor.
+ */
+ public AFPResourceInfo() {
+ super(ELEMENT);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String toString() {
+ return "AFPResourceInfo("
+ + "name=" + name + ", "
+ + (level > -1 ? "level=" + LEVEL_NAME_MAP[level] : "")
+ + (dest != null ? ", dest=" + getDestination() : "" ) + ")";
+ }
+
+ /**
+ * Sets the destination filename of where resources
+ * are to be stored for this document
+ * @param destination the location of the external resource group file
+ */
+ public void setExternalDestination(String destination) {
+ this.dest = destination;
+ }
+
+ /**
+ * Returns the destination filename of where external resources
+ * are to be stored for this document.
+ * @return the destination AFP external resource filename
+ */
+ public String getDestination() {
+ return this.dest;
+ }
+
+ /**
+ * Sets the level at which resource groups are stored
+ * @param level the resource group level
+ */
+ public void setLevel(int level) {
+ this.level = level;
+ }
+
+ /**
+ * Sets the level at which resource groups are stored
+ * @param name the level name
+ */
+ public void setLevel(String name) {
+ if (name != null) {
+ for (int i = 0; i < LEVEL_NAME_MAP.length; i++) {
+ if (name.toLowerCase().equals(LEVEL_NAME_MAP[i])) {
+ this.level = i;
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the level at which resource groups are stored
+ * @return the level at which resource groups are stored
+ */
+ public int getLevel() {
+ return this.level;
+ }
+
+ private static final String ATT_LEVEL = "level";
+
+ private static final String ATT_DEST = "dest";
+
+ /**
+ * {@inheritDoc}
+ */
+ public void toSAX(ContentHandler handler) throws SAXException {
+ AttributesImpl atts = new AttributesImpl();
+
+ // name
+ if (hasName()) {
+ atts.addAttribute(null, ATT_NAME, ATT_NAME, "CDATA", super.getName());
+ }
+
+ // level
+ if (level > 0) {
+ atts.addAttribute(null, ATT_LEVEL, ATT_LEVEL, "CDATA", LEVEL_NAME_MAP[level]);
+
+ // dest
+ if (level == LEVEL_EXTERNAL && dest != null && dest.length() > 0) {
+ atts.addAttribute(null, ATT_DEST, ATT_DEST, "CDATA", dest);
+ }
+ }
+ handler.startElement(CATEGORY, elementName, elementName, atts);
+ handler.endElement(CATEGORY, elementName, elementName);
+ }
+
+ /**
+ * @return true if this resource group is to be stored externally
+ */
+ public boolean isExternalLevel() {
+ return level == LEVEL_EXTERNAL;
+ }
+} \ No newline at end of file
diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPResourceInfoElement.java b/src/java/org/apache/fop/render/afp/extensions/AFPResourceInfoElement.java
new file mode 100644
index 000000000..7613e80ae
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/extensions/AFPResourceInfoElement.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp.extensions;
+
+import org.apache.fop.apps.FOPException;
+//import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.Constants;
+import org.apache.fop.fo.FONode;
+//import org.apache.fop.fo.ValidationException;
+import org.apache.fop.fo.extensions.ExtensionAttachment;
+import org.apache.fop.fo.PropertyList;
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+
+/**
+ * Extension element for afp:resource-group
+ */
+public class AFPResourceInfoElement extends AbstractAFPExtensionObject {
+
+ /**
+ * Main constructor
+ * @param parent parent FO node
+ */
+ public AFPResourceInfoElement(FONode parent) {
+ super(parent, AFPResourceInfo.ELEMENT);
+ }
+
+ /**
+ * @throws FOPException if there's a problem during processing
+ * @see org.apache.fop.fo.FONode#startOfNode()
+ */
+ protected void startOfNode() throws FOPException {
+ if (parent.getNameId() != Constants.FO_INSTREAM_FOREIGN_OBJECT
+ && parent.getNameId() != Constants.FO_EXTERNAL_GRAPHIC) {
+ invalidChildError(getLocator(), parent.getName(), getNamespaceURI(), getName(),
+ "rule.childOfInstreamForeignObjectorExternalGraphic");
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void processNode(String elementName, Locator locator,
+ Attributes attlist, PropertyList propertyList)
+ throws FOPException {
+ getExtensionAttachment();
+ String attr = attlist.getValue("name");
+ if (attr != null && attr.length() > 0) {
+ extensionAttachment.setName(attr);
+ } else {
+ throw new FOPException(elementName + " must have a name attribute.");
+ }
+ String lvl = attlist.getValue("level");
+ AFPResourceInfo resourceInfo = (AFPResourceInfo)getExtensionAttachment();
+ if (lvl != null && lvl.length() > 0) {
+ resourceInfo.setLevel(lvl);
+ if (resourceInfo.isExternalLevel()) {
+ String dest = attlist.getValue("dest");
+ if (dest != null && dest.length() > 0) {
+ resourceInfo.setExternalDestination(dest);
+ } else {
+ throw new FOPException("must have a dest attribute.");
+ }
+ }
+ } else {
+ throw new FOPException("must have a level attribute.");
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected ExtensionAttachment instantiateExtensionAttachment() {
+ return new AFPResourceInfo();
+ }
+} \ No newline at end of file
diff --git a/src/java/org/apache/fop/render/afp/goca/GraphicsSetMix.java b/src/java/org/apache/fop/render/afp/goca/GraphicsSetMix.java
new file mode 100644
index 000000000..99a04d3ee
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/goca/GraphicsSetMix.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.afp.goca;
+
+import org.apache.fop.render.afp.modca.AbstractPreparedAFPObject;
+
+public class GraphicsSetMix extends AbstractPreparedAFPObject {
+
+ public static final byte MODE_DEFAULT = 0x00;
+ public static final byte MODE_OVERPAINT = 0x02;
+
+ /** the mix mode value */
+ private final byte mode;
+
+ /**
+ * Main constructor
+ *
+ * @param mode the mix mode value
+ */
+ public GraphicsSetMix(byte mode) {
+ this.mode = mode;
+ prepareData();
+ }
+
+ /** {@inheritDoc} */
+ protected void prepareData() {
+ super.data = new byte[] {
+ 0x0C, // GSMX order code
+ mode // MODE (mix mode value)
+ };
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return "GraphicsSetMix{mode=" + mode + "}";
+ }
+
+}
diff --git a/src/java/org/apache/fop/render/afp/modca/DocumentIndex.java b/src/java/org/apache/fop/render/afp/modca/DocumentIndex.java
new file mode 100644
index 000000000..5b3350b91
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/modca/DocumentIndex.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.render.afp.modca;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+
+/**
+ * The document index defined by the MOD:CA architecture provides functions
+ * for indexing the document based on document structure and on
+ * application-defined document tags.
+ */
+public class DocumentIndex extends AbstractStructuredAFPObject {
+ /**
+ * document index element
+ */
+ private IndexElement indexElement;
+
+ private List linkLogicalElements;
+
+ private List tagLogicalElements;
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void writeStart(OutputStream os) throws IOException {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void writeContent(OutputStream os) throws IOException {
+ indexElement.writeToStream(os);
+ writeObjects(linkLogicalElements, os);
+ writeObjects(tagLogicalElements, os);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ protected void writeEnd(OutputStream os) throws IOException {
+ }
+
+
+ private class IndexElement extends AbstractAFPObject {
+
+ public void writeToStream(OutputStream os) throws IOException {
+ }
+
+ }
+}
diff --git a/src/java/org/apache/fop/render/afp/svn-commit.2.tmp b/src/java/org/apache/fop/render/afp/svn-commit.2.tmp
new file mode 100644
index 000000000..986ccd6ae
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/svn-commit.2.tmp
@@ -0,0 +1,25 @@
+Moved goca package to level above modca.
+--This line, and those below, will be ignored--
+
+A goca
+A goca/GraphicsChainedSegment.java
+A goca/GraphicsSetPatternSymbol.java
+A goca/GraphicsFillet.java
+A goca/GraphicsSetCurrentPosition.java
+D goca/AbstractPreparedAFPObject.java
+A goca/GraphicsSetCharacterSet.java
+A goca/GraphicsImageBegin.java
+A goca/GraphicsLine.java
+A goca/GraphicsBox.java
+A goca/GraphicsFullArc.java
+A goca/GraphicsSetProcessColor.java
+A goca/AbstractGraphicsCoord.java
+A goca/GraphicsSetLineWidth.java
+A goca/GraphicsSetLineType.java
+A goca/GraphicsSetArcParameters.java
+A goca/AbstractGraphicsContainer.java
+A goca/GraphicsString.java
+A goca/GraphicsArea.java
+A goca/GraphicsImageEnd.java
+A goca/GraphicsData.java
+A goca/GraphicsImageData.java
diff --git a/src/java/org/apache/fop/render/afp/svn-commit.3.tmp b/src/java/org/apache/fop/render/afp/svn-commit.3.tmp
new file mode 100644
index 000000000..986ccd6ae
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/svn-commit.3.tmp
@@ -0,0 +1,25 @@
+Moved goca package to level above modca.
+--This line, and those below, will be ignored--
+
+A goca
+A goca/GraphicsChainedSegment.java
+A goca/GraphicsSetPatternSymbol.java
+A goca/GraphicsFillet.java
+A goca/GraphicsSetCurrentPosition.java
+D goca/AbstractPreparedAFPObject.java
+A goca/GraphicsSetCharacterSet.java
+A goca/GraphicsImageBegin.java
+A goca/GraphicsLine.java
+A goca/GraphicsBox.java
+A goca/GraphicsFullArc.java
+A goca/GraphicsSetProcessColor.java
+A goca/AbstractGraphicsCoord.java
+A goca/GraphicsSetLineWidth.java
+A goca/GraphicsSetLineType.java
+A goca/GraphicsSetArcParameters.java
+A goca/AbstractGraphicsContainer.java
+A goca/GraphicsString.java
+A goca/GraphicsArea.java
+A goca/GraphicsImageEnd.java
+A goca/GraphicsData.java
+A goca/GraphicsImageData.java
diff --git a/src/java/org/apache/fop/render/afp/svn-commit.tmp b/src/java/org/apache/fop/render/afp/svn-commit.tmp
new file mode 100644
index 000000000..986ccd6ae
--- /dev/null
+++ b/src/java/org/apache/fop/render/afp/svn-commit.tmp
@@ -0,0 +1,25 @@
+Moved goca package to level above modca.
+--This line, and those below, will be ignored--
+
+A goca
+A goca/GraphicsChainedSegment.java
+A goca/GraphicsSetPatternSymbol.java
+A goca/GraphicsFillet.java
+A goca/GraphicsSetCurrentPosition.java
+D goca/AbstractPreparedAFPObject.java
+A goca/GraphicsSetCharacterSet.java
+A goca/GraphicsImageBegin.java
+A goca/GraphicsLine.java
+A goca/GraphicsBox.java
+A goca/GraphicsFullArc.java
+A goca/GraphicsSetProcessColor.java
+A goca/AbstractGraphicsCoord.java
+A goca/GraphicsSetLineWidth.java
+A goca/GraphicsSetLineType.java
+A goca/GraphicsSetArcParameters.java
+A goca/AbstractGraphicsContainer.java
+A goca/GraphicsString.java
+A goca/GraphicsArea.java
+A goca/GraphicsImageEnd.java
+A goca/GraphicsData.java
+A goca/GraphicsImageData.java
diff --git a/src/java/org/apache/fop/svg/patch.diff b/src/java/org/apache/fop/svg/patch.diff
new file mode 100644
index 000000000..649a735ab
--- /dev/null
+++ b/src/java/org/apache/fop/svg/patch.diff
@@ -0,0 +1,44 @@
+Index: PDFGraphics2D.java
+===================================================================
+--- PDFGraphics2D.java (Revision 570024)
++++ PDFGraphics2D.java (Arbeitskopie)
+@@ -719,13 +719,15 @@
+ }
+
+ c = getColor();
+- if (graphicsState.setColor(c)) {
++ graphicsState.setColor(c);
++ // if (graphicsState.setColor(c)) {
+ applyColor(c, false);
+- }
++ // }
+ c = getBackground();
+- if (graphicsState.setBackColor(c)) {
++ graphicsState.setBackColor(c);
++ // if (graphicsState.setBackColor(c)) {
+ applyColor(c, true);
+- }
++ // }
+
+ Paint paint = getPaint();
+ if (graphicsState.setPaint(paint)) {
+@@ -1718,13 +1720,15 @@
+ }
+
+ c = getColor();
+- if (graphicsState.setColor(c)) {
++ graphicsState.setColor(c);
++ // if (graphicsState.setColor(c)) {
+ applyColor(c, true);
+- }
++ // }
+ c = getBackground();
+- if (graphicsState.setBackColor(c)) {
++ graphicsState.setBackColor(c);
++ // if (graphicsState.setBackColor(c)) {
+ applyColor(c, false);
+- }
++ // }
+
+ Paint paint = getPaint();
+ if (graphicsState.setPaint(paint)) {