From 5d677308df2545985dcf053f99703c506314a6e8 Mon Sep 17 00:00:00 2001 From: "Andreas L. Delmelle" Date: Mon, 24 Jan 2011 18:35:15 +0000 Subject: Bugzilla 50636: fix performance issue when adding pages in very large documents git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1062913 13f79535-47bb-0310-9956-ffa450edef68 --- status.xml | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'status.xml') diff --git a/status.xml b/status.xml index c80ba0668..b604971e5 100644 --- a/status.xml +++ b/status.xml @@ -59,6 +59,14 @@ documents. Example: the fix of marks layering will be such a case when it's done. --> + + Bugfix: fix performance issue when adding pages, if the total number of pages + is significantly large. + + + Bugfix: fix performance issue when adding nodes, if the number of children + is significantly large. + Bugfix: relative URIs in the configuration file (base, font-base, hyphenation-base) are evaluated relative to the base URI of the configuration file. -- cgit v1.2.3 From 6de2d9fab226f7da81f5c803100990f71f7e44e1 Mon Sep 17 00:00:00 2001 From: "Andreas L. Delmelle" Date: Mon, 24 Jan 2011 18:36:56 +0000 Subject: Credit where credit is due... git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1062914 13f79535-47bb-0310-9956-ffa450edef68 --- status.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'status.xml') diff --git a/status.xml b/status.xml index b604971e5..bb51ab16f 100644 --- a/status.xml +++ b/status.xml @@ -59,11 +59,11 @@ documents. Example: the fix of marks layering will be such a case when it's done. --> - + Bugfix: fix performance issue when adding pages, if the total number of pages is significantly large. - + Bugfix: fix performance issue when adding nodes, if the number of children is significantly large. -- cgit v1.2.3 From 1c8f05b0a02f3238ec6d508ed6e942b6104d7f1c Mon Sep 17 00:00:00 2001 From: "Andreas L. Delmelle" Date: Mon, 24 Jan 2011 22:18:42 +0000 Subject: Bugzilla 50635: fix issue in checkPreparedPages() where the same page-sequence is potentially started multiple times git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1063022 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/area/RenderPagesModel.java | 7 ++++--- status.xml | 4 ++++ 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'status.xml') diff --git a/src/java/org/apache/fop/area/RenderPagesModel.java b/src/java/org/apache/fop/area/RenderPagesModel.java index 592e49f1e..afec850f8 100644 --- a/src/java/org/apache/fop/area/RenderPagesModel.java +++ b/src/java/org/apache/fop/area/RenderPagesModel.java @@ -155,14 +155,15 @@ public class RenderPagesModel extends AreaTreeModel { * false if the renderer doesn't support out of order * rendering and there are pending pages */ - protected boolean checkPreparedPages(PageViewport newPageViewport, boolean - renderUnresolved) { + protected boolean checkPreparedPages(PageViewport newPageViewport, + boolean renderUnresolved) { + for (Iterator iter = prepared.iterator(); iter.hasNext();) { PageViewport pageViewport = (PageViewport)iter.next(); if (pageViewport.isResolved() || renderUnresolved) { if (!renderer.supportsOutOfOrder() && pageViewport.getPageSequence().isFirstPage(pageViewport)) { - renderer.startPageSequence(getCurrentPageSequence()); + renderer.startPageSequence(pageViewport.getPageSequence()); } renderPage(pageViewport); pageViewport.clear(); diff --git a/status.xml b/status.xml index bb51ab16f..dd131de73 100644 --- a/status.xml +++ b/status.xml @@ -59,6 +59,10 @@ documents. Example: the fix of marks layering will be such a case when it's done. --> + + Bugfix: fix issue in RenderPagesModel.checkPreparedPages() where the same page-sequence + is potentially started multiple times. + Bugfix: fix performance issue when adding pages, if the total number of pages is significantly large. -- cgit v1.2.3 From 941181b8e3bf0369f1803e9af89bff52c0c93c8f Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Tue, 1 Feb 2011 16:04:41 +0000 Subject: Allow afp:no-operation to be added to fo:page-sequence (page group in AFP) and fo:declarations (document in AFP). Includes a test case. Update QDox to avoid a bug with class private enums. Connect some older test cases into the standard test suite. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1066078 13f79535-47bb-0310-9956-ffa450edef68 --- build.xml | 1 + lib/build/qdox-1.12.jar | Bin 0 -> 179721 bytes lib/build/qdox-1.6.3.jar | Bin 104078 -> 0 bytes .../apache/fop/tools/EventProducerCollector.java | 15 ++- src/documentation/content/xdocs/trunk/output.xml | 12 +- src/java/org/apache/fop/afp/DataStream.java | 10 +- .../afp/modca/AbstractResourceGroupContainer.java | 4 +- src/java/org/apache/fop/afp/modca/NoOperation.java | 21 +++- .../apache/fop/fo/FOValidationEventProducer.xml | 1 + .../apache/fop/render/afp/AFPDocumentHandler.java | 80 +++++++++----- .../render/afp/extensions/AFPPageSetupElement.java | 10 +- status.xml | 3 + test/java/org/apache/fop/StandardTestSuite.java | 4 + .../fop/render/AbstractRenderingTestCase.java | 106 ++++++++++++++++++ .../org/apache/fop/render/afp/AFPTestSuite.java | 42 +++++++ .../apache/fop/render/afp/AbstractAFPTestCase.java | 47 ++++++++ .../apache/fop/render/afp/NoOperationTestCase.java | 123 +++++++++++++++++++++ test/java/org/apache/fop/render/afp/nops.fo | 41 +++++++ .../fop/render/ps/AbstractPostScriptTestCase.java | 54 +-------- .../fop/render/ps/ImageHandlingTestCase.java | 1 + .../java/org/apache/fop/render/ps/PSTestSuite.java | 43 +++++++ .../render/ps/ResourceOptimizationTestCase.java | 2 +- 22 files changed, 525 insertions(+), 95 deletions(-) create mode 100644 lib/build/qdox-1.12.jar delete mode 100644 lib/build/qdox-1.6.3.jar create mode 100644 test/java/org/apache/fop/render/AbstractRenderingTestCase.java create mode 100644 test/java/org/apache/fop/render/afp/AFPTestSuite.java create mode 100644 test/java/org/apache/fop/render/afp/AbstractAFPTestCase.java create mode 100644 test/java/org/apache/fop/render/afp/NoOperationTestCase.java create mode 100644 test/java/org/apache/fop/render/afp/nops.fo create mode 100644 test/java/org/apache/fop/render/ps/PSTestSuite.java (limited to 'status.xml') diff --git a/build.xml b/build.xml index c63de4004..b93a0176f 100644 --- a/build.xml +++ b/build.xml @@ -737,6 +737,7 @@ list of possible build targets. + diff --git a/lib/build/qdox-1.12.jar b/lib/build/qdox-1.12.jar new file mode 100644 index 000000000..3d850e5f5 Binary files /dev/null and b/lib/build/qdox-1.12.jar differ diff --git a/lib/build/qdox-1.6.3.jar b/lib/build/qdox-1.6.3.jar deleted file mode 100644 index 3e99cb064..000000000 Binary files a/lib/build/qdox-1.6.3.jar and /dev/null differ diff --git a/src/codegen/java/org/apache/fop/tools/EventProducerCollector.java b/src/codegen/java/org/apache/fop/tools/EventProducerCollector.java index 4721f41df..7b103e0cd 100644 --- a/src/codegen/java/org/apache/fop/tools/EventProducerCollector.java +++ b/src/codegen/java/org/apache/fop/tools/EventProducerCollector.java @@ -21,7 +21,6 @@ package org.apache.fop.tools; import java.io.File; import java.io.IOException; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; @@ -47,10 +46,10 @@ import com.thoughtworks.qdox.model.Type; class EventProducerCollector { private static final String CLASSNAME_EVENT_PRODUCER = EventProducer.class.getName(); - private static final Map PRIMITIVE_MAP; + private static final Map> PRIMITIVE_MAP; static { - Map m = new java.util.HashMap(); + Map > m = new java.util.HashMap>(); m.put("boolean", Boolean.class); m.put("byte", Byte.class); m.put("char", Character.class); @@ -63,7 +62,7 @@ class EventProducerCollector { } private DocletTagFactory tagFactory; - private List models = new ArrayList(); + private List models = new java.util.ArrayList(); /** * Creates a new EventProducerCollector. @@ -139,7 +138,7 @@ class EventProducerCollector { throws EventConventionException, ClassNotFoundException { JavaClass clazz = method.getParentClass(); //Check EventProducer conventions - if (!method.getReturns().isVoid()) { + if (!method.getReturnType().isVoid()) { throw new EventConventionException("All methods of interface " + clazz.getFullyQualifiedName() + " must have return type 'void'!"); } @@ -168,10 +167,10 @@ class EventProducerCollector { if (params.length > 1) { for (int j = 1, cj = params.length; j < cj; j++) { JavaParameter p = params[j]; - Class type; + Class type; JavaClass pClass = p.getType().getJavaClass(); if (p.getType().isPrimitive()) { - type = (Class)PRIMITIVE_MAP.get(pClass.getName()); + type = PRIMITIVE_MAP.get(pClass.getName()); if (type == null) { throw new UnsupportedOperationException( "Primitive datatype not supported: " + pClass.getName()); @@ -197,7 +196,7 @@ class EventProducerCollector { * Returns the event model that has been accumulated. * @return the event model. */ - public List getModels() { + public List getModels() { return this.models; } diff --git a/src/documentation/content/xdocs/trunk/output.xml b/src/documentation/content/xdocs/trunk/output.xml index 226a2d96c..ea994b521 100644 --- a/src/documentation/content/xdocs/trunk/output.xml +++ b/src/documentation/content/xdocs/trunk/output.xml @@ -931,9 +931,15 @@ Note that the value of the encoding attribute in the example is the double-byte ]]> -

The no-operation extension element can only occur within a simple-page-master. - Multiple no-operation extension elements within a simple-page-master are allowed. - The name attribute is mandatory. +

The no-operation extension element can appear as child of + simple-page-master (appears after "Begin Page" BPG), + page-sequence (appears after "Begin Named Page Group" BNG + and declarations (appears after "Begin Document" BDT). + Multiple no-operation extension elements inside the same formatting object are allowed. + Each NOP will appear right after the respective "Begin" field indicated above even if it + is specified as the last child under its parent. However, the order inside the parent + will be maintained. + The name attribute is mandatory but will not appear inside the AFP stream.

diff --git a/src/java/org/apache/fop/afp/DataStream.java b/src/java/org/apache/fop/afp/DataStream.java index a437c3004..2794ae932 100644 --- a/src/java/org/apache/fop/afp/DataStream.java +++ b/src/java/org/apache/fop/afp/DataStream.java @@ -595,7 +595,13 @@ public class DataStream { * byte data */ public void createNoOperation(String content) { - currentPage.createNoOperation(content); + if (currentPage != null) { + currentPage.createNoOperation(content); + } else if (currentPageGroup != null) { + currentPageGroup.createNoOperation(content); + } else { + document.createNoOperation(content); + } } /** @@ -639,9 +645,9 @@ public class DataStream { currentPageGroup.endPageGroup(); tleSequence = currentPageGroup.getTleSequence(); document.addPageGroup(currentPageGroup); - document.writeToStream(outputStream); currentPageGroup = null; } + document.writeToStream(outputStream); //Flush objects } /** diff --git a/src/java/org/apache/fop/afp/modca/AbstractResourceGroupContainer.java b/src/java/org/apache/fop/afp/modca/AbstractResourceGroupContainer.java index 2c5e02328..f8c5a38d3 100644 --- a/src/java/org/apache/fop/afp/modca/AbstractResourceGroupContainer.java +++ b/src/java/org/apache/fop/afp/modca/AbstractResourceGroupContainer.java @@ -126,6 +126,7 @@ implements Streamable { // } /** {@inheritDoc} */ + @Override public void writeToStream(OutputStream os) throws IOException { if (!started) { writeStart(os); @@ -140,6 +141,7 @@ implements Streamable { } /** {@inheritDoc} */ + @Override protected void writeObjects(Collection/**/ objects, OutputStream os) throws IOException { writeObjects(objects, os, false); @@ -176,7 +178,7 @@ implements Streamable { * @return true if this object can be written */ protected boolean canWrite(AbstractAFPObject obj) { - if (obj instanceof AbstractPageObject) { + if (obj instanceof Completable) { return ((Completable)obj).isComplete(); } else { diff --git a/src/java/org/apache/fop/afp/modca/NoOperation.java b/src/java/org/apache/fop/afp/modca/NoOperation.java index cb5841346..cb6f4d60b 100644 --- a/src/java/org/apache/fop/afp/modca/NoOperation.java +++ b/src/java/org/apache/fop/afp/modca/NoOperation.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.io.OutputStream; import org.apache.fop.afp.AFPConstants; +import org.apache.fop.afp.Completable; import org.apache.fop.afp.util.BinaryUtils; /** @@ -35,7 +36,7 @@ import org.apache.fop.afp.util.BinaryUtils; * No Operation structured fields, no semantics should be attached to * the data carried by the No Operation structured field in interchange */ -public class NoOperation extends AbstractAFPObject { +public class NoOperation extends AbstractAFPObject implements Completable { /** Up to 32759 bytes of data with no architectural definition */ private static final int MAX_DATA_LEN = 32759; @@ -81,7 +82,7 @@ public class NoOperation extends AbstractAFPObject { data[1] = rl1[0]; data[2] = rl1[1]; - // Structured field ID for a TLE + // Structured field ID for a NOP data[3] = (byte) 0xD3; data[4] = (byte) 0xEE; data[5] = (byte) 0xEE; @@ -97,4 +98,20 @@ public class NoOperation extends AbstractAFPObject { os.write(data); } + /** {@inheritDoc} */ + public boolean isComplete() { + return true; //always complete + } + + /** {@inheritDoc} */ + public void setComplete(boolean complete) { + //ignore + } + + /** {@inheritDoc} */ + @Override + public String toString() { + return "NOP: " + content.substring(0, Math.min(64, content.length())); + } + } \ No newline at end of file diff --git a/src/java/org/apache/fop/fo/FOValidationEventProducer.xml b/src/java/org/apache/fop/fo/FOValidationEventProducer.xml index c3e4b6b61..509f7c1d3 100644 --- a/src/java/org/apache/fop/fo/FOValidationEventProducer.xml +++ b/src/java/org/apache/fop/fo/FOValidationEventProducer.xml @@ -9,6 +9,7 @@ The element must be a child of fo:simple-page-master. The element must be a child of fo:declarations. The element must be a child of fo:declarations or fo:simple-page-master. + The element must be a child of fo:declarations, fo:simple-page-master or fo:page-sequence. The element must be a child of fo:instream-foreign-object or fo:external-graphic. The element must be a child of fo:page-sequence. The element must be a child of fo:page-sequence or fo:simple-page-master. diff --git a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java index c37e0c37c..87651defd 100644 --- a/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java +++ b/src/java/org/apache/fop/render/afp/AFPDocumentHandler.java @@ -77,17 +77,17 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler private DataStream dataStream; /** the map of page segments */ - private Map/**/pageSegmentMap - = new java.util.HashMap/**/(); + private Map pageSegmentMap + = new java.util.HashMap(); /** Medium Map referenced on previous page **/ private String lastMediumMap; - private static final int LOC_ELSEWHERE = 0; - private static final int LOC_FOLLOWING_PAGE_SEQUENCE = 1; - private static final int LOC_IN_PAGE_HEADER = 2; + private static enum Location { + ELSEWHERE, IN_DOCUMENT_HEADER, FOLLOWING_PAGE_SEQUENCE, IN_PAGE_HEADER + } - private int location = LOC_ELSEWHERE; + private Location location = Location.ELSEWHERE; /** the shading mode for filled rectangles */ private AFPShadingMode shadingMode = AFPShadingMode.COLOR; @@ -117,6 +117,7 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler } /** {@inheritDoc} */ + @Override public void setDefaultFontInfo(FontInfo fontInfo) { FontManager fontManager = getUserAgent().getFactory().getFontManager(); FontCollection[] fontCollections = new FontCollection[] { @@ -152,6 +153,7 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler } /** {@inheritDoc} */ + @Override public void startDocument() throws IFException { super.startDocument(); try { @@ -165,11 +167,23 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler } } + + /** {@inheritDoc} */ + @Override + public void startDocumentHeader() throws IFException { + super.startDocumentHeader(); + this.location = Location.IN_DOCUMENT_HEADER; + } + /** {@inheritDoc} */ + @Override public void endDocumentHeader() throws IFException { + super.endDocumentHeader(); + this.location = Location.ELSEWHERE; } /** {@inheritDoc} */ + @Override public void endDocument() throws IFException { try { this.dataStream.endDocument(); @@ -189,7 +203,7 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler } catch (IOException ioe) { throw new IFException("I/O error in startPageSequence()", ioe); } - this.location = LOC_FOLLOWING_PAGE_SEQUENCE; + this.location = Location.FOLLOWING_PAGE_SEQUENCE; } /** {@inheritDoc} */ @@ -212,7 +226,7 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler /** {@inheritDoc} */ public void startPage(int index, String name, String pageMasterName, Dimension size) throws IFException { - this.location = LOC_ELSEWHERE; + this.location = Location.ELSEWHERE; paintingState.clear(); AffineTransform baseTransform = getBaseTransform(); @@ -232,14 +246,16 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler } /** {@inheritDoc} */ + @Override public void startPageHeader() throws IFException { super.startPageHeader(); - this.location = LOC_IN_PAGE_HEADER; + this.location = Location.IN_PAGE_HEADER; } /** {@inheritDoc} */ + @Override public void endPageHeader() throws IFException { - this.location = LOC_ELSEWHERE; + this.location = Location.ELSEWHERE; super.endPageHeader(); } @@ -272,17 +288,36 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler AFPPageSetup aps = (AFPPageSetup)extension; String element = aps.getElementName(); if (AFPElementMapping.TAG_LOGICAL_ELEMENT.equals(element)) { - if (this.location != LOC_IN_PAGE_HEADER - && this.location != LOC_FOLLOWING_PAGE_SEQUENCE) { + switch (this.location) { + case FOLLOWING_PAGE_SEQUENCE: + case IN_PAGE_HEADER: + String name = aps.getName(); + String value = aps.getValue(); + dataStream.createTagLogicalElement(name, value); + break; + default: throw new IFException( "TLE extension must be in the page header or between page-sequence" + " and the first page: " + aps, null); } - String name = aps.getName(); - String value = aps.getValue(); - dataStream.createTagLogicalElement(name, value); + } else if (AFPElementMapping.NO_OPERATION.equals(element)) { + switch (this.location) { + case IN_DOCUMENT_HEADER: + case FOLLOWING_PAGE_SEQUENCE: + case IN_PAGE_HEADER: + String content = aps.getContent(); + if (content != null) { + dataStream.createNoOperation(content); + } + break; + default: + throw new IFException( + "NOP extension must be in the document header, the page header" + + " or between page-sequence" + + " and the first page: " + aps, null); + } } else { - if (this.location != LOC_IN_PAGE_HEADER) { + if (this.location != Location.IN_PAGE_HEADER) { throw new IFException( "AFP page setup extension encountered outside the page header: " + aps, null); @@ -294,16 +329,11 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler String source = apse.getValue(); String uri = apse.getResourceSrc(); pageSegmentMap.put(source, new PageSegmentDescriptor(name, uri)); - } else if (AFPElementMapping.NO_OPERATION.equals(element)) { - String content = aps.getContent(); - if (content != null) { - dataStream.createNoOperation(content); - } } } } else if (extension instanceof AFPPageOverlay) { AFPPageOverlay ipo = (AFPPageOverlay)extension; - if (this.location != LOC_IN_PAGE_HEADER) { + if (this.location != Location.IN_PAGE_HEADER) { throw new IFException( "AFP page overlay extension encountered outside the page header: " + ipo, null); @@ -313,8 +343,8 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler dataStream.createIncludePageOverlay(overlay, ipo.getX(), ipo.getY()); } } else if (extension instanceof AFPInvokeMediumMap) { - if (this.location != LOC_FOLLOWING_PAGE_SEQUENCE - && this.location != LOC_IN_PAGE_HEADER) { + if (this.location != Location.FOLLOWING_PAGE_SEQUENCE + && this.location != Location.IN_PAGE_HEADER) { throw new IFException( "AFP IMM extension must be between page-sequence" @@ -401,7 +431,7 @@ public class AFPDocumentHandler extends AbstractBinaryWritingIFDocumentHandler * @return the page segment descriptor or null if there's no page segment for the given URI */ PageSegmentDescriptor getPageSegmentNameFor(String uri) { - return (PageSegmentDescriptor)pageSegmentMap.get(uri); + return pageSegmentMap.get(uri); } } diff --git a/src/java/org/apache/fop/render/afp/extensions/AFPPageSetupElement.java b/src/java/org/apache/fop/render/afp/extensions/AFPPageSetupElement.java index 19f98f32a..b5b05191a 100644 --- a/src/java/org/apache/fop/render/afp/extensions/AFPPageSetupElement.java +++ b/src/java/org/apache/fop/render/afp/extensions/AFPPageSetupElement.java @@ -54,6 +54,7 @@ public class AFPPageSetupElement extends AbstractAFPExtensionObject { } /** {@inheritDoc} */ + @Override protected void startOfNode() throws FOPException { super.startOfNode(); if (AFPElementMapping.TAG_LOGICAL_ELEMENT.equals(getLocalName())) { @@ -63,14 +64,17 @@ public class AFPPageSetupElement extends AbstractAFPExtensionObject { "rule.childOfPageSequenceOrSPM"); } } else { - if (parent.getNameId() != Constants.FO_SIMPLE_PAGE_MASTER) { + if (parent.getNameId() != Constants.FO_SIMPLE_PAGE_MASTER + && parent.getNameId() != Constants.FO_PAGE_SEQUENCE + && parent.getNameId() != Constants.FO_DECLARATIONS) { invalidChildError(getLocator(), parent.getName(), getNamespaceURI(), getName(), - "rule.childOfSPM"); + "rule.childOfSPMorPSorDeclarations"); } } } /** {@inheritDoc} */ + @Override protected void characters(char[] data, int start, int length, PropertyList pList, Locator locator) throws FOPException { StringBuffer sb = new StringBuffer(); @@ -83,6 +87,7 @@ public class AFPPageSetupElement extends AbstractAFPExtensionObject { } /** {@inheritDoc} */ + @Override public void processNode(String elementName, Locator locator, Attributes attlist, PropertyList propertyList) throws FOPException { @@ -106,6 +111,7 @@ public class AFPPageSetupElement extends AbstractAFPExtensionObject { } /** {@inheritDoc} */ + @Override protected ExtensionAttachment instantiateExtensionAttachment() { return new AFPPageSetup(getLocalName()); } diff --git a/status.xml b/status.xml index dd131de73..8afa69af4 100644 --- a/status.xml +++ b/status.xml @@ -59,6 +59,9 @@ documents. Example: the fix of marks layering will be such a case when it's done. --> + + Allow afp:no-operation to also appear under fo:page-sequence and fo:declarations. + Bugfix: fix issue in RenderPagesModel.checkPreparedPages() where the same page-sequence is potentially started multiple times. diff --git a/test/java/org/apache/fop/StandardTestSuite.java b/test/java/org/apache/fop/StandardTestSuite.java index caf75b4b4..61a9bdc5e 100644 --- a/test/java/org/apache/fop/StandardTestSuite.java +++ b/test/java/org/apache/fop/StandardTestSuite.java @@ -26,12 +26,14 @@ import org.apache.fop.fonts.DejaVuLGCSerifTest; import org.apache.fop.image.loader.batik.ImageLoaderTestCase; import org.apache.fop.image.loader.batik.ImagePreloaderTestCase; import org.apache.fop.intermediate.IFMimickingTestCase; +import org.apache.fop.render.afp.AFPTestSuite; import org.apache.fop.render.extensions.prepress.PageBoundariesTest; import org.apache.fop.render.extensions.prepress.PageScaleTest; import org.apache.fop.render.pdf.PDFAConformanceTestCase; import org.apache.fop.render.pdf.PDFCMapTestCase; import org.apache.fop.render.pdf.PDFEncodingTestCase; import org.apache.fop.render.pdf.PDFsRGBSettingsTestCase; +import org.apache.fop.render.ps.PSTestSuite; import org.apache.fop.render.rtf.RichTextFormatTestSuite; import org.apache.fop.traits.MinOptMaxTest; @@ -54,6 +56,8 @@ public class StandardTestSuite { suite.addTest(new TestSuite(PDFCMapTestCase.class)); suite.addTest(new TestSuite(PDFsRGBSettingsTestCase.class)); suite.addTest(new TestSuite(DejaVuLGCSerifTest.class)); + suite.addTest(AFPTestSuite.suite()); + suite.addTest(PSTestSuite.suite()); suite.addTest(RichTextFormatTestSuite.suite()); suite.addTest(new TestSuite(ImageLoaderTestCase.class)); suite.addTest(new TestSuite(ImagePreloaderTestCase.class)); diff --git a/test/java/org/apache/fop/render/AbstractRenderingTestCase.java b/test/java/org/apache/fop/render/AbstractRenderingTestCase.java new file mode 100644 index 000000000..daaa94e41 --- /dev/null +++ b/test/java/org/apache/fop/render/AbstractRenderingTestCase.java @@ -0,0 +1,106 @@ +/* + * 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; + +import java.io.File; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Map; +import java.util.MissingResourceException; + +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.stream.StreamSource; + +import junit.framework.TestCase; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; + +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.apps.Fop; +import org.apache.fop.apps.FopFactory; +import org.apache.fop.apps.MimeConstants; + +/** + * Abstract base class for rendering (output) verification tests. + */ +public abstract class AbstractRenderingTestCase extends TestCase { + + private static final Map MIME_MAP = new java.util.HashMap(); + + static { + MIME_MAP.put(MimeConstants.MIME_PDF, ".pdf"); + MIME_MAP.put(MimeConstants.MIME_POSTSCRIPT, ".ps"); + MIME_MAP.put(MimeConstants.MIME_AFP, ".afp"); + } + + /** the JAXP TransformerFactory */ + protected TransformerFactory tFactory = TransformerFactory.newInstance(); + /** the FopFactory */ + protected FopFactory fopFactory = FopFactory.newInstance(); + + /** + * Renders a test file. + * @param ua the user agent (with override set!) + * @param resourceName the resource name for the FO file + * @param suffix a suffix for the output filename + * @param outputFormat MIME type of the requested output format + * @return the output file + * @throws Exception if an error occurs + */ + protected File renderFile(FOUserAgent ua, String resourceName, String suffix, + String outputFormat) throws Exception { + String extension = MIME_MAP.get(outputFormat); + assert extension != null; + File outputFile = new File("build/test-results/" + resourceName + suffix + extension); + File outputDir = outputFile.getParentFile(); + FileUtils.forceMkdir(outputDir); + + // Prepare input file + InputStream in = getClass().getResourceAsStream(resourceName); + if (in == null) { + throw new MissingResourceException(resourceName + " not found in resources", + getClass().getName(), null); + } + try { + Source src = new StreamSource(in); + + // Create output file + OutputStream out = new java.io.FileOutputStream(outputFile); + out = new java.io.BufferedOutputStream(out); + try { + Fop fop = fopFactory.newFop(outputFormat, ua, out); + SAXResult res = new SAXResult(fop.getDefaultHandler()); + + Transformer transformer = tFactory.newTransformer(); + transformer.transform(src, res); + } finally { + IOUtils.closeQuietly(out); + } + } finally { + IOUtils.closeQuietly(in); + } + return outputFile; + } + +} diff --git a/test/java/org/apache/fop/render/afp/AFPTestSuite.java b/test/java/org/apache/fop/render/afp/AFPTestSuite.java new file mode 100644 index 000000000..3f12746bf --- /dev/null +++ b/test/java/org/apache/fop/render/afp/AFPTestSuite.java @@ -0,0 +1,42 @@ +/* + * 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; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * Test suite for FOP's AFP output. + */ +public class AFPTestSuite { + + /** + * Builds the test suite + * @return the test suite + */ + public static Test suite() { + TestSuite suite = new TestSuite( + "Test suite for AFP output"); + //$JUnit-BEGIN$ + suite.addTest(new TestSuite(NoOperationTestCase.class)); + //$JUnit-END$ + return suite; + } +} diff --git a/test/java/org/apache/fop/render/afp/AbstractAFPTestCase.java b/test/java/org/apache/fop/render/afp/AbstractAFPTestCase.java new file mode 100644 index 000000000..7f081a4d0 --- /dev/null +++ b/test/java/org/apache/fop/render/afp/AbstractAFPTestCase.java @@ -0,0 +1,47 @@ +/* + * 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; + +import java.io.File; + +import org.apache.fop.apps.FOUserAgent; +import org.apache.fop.apps.MimeConstants; +import org.apache.fop.render.AbstractRenderingTestCase; + +/** + * Abstract base class for AFP verification tests. + */ +abstract class AbstractAFPTestCase extends AbstractRenderingTestCase { + + /** + * Renders a test file. + * @param ua the user agent (with override set!) + * @param resourceName the resource name for the FO file + * @param suffix a suffix for the output filename + * @return the output file + * @throws Exception if an error occurs + */ + protected File renderFile(FOUserAgent ua, String resourceName, String suffix) + throws Exception { + return renderFile(ua, resourceName, suffix, MimeConstants.MIME_AFP); + } + + +} diff --git a/test/java/org/apache/fop/render/afp/NoOperationTestCase.java b/test/java/org/apache/fop/render/afp/NoOperationTestCase.java new file mode 100644 index 000000000..56e4551d1 --- /dev/null +++ b/test/java/org/apache/fop/render/afp/NoOperationTestCase.java @@ -0,0 +1,123 @@ +/* + * 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; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; + +import junit.framework.Assert; + +import org.apache.commons.io.IOUtils; + +import org.apache.fop.afp.AFPConstants; +import org.apache.fop.afp.parser.MODCAParser; +import org.apache.fop.afp.parser.UnparsedStructuredField; +import org.apache.fop.apps.FOUserAgent; + +/** + * Tests generation of afp:no-operation (NOPs). + */ +public class NoOperationTestCase extends AbstractAFPTestCase { + + /** + * Tests afp:no-operation. + * @throws Exception if an error occurs + */ + public void testNoOperation() throws Exception { + FOUserAgent ua = fopFactory.newFOUserAgent(); + File outputFile = renderFile(ua, "nops.fo", ""); + + InputStream in = new java.io.FileInputStream(outputFile); + try { + MODCAParser parser = new MODCAParser(in); + UnparsedStructuredField field = skipTo(parser, 0xD3A8A8); //Begin Document + + //NOP in fo:declarations + field = parser.readNextStructuredField(); + assertEquals(0xD3EEEE, field.getSfTypeID()); + assertEquals("fo:declarations", getNopText(field)); + + field = parser.readNextStructuredField(); + assertEquals(0xD3A8AD, field.getSfTypeID()); //Begin Named Page Group + + //NOPs in fo:page-sequence + field = parser.readNextStructuredField(); + assertEquals(0xD3EEEE, field.getSfTypeID()); + assertEquals("fo:page-sequence: start", getNopText(field)); + field = parser.readNextStructuredField(); + assertEquals(0xD3EEEE, field.getSfTypeID()); + assertEquals("fo:page-sequence: end", getNopText(field)); + + field = parser.readNextStructuredField(); + assertEquals(0xD3A8AF, field.getSfTypeID()); //Begin Page + + field = skipTo(parser, 0xD3A9C9); //End Active Environment Group + field = parser.readNextStructuredField(); + assertEquals(0xD3EEEE, field.getSfTypeID()); + assertEquals("fo:simple-page-master: first", getNopText(field)); + + field = skipTo(parser, 0xD3A9C9); //End Active Environment Group + field = parser.readNextStructuredField(); + assertEquals(0xD3EEEE, field.getSfTypeID()); + assertEquals("fo:simple-page-master: rest", getNopText(field)); + } finally { + IOUtils.closeQuietly(in); + } + + int counter = 0; + in = new java.io.FileInputStream(outputFile); + try { + MODCAParser parser = new MODCAParser(in); + while (true) { + UnparsedStructuredField field = parser.readNextStructuredField(); + if (field == null) { + break; + } + if (field.getSfTypeID() == 0xD3EEEE) { + counter++; + } + } + } finally { + IOUtils.closeQuietly(in); + } + assertEquals(6, counter); //decl, 2 * ps, 3 * page/spm + } + + private String getNopText(UnparsedStructuredField field) throws UnsupportedEncodingException { + byte[] data = field.getData(); + String text = new String(data, AFPConstants.EBCIDIC_ENCODING); + return text; + } + + private UnparsedStructuredField skipTo(MODCAParser parser, int typeID) throws IOException { + UnparsedStructuredField field = null; + do { + field = parser.readNextStructuredField(); + if (field.getSfTypeID() == typeID) { + return field; + } + } while (field != null); + Assert.fail("Structured field not found: " + Integer.toHexString(typeID)); + return null; + } + +} diff --git a/test/java/org/apache/fop/render/afp/nops.fo b/test/java/org/apache/fop/render/afp/nops.fo new file mode 100644 index 000000000..96c6e0d24 --- /dev/null +++ b/test/java/org/apache/fop/render/afp/nops.fo @@ -0,0 +1,41 @@ + + + + + fo:simple-page-master: first + + + + + fo:simple-page-master: rest + + + + + + + + + + + + + fo:declarations + + + + fo:page-sequence: start + + Page 1 + Page 1 + + Page 2 + Page 2 + + Page 3 + Page 3 + + fo:page-sequence: end + + diff --git a/test/java/org/apache/fop/render/ps/AbstractPostScriptTestCase.java b/test/java/org/apache/fop/render/ps/AbstractPostScriptTestCase.java index 522d193ed..30e499846 100644 --- a/test/java/org/apache/fop/render/ps/AbstractPostScriptTestCase.java +++ b/test/java/org/apache/fop/render/ps/AbstractPostScriptTestCase.java @@ -21,20 +21,6 @@ package org.apache.fop.render.ps; import java.io.File; import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.MissingResourceException; - -import javax.xml.transform.Source; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.sax.SAXResult; -import javax.xml.transform.stream.StreamSource; - -import junit.framework.TestCase; - -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; import org.apache.xmlgraphics.ps.PSResource; import org.apache.xmlgraphics.ps.dsc.DSCException; @@ -44,19 +30,13 @@ import org.apache.xmlgraphics.ps.dsc.events.DSCComment; import org.apache.xmlgraphics.ps.dsc.events.DSCEvent; import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.apps.Fop; -import org.apache.fop.apps.FopFactory; import org.apache.fop.apps.MimeConstants; +import org.apache.fop.render.AbstractRenderingTestCase; /** * Abstract base class for PostScript verification tests. */ -public abstract class AbstractPostScriptTestCase extends TestCase { - - /** the JAXP TransformerFactory */ - protected TransformerFactory tFactory = TransformerFactory.newInstance(); - /** the FopFactory */ - protected FopFactory fopFactory = FopFactory.newInstance(); +public abstract class AbstractPostScriptTestCase extends AbstractRenderingTestCase { /** * Renders a test file. @@ -68,35 +48,7 @@ public abstract class AbstractPostScriptTestCase extends TestCase { */ protected File renderFile(FOUserAgent ua, String resourceName, String suffix) throws Exception { - File outputFile = new File("build/test-results/" + resourceName + suffix + ".ps"); - File outputDir = outputFile.getParentFile(); - FileUtils.forceMkdir(outputDir); - - // Prepare input file - InputStream in = getClass().getResourceAsStream(resourceName); - if (in == null) { - throw new MissingResourceException(resourceName + " not found in resources", - getClass().getName(), null); - } - try { - Source src = new StreamSource(in); - - // Create PostScript - OutputStream out = new java.io.FileOutputStream(outputFile); - out = new java.io.BufferedOutputStream(out); - try { - Fop fop = fopFactory.newFop(MimeConstants.MIME_POSTSCRIPT, ua, out); - SAXResult res = new SAXResult(fop.getDefaultHandler()); - - Transformer transformer = tFactory.newTransformer(); - transformer.transform(src, res); - } finally { - IOUtils.closeQuietly(out); - } - } finally { - IOUtils.closeQuietly(in); - } - return outputFile; + return renderFile(ua, resourceName, suffix, MimeConstants.MIME_POSTSCRIPT); } /** diff --git a/test/java/org/apache/fop/render/ps/ImageHandlingTestCase.java b/test/java/org/apache/fop/render/ps/ImageHandlingTestCase.java index 72c677a0c..c127d82a5 100644 --- a/test/java/org/apache/fop/render/ps/ImageHandlingTestCase.java +++ b/test/java/org/apache/fop/render/ps/ImageHandlingTestCase.java @@ -86,6 +86,7 @@ public class ImageHandlingTestCase extends AbstractPostScriptTestCase { gotoDSCComment(parser, DSCConstants.BEGIN_RESOURCE); gotoDSCComment(parser, DSCConstants.BEGIN_RESOURCE); gotoDSCComment(parser, DSCConstants.BEGIN_RESOURCE); + gotoDSCComment(parser, DSCConstants.BEGIN_RESOURCE); PSResource form2 = new PSResource(PSResource.TYPE_FORM, "FOPForm:2"); checkResourceComment(parser, DSCConstants.BEGIN_RESOURCE, form2); diff --git a/test/java/org/apache/fop/render/ps/PSTestSuite.java b/test/java/org/apache/fop/render/ps/PSTestSuite.java new file mode 100644 index 000000000..05ba2dac7 --- /dev/null +++ b/test/java/org/apache/fop/render/ps/PSTestSuite.java @@ -0,0 +1,43 @@ +/* + * 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; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + * Test suite for FOP's PostScript output. + */ +public class PSTestSuite { + + /** + * Builds the test suite + * @return the test suite + */ + public static Test suite() { + TestSuite suite = new TestSuite( + "Test suite for PostScript output"); + //$JUnit-BEGIN$ + suite.addTest(new TestSuite(ImageHandlingTestCase.class)); + suite.addTest(new TestSuite(ResourceOptimizationTestCase.class)); + //$JUnit-END$ + return suite; + } +} diff --git a/test/java/org/apache/fop/render/ps/ResourceOptimizationTestCase.java b/test/java/org/apache/fop/render/ps/ResourceOptimizationTestCase.java index 862ad5205..327c86548 100644 --- a/test/java/org/apache/fop/render/ps/ResourceOptimizationTestCase.java +++ b/test/java/org/apache/fop/render/ps/ResourceOptimizationTestCase.java @@ -90,7 +90,7 @@ public class ResourceOptimizationTestCase extends AbstractPostScriptTestCase { = (DSCCommentDocumentSuppliedResources)gotoDSCComment(parser, DSCConstants.DOCUMENT_SUPPLIED_RESOURCES); Set resources = supplied.getResources(); - assertEquals(4, resources.size()); + assertEquals(5, resources.size()); assertTrue(resources.contains(form1)); assertTrue("Expected barcode.eps as supplied resource", resources.contains(new PSResource(PSResource.TYPE_FILE, -- cgit v1.2.3 From d8261a197b2d8cd10c3f171f2a3ca7e9f04f1302 Mon Sep 17 00:00:00 2001 From: "Andreas L. Delmelle" Date: Tue, 1 Feb 2011 20:20:02 +0000 Subject: Bugzilla 48334: Added implementation for xml:base git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1066190 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/fo/Constants.java | 4 +- src/java/org/apache/fop/fo/FOPropertyMapping.java | 9 +- src/java/org/apache/fop/fo/PropertyList.java | 3 +- .../org/apache/fop/fo/properties/URIProperty.java | 148 +++++++++++++++++++++ status.xml | 4 + test/fotree/testcases/xml_base.fo | 82 ++++++++++++ 6 files changed, 247 insertions(+), 3 deletions(-) create mode 100644 src/java/org/apache/fop/fo/properties/URIProperty.java create mode 100644 test/fotree/testcases/xml_base.fo (limited to 'status.xml') diff --git a/src/java/org/apache/fop/fo/Constants.java b/src/java/org/apache/fop/fo/Constants.java index 5f23502f3..726d4d89e 100644 --- a/src/java/org/apache/fop/fo/Constants.java +++ b/src/java/org/apache/fop/fo/Constants.java @@ -778,9 +778,11 @@ public interface Constants { * Used for accessibility. */ int PR_X_ALT_TEXT = 275; + /** Property constant - FOP proprietary prototype (in XSL-FO 2.0 Requirements) */ + int PR_X_XML_BASE = 276; /** Number of property constants defined */ - int PROPERTY_COUNT = 275; + int PROPERTY_COUNT = 276; // compound property constants diff --git a/src/java/org/apache/fop/fo/FOPropertyMapping.java b/src/java/org/apache/fop/fo/FOPropertyMapping.java index b1e851ea4..c32aca0f0 100644 --- a/src/java/org/apache/fop/fo/FOPropertyMapping.java +++ b/src/java/org/apache/fop/fo/FOPropertyMapping.java @@ -64,6 +64,7 @@ import org.apache.fop.fo.properties.StringProperty; import org.apache.fop.fo.properties.TableBorderPrecedence; import org.apache.fop.fo.properties.TextDecorationProperty; import org.apache.fop.fo.properties.ToBeImplementedProperty; +import org.apache.fop.fo.properties.URIProperty; import org.apache.fop.fo.properties.VerticalAlignShorthandParser; import org.apache.fop.fo.properties.WhiteSpaceShorthandParser; import org.apache.fop.fo.properties.XMLLangShorthandParser; @@ -2572,7 +2573,7 @@ public final class FOPropertyMapping implements Constants { addPropertyMaker("score-spaces", m); // src - m = new StringProperty.Maker(PR_SRC); + m = new URIProperty.Maker(PR_SRC); m.setInherited(false); m.setDefault(""); addPropertyMaker("src", m); @@ -2819,6 +2820,12 @@ public final class FOPropertyMapping implements Constants { m.setDatatypeParser(new XMLLangShorthandParser()); addPropertyMaker("xml:lang", m); + // xml:base + m = new URIProperty.Maker(PR_X_XML_BASE); + m.setInherited(true); + m.setDefault(""); + addPropertyMaker("xml:base", m); + } } diff --git a/src/java/org/apache/fop/fo/PropertyList.java b/src/java/org/apache/fop/fo/PropertyList.java index 8d5a4311f..a1634e868 100644 --- a/src/java/org/apache/fop/fo/PropertyList.java +++ b/src/java/org/apache/fop/fo/PropertyList.java @@ -312,7 +312,8 @@ public abstract class PropertyList { attributeName = attributes.getQName(i); attributeValue = attributes.getValue(i); if (attributeNS == null || attributeNS.length() == 0 - || "xml:lang".equals(attributeName)) { + || "xml:lang".equals(attributeName) + || "xml:base".equals(attributeName)) { convertAttributeToProperty(attributes, attributeName, attributeValue); } else if (!factory.isNamespaceIgnored(attributeNS)) { ElementMapping mapping = factory.getElementMappingRegistry().getElementMapping( diff --git a/src/java/org/apache/fop/fo/properties/URIProperty.java b/src/java/org/apache/fop/fo/properties/URIProperty.java new file mode 100644 index 000000000..6465fafdb --- /dev/null +++ b/src/java/org/apache/fop/fo/properties/URIProperty.java @@ -0,0 +1,148 @@ +/* + * 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.fo.properties; + +import org.apache.fop.datatypes.URISpecification; +import org.apache.fop.fo.FObj; +import org.apache.fop.fo.PropertyList; +import org.apache.fop.fo.expr.PropertyException; + +import java.net.URI; +import java.net.URISyntaxException; + +import static org.apache.fop.fo.Constants.PR_X_XML_BASE; + +/** + * Class modeling a property that has a value of type <uri-specification>. + * The purpose is mainly to support resolution of a specified + * relative URI against a specified or inherited xml:base + * during the property refinement stage. + * If no xml:base has been specified, only the original URI, as + * it appears in the source document, is stored as the property's specified + * value. + */ +public class URIProperty extends Property { + + /** will be null if the URI is not resolved against an xml:base */ + private URI resolvedURI; + + /** + * Default constructor, to create a {@link URIProperty} from a + * {@code java.net.URI} directly. + * @param uri a resolved {@code java.net.URI} + */ + protected URIProperty(URI uri) { + this.resolvedURI = uri; + } + + /** + * Alternate constructor, to create a {@link URIProperty} from a + * string representation. + * @param uri a {@code java.lang.String} representing the URI + * @param resolve flag indicating whether this URI was the result of resolution + * @throws IllegalArgumentException if the URI should be resolved, but is not valid. + */ + private URIProperty(String uri, boolean resolve) { + if (resolve && !(uri == null || "".equals(uri))) { + this.resolvedURI = URI.create(uri); + } else { + setSpecifiedValue(uri); + } + } + + /** + * Return a string representing the resolved URI, or the + * specified value if the URI is not resolved against + * an xml:base + * @return a string representing the URI + */ + @Override + public String getString() { + if (resolvedURI == null) { + return getSpecifiedValue(); + } else { + return resolvedURI.toString(); + } + } + + /** {@inheritDoc} */ + @Override + public String toString() { + return this.getString(); + } + + /** + * Inner {@link PropertyMaker} subclass responsible + * for making instances of this type. + */ + public static class Maker extends PropertyMaker { + + /** + * Create a maker for the given property id + * + * @param propId the id of the property for which a Maker should be created + */ + public Maker(int propId) { + super(propId); + } + + /** + * {@inheritDoc} + * Check if {@code xml:base} has been specified and whether the + * given {@code value} represents a relative URI. If so, create + * a property representing the resolved URI. + */ + @Override + public Property make(PropertyList propertyList, String value, + FObj fo) throws PropertyException { + + Property p = null; + //special treament for data: URIs + if (value.matches("(?s)^(url\\(('|\")?)?data:.*$")) { + p = new URIProperty(value, false); + } else { + try { + URI specifiedURI = new URI(URISpecification.escapeURI(value)); + URIProperty xmlBase = (URIProperty)propertyList.get(PR_X_XML_BASE, true, false); + if (xmlBase == null) { + //xml:base undefined + if (this.propId == PR_X_XML_BASE) { + //if current property is xml:base, define a new one + p = new URIProperty(specifiedURI); + p.setSpecifiedValue(value); + } else { + //otherwise, just store the specified value (for backward compatibility) + p = new URIProperty(value, false); + } + } else { + //xml:base defined, so resolve + p = new URIProperty(xmlBase.resolvedURI.resolve(specifiedURI)); + p.setSpecifiedValue(value); + } + } catch (URISyntaxException use) { + // Let PropertyList propagate the exception + throw new PropertyException("Invalid URI specified"); + } + } + return p; + } + } + +} diff --git a/status.xml b/status.xml index 8afa69af4..c0c759763 100644 --- a/status.xml +++ b/status.xml @@ -59,6 +59,10 @@ documents. Example: the fix of marks layering will be such a case when it's done. --> + + Added support for resolution of relative URIs against a specified xml:base during + property refinement. + Allow afp:no-operation to also appear under fo:page-sequence and fo:declarations. diff --git a/test/fotree/testcases/xml_base.fo b/test/fotree/testcases/xml_base.fo new file mode 100644 index 000000000..fa4858d7c --- /dev/null +++ b/test/fotree/testcases/xml_base.fo @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3 From d42674784ff6bda51cf4b28b377414b059cbcfd7 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Wed, 2 Feb 2011 10:19:18 +0000 Subject: Bugzilla #50699: Added support for lookup of alternative glyphs when additional single-byte encodings are used, ex. replacing "Omegagreek" by "Omega" and vice versa. Submitted by: Alexandros Papadakis Changes to patch: - fixed a couple of typos - code formatting - a little code optimization git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1066400 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/fonts/SingleByteFont.java | 68 +++++++++++++++++++++-- status.xml | 4 ++ 2 files changed, 67 insertions(+), 5 deletions(-) (limited to 'status.xml') diff --git a/src/java/org/apache/fop/fonts/SingleByteFont.java b/src/java/org/apache/fop/fonts/SingleByteFont.java index d798db1bb..b832eec2b 100644 --- a/src/java/org/apache/fop/fonts/SingleByteFont.java +++ b/src/java/org/apache/fop/fonts/SingleByteFont.java @@ -29,6 +29,8 @@ import java.util.TreeSet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.xmlgraphics.fonts.Glyphs; + /** * Generic SingleByte font */ @@ -44,6 +46,7 @@ public class SingleByteFont extends CustomFont { private Map unencodedCharacters; private List additionalEncodings; + private Map alternativeCodes; /** @@ -99,19 +102,69 @@ public class SingleByteFont extends CustomFont { return arr; } - /** {@inheritDoc} */ - @Override - public char mapChar(char c) { - notifyMapOperation(); + /** + * Lookup a character using its alternative names. If found, cache it so we + * can speed up lookups. + * @param c the character + * @return the suggested alternative character present in the font + */ + private char findAlternative(char c) { + char d; + if (alternativeCodes == null) { + alternativeCodes = new java.util.HashMap(); + } else { + Character alternative = alternativeCodes.get(c); + if (alternative != null) { + return alternative; + } + } + String charName = Glyphs.charToGlyphName(c); + String[] charNameAlternatives = Glyphs.getCharNameAlternativesFor(charName); + if (charNameAlternatives != null && charNameAlternatives.length > 0) { + for (int i = 0; i < charNameAlternatives.length; i++) { + if (log.isDebugEnabled()) { + log.debug("Checking alternative for char " + c + " (charname=" + + charName + "): " + charNameAlternatives[i]); + } + String s = Glyphs.getUnicodeSequenceForGlyphName(charNameAlternatives[i]); + if (s != null) { + d = lookupChar(s.charAt(0)); + if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) { + alternativeCodes.put(c, d); + return d; + } + } + } + } + + return SingleByteEncoding.NOT_FOUND_CODE_POINT; + } + + private char lookupChar(char c) { char d = mapping.mapChar(c); if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) { return d; } - //Check unencoded characters which are available in the font by character name + // Check unencoded characters which are available in the font by + // character name d = mapUnencodedChar(c); + return d; + } + + /** {@inheritDoc} */ + @Override + public char mapChar(char c) { + notifyMapOperation(); + char d = lookupChar(c); if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) { return d; + } else { + // Check for alternative + d = findAlternative(c); + if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) { + return d; + } } this.warnMissingGlyph(c); return Typeface.NOT_FOUND; @@ -162,6 +215,11 @@ public class SingleByteFont extends CustomFont { if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) { return true; } + // Check if an alternative exists + d = findAlternative(c); + if (d != SingleByteEncoding.NOT_FOUND_CODE_POINT) { + return true; + } return false; } diff --git a/status.xml b/status.xml index c0c759763..2ba48dc80 100644 --- a/status.xml +++ b/status.xml @@ -59,6 +59,10 @@ documents. Example: the fix of marks layering will be such a case when it's done. --> + + Added support for lookup of alternative glyphs when additional single-byte encodings are + used, ex. replacing "Omegagreek" by "Omega" and vice versa. + Added support for resolution of relative URIs against a specified xml:base during property refinement. -- cgit v1.2.3 From 2068719a604acf7eaccadf185c7112bd2e6e2565 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Fri, 4 Feb 2011 08:14:41 +0000 Subject: Bugzilla #50705: Fix to preserve the order of AFP TLEs and NOPs as given in the XSL-FO document. Submitted by: Mehdi Houshmand git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1067109 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/afp/modca/AbstractPageObject.java | 11 ++++------- src/java/org/apache/fop/afp/modca/Overlay.java | 1 - src/java/org/apache/fop/afp/modca/PageGroup.java | 6 ------ src/java/org/apache/fop/afp/modca/PageObject.java | 1 - status.xml | 3 +++ 5 files changed, 7 insertions(+), 15 deletions(-) (limited to 'status.xml') diff --git a/src/java/org/apache/fop/afp/modca/AbstractPageObject.java b/src/java/org/apache/fop/afp/modca/AbstractPageObject.java index 1454cf96d..99afd322a 100644 --- a/src/java/org/apache/fop/afp/modca/AbstractPageObject.java +++ b/src/java/org/apache/fop/afp/modca/AbstractPageObject.java @@ -57,11 +57,8 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject implemen /** The current presentation text object */ private PresentationTextObject currentPresentationTextObject = null; - /** The list of tag logical elements */ - protected List/**/ tagLogicalElements = null; - /** The list of objects within this resource container */ - protected List/**/ objects = new java.util.ArrayList(); + protected List/**/ objects = new java.util.ArrayList(); /** The page width */ private int width; @@ -217,10 +214,10 @@ public abstract class AbstractPageObject extends AbstractNamedAFPObject implemen * @return the TLEs */ protected List getTagLogicalElements() { - if (tagLogicalElements == null) { - this.tagLogicalElements = new java.util.ArrayList/**/(); + if (objects == null) { + this.objects = new java.util.ArrayList/**/(); } - return this.tagLogicalElements; + return this.objects; } /** diff --git a/src/java/org/apache/fop/afp/modca/Overlay.java b/src/java/org/apache/fop/afp/modca/Overlay.java index 0179c94a7..2793e93f5 100644 --- a/src/java/org/apache/fop/afp/modca/Overlay.java +++ b/src/java/org/apache/fop/afp/modca/Overlay.java @@ -72,7 +72,6 @@ public class Overlay extends PageObject { getActiveEnvironmentGroup().writeToStream(os); - writeObjects(tagLogicalElements, os); writeObjects(objects, os); } diff --git a/src/java/org/apache/fop/afp/modca/PageGroup.java b/src/java/org/apache/fop/afp/modca/PageGroup.java index 895ec1259..aceb0ff80 100644 --- a/src/java/org/apache/fop/afp/modca/PageGroup.java +++ b/src/java/org/apache/fop/afp/modca/PageGroup.java @@ -75,12 +75,6 @@ public class PageGroup extends AbstractResourceEnvironmentGroupContainer { complete = true; } - /** {@inheritDoc} */ - protected void writeContent(OutputStream os) throws IOException { - writeObjects(tagLogicalElements, os, true); - super.writeContent(os); - } - /** {@inheritDoc} */ protected void writeStart(OutputStream os) throws IOException { byte[] data = new byte[17]; diff --git a/src/java/org/apache/fop/afp/modca/PageObject.java b/src/java/org/apache/fop/afp/modca/PageObject.java index 6c2547f0b..33bfe0997 100644 --- a/src/java/org/apache/fop/afp/modca/PageObject.java +++ b/src/java/org/apache/fop/afp/modca/PageObject.java @@ -185,7 +185,6 @@ public class PageObject extends AbstractResourceGroupContainer { getActiveEnvironmentGroup().writeToStream(os); - writeObjects(tagLogicalElements, os); writeObjects(objects, os); } diff --git a/status.xml b/status.xml index 2ba48dc80..2a7fe4f12 100644 --- a/status.xml +++ b/status.xml @@ -59,6 +59,9 @@ documents. Example: the fix of marks layering will be such a case when it's done. --> + + Fix to preserve the order of AFP TLEs and NOPs as given in the XSL-FO document. + Added support for lookup of alternative glyphs when additional single-byte encodings are used, ex. replacing "Omegagreek" by "Omega" and vice versa. -- cgit v1.2.3