aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/xmlgraphics-commons-1.3svn.jarbin498800 -> 499126 bytes
-rw-r--r--src/java/org/apache/fop/area/AreaTreeModel.java19
-rw-r--r--src/java/org/apache/fop/area/AreaTreeParser.java21
-rw-r--r--src/java/org/apache/fop/area/PageSequence.java53
-rw-r--r--src/java/org/apache/fop/area/RenderPagesModel.java17
-rw-r--r--src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java4
-rw-r--r--src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java8
-rw-r--r--src/java/org/apache/fop/pdf/PDFMetadata.java11
-rw-r--r--src/java/org/apache/fop/pdf/PDFRoot.java20
-rw-r--r--src/java/org/apache/fop/render/AbstractRenderer.java29
-rw-r--r--src/java/org/apache/fop/render/Renderer.java16
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFRenderer.java27
-rw-r--r--src/java/org/apache/fop/render/ps/PSRenderer.java6
-rw-r--r--src/java/org/apache/fop/render/xml/XMLRenderer.java17
-rw-r--r--status.xml4
-rw-r--r--test/java/org/apache/fop/render/pdf/PDFAMetadataTestCase.java2
-rw-r--r--test/layoutengine/hyphenation-testcases/block_hyphenation_kerning.xml2
-rw-r--r--test/layoutengine/standard-testcases/page-sequence_language.xml68
18 files changed, 258 insertions, 66 deletions
diff --git a/lib/xmlgraphics-commons-1.3svn.jar b/lib/xmlgraphics-commons-1.3svn.jar
index 75b10615a..ea00555ef 100644
--- a/lib/xmlgraphics-commons-1.3svn.jar
+++ b/lib/xmlgraphics-commons-1.3svn.jar
Binary files differ
diff --git a/src/java/org/apache/fop/area/AreaTreeModel.java b/src/java/org/apache/fop/area/AreaTreeModel.java
index bdbb88f2a..c43db31bb 100644
--- a/src/java/org/apache/fop/area/AreaTreeModel.java
+++ b/src/java/org/apache/fop/area/AreaTreeModel.java
@@ -22,10 +22,8 @@ package org.apache.fop.area;
// Java
import java.util.List;
-// XML
import org.xml.sax.SAXException;
-// Apache
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -55,10 +53,13 @@ public class AreaTreeModel {
/**
* Start a page sequence on this model.
- * @param title the title of the new page sequence
+ * @param pageSequence the page sequence about to start
*/
- public void startPageSequence(LineArea title) {
- currentPageSequence = new PageSequence(title);
+ public void startPageSequence(PageSequence pageSequence) {
+ if (pageSequence == null) {
+ throw new NullPointerException("pageSequence must not be null");
+ }
+ this.currentPageSequence = pageSequence;
pageSequenceList.add(currentPageSequence);
currentPageSequenceIndex = pageSequenceList.size() - 1;
}
@@ -91,6 +92,14 @@ public class AreaTreeModel {
public void endDocument() throws SAXException {};
/**
+ * Returns the currently active page-sequence.
+ * @return the currently active page-sequence
+ */
+ public PageSequence getCurrentPageSequence() {
+ return this.currentPageSequence;
+ }
+
+ /**
* Get the page sequence count.
* @return the number of page sequences in the document.
*/
diff --git a/src/java/org/apache/fop/area/AreaTreeParser.java b/src/java/org/apache/fop/area/AreaTreeParser.java
index d4cdf5239..fafb99ed6 100644
--- a/src/java/org/apache/fop/area/AreaTreeParser.java
+++ b/src/java/org/apache/fop/area/AreaTreeParser.java
@@ -141,7 +141,6 @@ public class AreaTreeParser {
private Stack areaStack = new Stack();
private boolean firstFlow;
- private boolean pendingStartPageSequence;
private Stack delegateStack = new Stack();
private ContentHandler delegate;
@@ -349,8 +348,12 @@ public class AreaTreeParser {
private class PageSequenceMaker extends AbstractMaker {
public void startElement(Attributes attributes) {
- pendingStartPageSequence = true;
- //treeModel.startPageSequence(null); Done after title or on the first viewport
+ PageSequence pageSequence = new PageSequence(null);
+ String lang = attributes.getValue("language");
+ pageSequence.setLanguage(lang);
+ String country = attributes.getValue("country");
+ pageSequence.setCountry(country);
+ areaStack.push(pageSequence);
}
}
@@ -364,19 +367,19 @@ public class AreaTreeParser {
public void endElement() {
LineArea line = (LineArea)areaStack.pop();
- treeModel.startPageSequence(line);
- pendingStartPageSequence = false;
+ PageSequence pageSequence = (PageSequence)areaStack.peek();
+ pageSequence.setTitle(line);
}
-
}
private class PageViewportMaker extends AbstractMaker {
public void startElement(Attributes attributes) {
- if (pendingStartPageSequence) {
- treeModel.startPageSequence(null);
- pendingStartPageSequence = false;
+ if (!areaStack.isEmpty()) {
+ PageSequence pageSequence = (PageSequence)areaStack.peek();
+ treeModel.startPageSequence(pageSequence);
+ areaStack.pop();
}
if (currentPageViewport != null) {
throw new IllegalStateException("currentPageViewport must be null");
diff --git a/src/java/org/apache/fop/area/PageSequence.java b/src/java/org/apache/fop/area/PageSequence.java
index d39ec7cf2..3b65f7701 100644
--- a/src/java/org/apache/fop/area/PageSequence.java
+++ b/src/java/org/apache/fop/area/PageSequence.java
@@ -28,13 +28,15 @@ public class PageSequence {
private List pages = new java.util.ArrayList();
private LineArea title;
+ private String language;
+ private String country;
/**
* Main constructor
* @param title the title for the page-sequence, may be null
*/
public PageSequence(LineArea title) {
- this.title = title;
+ setTitle(title);
}
/**
@@ -45,6 +47,14 @@ public class PageSequence {
}
/**
+ * Sets the page sequence's title.
+ * @param title the title
+ */
+ public void setTitle(LineArea title) {
+ this.title = title;
+ }
+
+ /**
* Adds a new page to the page sequence
* @param page the page to be added
*/
@@ -76,4 +86,45 @@ public class PageSequence {
public boolean isFirstPage(PageViewport page) {
return page.equals(getPage(0));
}
+
+ /**
+ * Returns the language of the page-sequence.
+ * @return the language (the value of the language property, "none" is mapped to null)
+ */
+ public String getLanguage() {
+ return this.language;
+ }
+
+ /**
+ * Sets the language that applies to this page-sequence.
+ * @param language the language to set ("none" is mapped to null)
+ */
+ public void setLanguage(String language) {
+ if ("none".equals(language)) {
+ this.language = null;
+ } else {
+ this.language = language;
+ }
+ }
+
+ /**
+ * Returns the country of the page-sequence.
+ * @return the country (the value of the country property, "none" is mapped to null)
+ */
+ public String getCountry() {
+ return this.country;
+ }
+
+ /**
+ * Sets the country that applies to this page-sequence.
+ * @param country the country to set ("none" is mapped to null)
+ */
+ public void setCountry(String country) {
+ if ("none".equals(country)) {
+ this.country = null;
+ } else {
+ this.country = country;
+ }
+ }
+
}
diff --git a/src/java/org/apache/fop/area/RenderPagesModel.java b/src/java/org/apache/fop/area/RenderPagesModel.java
index 1b3a22706..e080e9cbe 100644
--- a/src/java/org/apache/fop/area/RenderPagesModel.java
+++ b/src/java/org/apache/fop/area/RenderPagesModel.java
@@ -81,16 +81,11 @@ public class RenderPagesModel extends AreaTreeModel {
}
}
- /**
- * Start a new page sequence.
- * This tells the renderer that a new page sequence has
- * started with the given title.
- * @param title the title of the new page sequence
- */
- public void startPageSequence(LineArea title) {
- super.startPageSequence(title);
+ /** {@inheritDoc} */
+ public void startPageSequence(PageSequence pageSequence) {
+ super.startPageSequence(pageSequence);
if (renderer.supportsOutOfOrder()) {
- renderer.startPageSequence(title);
+ renderer.startPageSequence(getCurrentPageSequence());
}
}
@@ -112,7 +107,7 @@ public class RenderPagesModel extends AreaTreeModel {
boolean ready = renderer.supportsOutOfOrder() && page.isResolved();
if (ready) {
if (!renderer.supportsOutOfOrder() && page.getPageSequence().isFirstPage(page)) {
- renderer.startPageSequence(this.currentPageSequence.getTitle());
+ renderer.startPageSequence(getCurrentPageSequence());
}
try {
renderer.renderPage(page);
@@ -159,7 +154,7 @@ public class RenderPagesModel extends AreaTreeModel {
if (pageViewport.isResolved() || renderUnresolved) {
if (!renderer.supportsOutOfOrder()
&& pageViewport.getPageSequence().isFirstPage(pageViewport)) {
- renderer.startPageSequence(this.currentPageSequence.getTitle());
+ renderer.startPageSequence(getCurrentPageSequence());
}
try {
renderer.renderPage(pageViewport);
diff --git a/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java b/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java
index 89065185b..21856c781 100644
--- a/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/ExternalDocumentLayoutManager.java
@@ -39,6 +39,7 @@ import org.apache.fop.area.Block;
import org.apache.fop.area.BodyRegion;
import org.apache.fop.area.CTM;
import org.apache.fop.area.LineArea;
+import org.apache.fop.area.PageSequence;
import org.apache.fop.area.PageViewport;
import org.apache.fop.area.RegionViewport;
import org.apache.fop.area.inline.Image;
@@ -102,7 +103,7 @@ public class ExternalDocumentLayoutManager extends AbstractPageSequenceLayoutMan
Dimension intrinsicSize = info.getSize().getDimensionMpt();
ImageLayout layout = new ImageLayout(getExternalDocument(), this, intrinsicSize);
- areaTreeHandler.getAreaTreeModel().startPageSequence(null);
+ areaTreeHandler.getAreaTreeModel().startPageSequence(new PageSequence(null));
if (log.isDebugEnabled()) {
log.debug("Starting layout");
}
@@ -200,6 +201,7 @@ public class ExternalDocumentLayoutManager extends AbstractPageSequenceLayoutMan
}
}
+ /** {@inheritDoc} */
protected Page createPage(int pageNumber, boolean isBlank) {
String pageNumberString = pageSeq.makeFormattedPageNumber(pageNumber);
diff --git a/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java b/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java
index efe64d284..5816fe482 100644
--- a/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java
+++ b/src/java/org/apache/fop/layoutmgr/PageSequenceLayoutManager.java
@@ -23,6 +23,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.area.AreaTreeHandler;
+import org.apache.fop.area.AreaTreeModel;
import org.apache.fop.area.LineArea;
import org.apache.fop.fo.pagination.PageSequence;
import org.apache.fop.fo.pagination.PageSequenceMaster;
@@ -88,7 +89,12 @@ public class PageSequenceLayoutManager extends AbstractPageSequenceLayoutManager
}
}
- areaTreeHandler.getAreaTreeModel().startPageSequence(title);
+ AreaTreeModel areaTreeModel = areaTreeHandler.getAreaTreeModel();
+ org.apache.fop.area.PageSequence pageSequenceAreaObject
+ = new org.apache.fop.area.PageSequence(title);
+ pageSequenceAreaObject.setLanguage(getPageSequence().getLanguage());
+ pageSequenceAreaObject.setCountry(getPageSequence().getCountry());
+ areaTreeModel.startPageSequence(pageSequenceAreaObject);
if (log.isDebugEnabled()) {
log.debug("Starting layout");
}
diff --git a/src/java/org/apache/fop/pdf/PDFMetadata.java b/src/java/org/apache/fop/pdf/PDFMetadata.java
index 067502986..e0833a30f 100644
--- a/src/java/org/apache/fop/pdf/PDFMetadata.java
+++ b/src/java/org/apache/fop/pdf/PDFMetadata.java
@@ -25,6 +25,8 @@ import java.util.Date;
import javax.xml.transform.TransformerConfigurationException;
+import org.xml.sax.SAXException;
+
import org.apache.xmlgraphics.xmp.Metadata;
import org.apache.xmlgraphics.xmp.XMPSerializer;
import org.apache.xmlgraphics.xmp.schemas.DublinCoreAdapter;
@@ -36,8 +38,6 @@ import org.apache.xmlgraphics.xmp.schemas.pdf.AdobePDFSchema;
import org.apache.xmlgraphics.xmp.schemas.pdf.PDFAAdapter;
import org.apache.xmlgraphics.xmp.schemas.pdf.PDFAXMPSchema;
-import org.xml.sax.SAXException;
-
/**
* Special PDFStream for Metadata.
* @since PDF 1.4
@@ -118,10 +118,11 @@ public class PDFMetadata extends PDFStream {
* @param pdfDoc the PDF Document
* @return the requested XMP metadata
*/
- public static Metadata createXMPFromUserAgent(PDFDocument pdfDoc) {
+ public static Metadata createXMPFromPDFDocument(PDFDocument pdfDoc) {
Metadata meta = new Metadata();
PDFInfo info = pdfDoc.getInfo();
+ PDFRoot root = pdfDoc.getRoot();
//Set creation date if not available, yet
if (info.getCreationDate() == null) {
@@ -145,6 +146,10 @@ public class PDFMetadata extends PDFStream {
//Subject maps to dc:description["x-default"] as per ISO-19005-1:2005/Cor.1:2007
dc.setDescription(null, info.getSubject());
}
+ if (root.getLanguage() != null) {
+ //Note: No check is performed to make sure the value is valid RFC 3066!
+ dc.addLanguage(root.getLanguage());
+ }
dc.addDate(info.getCreationDate());
//PDF/A identification
diff --git a/src/java/org/apache/fop/pdf/PDFRoot.java b/src/java/org/apache/fop/pdf/PDFRoot.java
index 54cadf616..0dd9b890c 100644
--- a/src/java/org/apache/fop/pdf/PDFRoot.java
+++ b/src/java/org/apache/fop/pdf/PDFRoot.java
@@ -232,4 +232,24 @@ public class PDFRoot extends PDFDictionary {
}
}
+ /**
+ * Returns the language identifier of the document.
+ * @return the language identifier of the document (or null if not set or undefined)
+ * @since PDF 1.4
+ */
+ public String getLanguage() {
+ return (String)get("Lang");
+ }
+
+ /**
+ * Sets the language identifier of the document.
+ * @param lang the language identifier of the document.
+ */
+ public void setLanguage(String lang) {
+ if (lang == null) {
+ throw new NullPointerException("lang must not be null");
+ }
+ put("Lang", lang);
+ }
+
}
diff --git a/src/java/org/apache/fop/render/AbstractRenderer.java b/src/java/org/apache/fop/render/AbstractRenderer.java
index c23f7ae8e..86820066f 100644
--- a/src/java/org/apache/fop/render/AbstractRenderer.java
+++ b/src/java/org/apache/fop/render/AbstractRenderer.java
@@ -25,32 +25,35 @@ import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.OutputStream;
-import java.util.List;
import java.util.Iterator;
+import java.util.List;
import java.util.Set;
-// XML
import org.w3c.dom.Document;
-// FOP
+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;
import org.apache.fop.area.BeforeFloat;
import org.apache.fop.area.Block;
import org.apache.fop.area.BlockViewport;
import org.apache.fop.area.BodyRegion;
import org.apache.fop.area.CTM;
-import org.apache.fop.area.NormalFlow;
import org.apache.fop.area.Footnote;
import org.apache.fop.area.LineArea;
import org.apache.fop.area.MainReference;
-import org.apache.fop.area.Span;
+import org.apache.fop.area.NormalFlow;
+import org.apache.fop.area.OffDocumentItem;
import org.apache.fop.area.Page;
+import org.apache.fop.area.PageSequence;
import org.apache.fop.area.PageViewport;
-import org.apache.fop.area.RegionViewport;
import org.apache.fop.area.RegionReference;
+import org.apache.fop.area.RegionViewport;
+import org.apache.fop.area.Span;
import org.apache.fop.area.Trait;
-import org.apache.fop.area.OffDocumentItem;
import org.apache.fop.area.inline.Character;
import org.apache.fop.area.inline.Container;
import org.apache.fop.area.inline.ForeignObject;
@@ -60,15 +63,12 @@ import org.apache.fop.area.inline.InlineBlockParent;
import org.apache.fop.area.inline.InlineParent;
import org.apache.fop.area.inline.Leader;
import org.apache.fop.area.inline.Space;
-import org.apache.fop.area.inline.Viewport;
+import org.apache.fop.area.inline.SpaceArea;
import org.apache.fop.area.inline.TextArea;
+import org.apache.fop.area.inline.Viewport;
import org.apache.fop.area.inline.WordArea;
-import org.apache.fop.area.inline.SpaceArea;
-import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.fo.Constants;
import org.apache.fop.fonts.FontInfo;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
/**
* Abstract base class for all renderers. The Abstract renderer does all the
@@ -219,6 +219,11 @@ public abstract class AbstractRenderer
public void startPageSequence(LineArea seqTitle) {
//do nothing
}
+
+ /** {@inheritDoc} */
+ public void startPageSequence(PageSequence pageSequence) {
+ startPageSequence(pageSequence.getTitle());
+ }
// normally this would be overriden to create a page in the
// output
diff --git a/src/java/org/apache/fop/render/Renderer.java b/src/java/org/apache/fop/render/Renderer.java
index d54a61025..b40eec0cf 100644
--- a/src/java/org/apache/fop/render/Renderer.java
+++ b/src/java/org/apache/fop/render/Renderer.java
@@ -20,16 +20,16 @@
package org.apache.fop.render;
// Java
-import java.io.OutputStream;
import java.io.IOException;
+import java.io.OutputStream;
-// FOP
import org.apache.fop.apps.FOPException;
-import org.apache.fop.area.PageViewport;
+import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.area.LineArea;
import org.apache.fop.area.OffDocumentItem;
+import org.apache.fop.area.PageSequence;
+import org.apache.fop.area.PageViewport;
import org.apache.fop.fonts.FontInfo;
-import org.apache.fop.apps.FOUserAgent;
/**
@@ -142,10 +142,18 @@ public interface Renderer {
* Tells the renderer that a new page sequence starts.
*
* @param seqTitle The title of the page sequence
+ * @deprecated Use startPageSequence(PageSequence) instead
*/
void startPageSequence(LineArea seqTitle);
/**
+ * Tells the renderer that a new page sequence starts.
+ *
+ * @param pageSequence the page sequence
+ */
+ void startPageSequence(PageSequence pageSequence);
+
+ /**
* Tells the renderer to render a particular page. A renderer typically
* reponds by packing up the current page and writing it immediately to the
* output device.
diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java
index 899bc1240..4d641517a 100644
--- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java
+++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java
@@ -61,6 +61,7 @@ import org.apache.fop.area.DestinationData;
import org.apache.fop.area.LineArea;
import org.apache.fop.area.OffDocumentExtensionAttachment;
import org.apache.fop.area.OffDocumentItem;
+import org.apache.fop.area.PageSequence;
import org.apache.fop.area.PageViewport;
import org.apache.fop.area.RegionViewport;
import org.apache.fop.area.Trait;
@@ -611,7 +612,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
private void renderXMPMetadata(XMPMetadata metadata) {
Metadata docXMP = metadata.getMetadata();
- Metadata fopXMP = PDFMetadata.createXMPFromUserAgent(pdfDoc);
+ Metadata fopXMP = PDFMetadata.createXMPFromPDFDocument(pdfDoc);
//Merge FOP's own metadata into the one from the XSL-FO document
fopXMP.mergeInto(docXMP);
XMPBasicAdapter xmpBasic = XMPBasicSchema.getAdapter(docXMP);
@@ -679,13 +680,15 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
/**
* Start the next page sequence.
- * For the pdf renderer there is no concept of page sequences
+ * For the PDF renderer there is no concept of page sequences
* but it uses the first available page sequence title to set
- * as the title of the pdf document.
- *
- * @param seqTitle the title of the page sequence
+ * as the title of the PDF document, and the language of the
+ * document.
+ * @param pageSequence the page sequence
*/
- public void startPageSequence(LineArea seqTitle) {
+ public void startPageSequence(PageSequence pageSequence) {
+ super.startPageSequence(pageSequence);
+ LineArea seqTitle = pageSequence.getTitle();
if (seqTitle != null) {
String str = convertTitleToString(seqTitle);
PDFInfo info = this.pdfDoc.getInfo();
@@ -693,10 +696,20 @@ public class PDFRenderer extends AbstractPathOrientedRenderer {
info.setTitle(str);
}
}
+ if (pageSequence.getLanguage() != null) {
+ String lang = pageSequence.getLanguage();
+ String country = pageSequence.getCountry();
+ String langCode = lang + (country != null ? "-" + country : "");
+ if (pdfDoc.getRoot().getLanguage() == null) {
+ //Only set if not set already (first non-null is used)
+ //Note: No checking is performed whether the values are valid!
+ pdfDoc.getRoot().setLanguage(langCode);
+ }
+ }
if (pdfDoc.getRoot().getMetadata() == null) {
//If at this time no XMP metadata for the overall document has been set, create it
//from the PDFInfo object.
- Metadata xmp = PDFMetadata.createXMPFromUserAgent(pdfDoc);
+ Metadata xmp = PDFMetadata.createXMPFromPDFDocument(pdfDoc);
PDFMetadata pdfMetadata = pdfDoc.getFactory().makeMetadata(
xmp, true);
pdfDoc.getRoot().setMetadata(pdfMetadata);
diff --git a/src/java/org/apache/fop/render/ps/PSRenderer.java b/src/java/org/apache/fop/render/ps/PSRenderer.java
index 7e3ce87a2..ecd403749 100644
--- a/src/java/org/apache/fop/render/ps/PSRenderer.java
+++ b/src/java/org/apache/fop/render/ps/PSRenderer.java
@@ -72,7 +72,6 @@ import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.area.Area;
import org.apache.fop.area.BlockViewport;
import org.apache.fop.area.CTM;
-import org.apache.fop.area.LineArea;
import org.apache.fop.area.OffDocumentExtensionAttachment;
import org.apache.fop.area.OffDocumentItem;
import org.apache.fop.area.PageViewport;
@@ -1082,11 +1081,6 @@ public class PSRenderer extends AbstractPathOrientedRenderer
super.processOffDocumentItem(oDI);
}
- /** {@inheritDoc} */
- public void startPageSequence(LineArea seqTitle) {
- super.startPageSequence(seqTitle);
- }
-
/**
* Formats and writes a List of PSSetupCode instances to the output stream.
* @param setupCodeList a List of PSSetupCode instances
diff --git a/src/java/org/apache/fop/render/xml/XMLRenderer.java b/src/java/org/apache/fop/render/xml/XMLRenderer.java
index 213cba58d..66cce0ae1 100644
--- a/src/java/org/apache/fop/render/xml/XMLRenderer.java
+++ b/src/java/org/apache/fop/render/xml/XMLRenderer.java
@@ -61,6 +61,7 @@ import org.apache.fop.area.MainReference;
import org.apache.fop.area.NormalFlow;
import org.apache.fop.area.OffDocumentExtensionAttachment;
import org.apache.fop.area.OffDocumentItem;
+import org.apache.fop.area.PageSequence;
import org.apache.fop.area.PageViewport;
import org.apache.fop.area.RegionReference;
import org.apache.fop.area.RegionViewport;
@@ -585,14 +586,20 @@ public class XMLRenderer extends PrintRenderer {
handleExtensionAttachments(page.getExtensionAttachments());
}
- /**
- * {@inheritDoc}
- */
- public void startPageSequence(LineArea seqTitle) {
+ /** {@inheritDoc} */
+ public void startPageSequence(PageSequence pageSequence) {
handleDocumentExtensionAttachments();
endPageSequence(); // move this before handleDocumentExtensionAttachments() ?
startedSequence = true;
- startElement("pageSequence");
+ atts.clear();
+ if (pageSequence.getLanguage() != null) {
+ addAttribute("language", pageSequence.getLanguage());
+ }
+ if (pageSequence.getCountry() != null) {
+ addAttribute("country", pageSequence.getCountry());
+ }
+ startElement("pageSequence", atts);
+ LineArea seqTitle = pageSequence.getTitle();
if (seqTitle != null) {
startElement("title");
List children = seqTitle.getInlineAreas();
diff --git a/status.xml b/status.xml
index 83442d251..2622f4063 100644
--- a/status.xml
+++ b/status.xml
@@ -28,6 +28,10 @@
<changes>
<release version="FOP Trunk">
+ <action context="Renderers" dev="JM" type="add">
+ Added support for the natural language indentifier ("Lang" in the document catalog)
+ for PDF documents based on the language/country values on fo:page-sequence.
+ </action>
<action context="Code" dev="AD" type="fix" fixes-bug="44286" due-to="Stefan Ziel">
Fixed a memory-leak in XMLWhiteSpaceHandler.
</action>
diff --git a/test/java/org/apache/fop/render/pdf/PDFAMetadataTestCase.java b/test/java/org/apache/fop/render/pdf/PDFAMetadataTestCase.java
index 2821dcb24..b645022bb 100644
--- a/test/java/org/apache/fop/render/pdf/PDFAMetadataTestCase.java
+++ b/test/java/org/apache/fop/render/pdf/PDFAMetadataTestCase.java
@@ -94,7 +94,7 @@ public class PDFAMetadataTestCase extends TestCase {
cal2.set(Calendar.MILLISECOND, 0);
info.setModDate(cal2.getTime());
- Metadata meta = PDFMetadata.createXMPFromUserAgent(doc);
+ Metadata meta = PDFMetadata.createXMPFromPDFDocument(doc);
DublinCoreAdapter dc = DublinCoreSchema.getAdapter(meta);
assertEquals("MyTitle", dc.getTitle());
diff --git a/test/layoutengine/hyphenation-testcases/block_hyphenation_kerning.xml b/test/layoutengine/hyphenation-testcases/block_hyphenation_kerning.xml
index f1f0cbd1e..084f1e685 100644
--- a/test/layoutengine/hyphenation-testcases/block_hyphenation_kerning.xml
+++ b/test/layoutengine/hyphenation-testcases/block_hyphenation_kerning.xml
@@ -45,6 +45,8 @@
</fo>
<checks>
<eval expected="1" xpath="count(//pageViewport)"/>
+ <eval expected="en" xpath="/areaTree/pageSequence/@language"/>
+ <true xpath="not(boolean(/areaTree/pageSequence/@country))"/>
<eval expected="17230" xpath="//flow/block[1]/lineArea[1]/text[1]/@twsadjust"/>
<eval expected="-1339" xpath="//flow/block[1]/lineArea[2]/text[1]/@twsadjust"/>
diff --git a/test/layoutengine/standard-testcases/page-sequence_language.xml b/test/layoutengine/standard-testcases/page-sequence_language.xml
new file mode 100644
index 000000000..93238e282
--- /dev/null
+++ b/test/layoutengine/standard-testcases/page-sequence_language.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id$ -->
+<testcase>
+ <info>
+ <p>
+ This test checks the language and country property on page-sequence.
+ </p>
+ </info>
+ <fo>
+ <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" language="en">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="normal"
+ page-width="5in" page-height="5in">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="normal">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>language checking only</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ <fo:page-sequence master-reference="normal" language="en" country="US">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>language checking only</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ <fo:page-sequence master-reference="normal" language="de" country="CH">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>language checking only</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ <fo:page-sequence master-reference="normal" language="de" country="none">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block>language checking only</fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <eval expected="en" xpath="/areaTree/pageSequence[1]/@language"/>
+ <true xpath="not(boolean(/areaTree/pageSequence[1]/@country))"/>
+
+ <eval expected="en" xpath="/areaTree/pageSequence[2]/@language"/>
+ <eval expected="US" xpath="/areaTree/pageSequence[2]/@country"/>
+
+ <eval expected="de" xpath="/areaTree/pageSequence[3]/@language"/>
+ <eval expected="CH" xpath="/areaTree/pageSequence[3]/@country"/>
+
+ <eval expected="de" xpath="/areaTree/pageSequence[4]/@language"/>
+ <true xpath="not(boolean(/areaTree/pageSequence[4]/@country))"/>
+ </checks>
+</testcase>