Added multi-page support for fox:external-document. Changed multi-page.tiff: page 4 is now bigger than all other pages. (to make sure that individually sized pages are handled properly) git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_ImagePackageRedesign@607092 13f79535-47bb-0310-9956-ffa450edef68Temp_ImagePackageRedesign
@@ -21,10 +21,18 @@ package org.apache.fop.layoutmgr; | |||
import java.awt.Dimension; | |||
import java.awt.Rectangle; | |||
import java.io.IOException; | |||
import java.net.URI; | |||
import java.net.URISyntaxException; | |||
import org.apache.commons.logging.Log; | |||
import org.apache.commons.logging.LogFactory; | |||
import org.apache.xmlgraphics.image.loader.ImageException; | |||
import org.apache.xmlgraphics.image.loader.ImageInfo; | |||
import org.apache.xmlgraphics.image.loader.ImageManager; | |||
import org.apache.xmlgraphics.image.loader.util.ImageUtil; | |||
import org.apache.fop.apps.FOUserAgent; | |||
import org.apache.fop.area.AreaTreeHandler; | |||
import org.apache.fop.area.Block; | |||
@@ -38,8 +46,6 @@ import org.apache.fop.area.inline.Viewport; | |||
import org.apache.fop.datatypes.FODimension; | |||
import org.apache.fop.fo.Constants; | |||
import org.apache.fop.fo.extensions.ExternalDocument; | |||
import org.apache.fop.image.FopImage; | |||
import org.apache.fop.image.ImageFactory; | |||
import org.apache.fop.layoutmgr.inline.ImageLayout; | |||
/** | |||
@@ -51,14 +57,13 @@ public class ExternalDocumentLayoutManager extends AbstractPageSequenceLayoutMan | |||
private static Log log = LogFactory.getLog(ExternalDocumentLayoutManager.class); | |||
private FopImage image; | |||
private ImageLayout imageLayout; | |||
/** | |||
* Constructor | |||
* | |||
* @param ath the area tree handler object | |||
* @param pseq fo:page-sequence to process | |||
* @param document fox:external-document to process | |||
*/ | |||
public ExternalDocumentLayoutManager(AreaTreeHandler ath, ExternalDocument document) { | |||
super(ath, document); | |||
@@ -80,38 +85,78 @@ public class ExternalDocumentLayoutManager extends AbstractPageSequenceLayoutMan | |||
public void activateLayout() { | |||
initialize(); | |||
String uri = getExternalDocument().getSrc(); | |||
FOUserAgent userAgent = pageSeq.getUserAgent(); | |||
ImageFactory fact = userAgent.getFactory().getImageFactory(); | |||
this.image = fact.getImage(uri, userAgent); | |||
if (this.image == null) { | |||
log.error("Image not available: " + uri); | |||
return; | |||
} else { | |||
// load dimensions | |||
if (!this.image.load(FopImage.DIMENSIONS)) { | |||
log.error("Cannot read image dimensions: " + uri); | |||
return; | |||
} | |||
} | |||
Dimension intrinsicSize = new Dimension( | |||
image.getIntrinsicWidth(), | |||
image.getIntrinsicHeight()); | |||
this.imageLayout = new ImageLayout(getExternalDocument(), this, intrinsicSize); | |||
ImageManager imageManager = userAgent.getFactory().getImageManager(); | |||
areaTreeHandler.getAreaTreeModel().startPageSequence(null); | |||
if (log.isDebugEnabled()) { | |||
log.debug("Starting layout"); | |||
String uri = getExternalDocument().getSrc(); | |||
Integer firstPageIndex = ImageUtil.getPageIndexFromURI(uri); | |||
boolean hasPageIndex = (firstPageIndex != null); | |||
try { | |||
ImageInfo info = imageManager.getImageInfo(uri, userAgent.getImageSessionContext()); | |||
Object moreImages = info.getCustomObjects().get(ImageInfo.HAS_MORE_IMAGES); | |||
boolean hasMoreImages = moreImages != null && !Boolean.FALSE.equals(moreImages); | |||
Dimension intrinsicSize = info.getSize().getDimensionMpt(); | |||
ImageLayout layout = new ImageLayout(getExternalDocument(), this, intrinsicSize); | |||
areaTreeHandler.getAreaTreeModel().startPageSequence(null); | |||
if (log.isDebugEnabled()) { | |||
log.debug("Starting layout"); | |||
} | |||
makePageForImage(info, layout); | |||
if (!hasPageIndex && hasMoreImages) { | |||
if (log.isTraceEnabled()) { | |||
log.trace("Starting multi-page processing..."); | |||
} | |||
URI originalURI; | |||
try { | |||
originalURI = new URI(uri); | |||
int pageIndex = 1; | |||
while (hasMoreImages) { | |||
URI tempURI = new URI(originalURI.getScheme(), | |||
originalURI.getSchemeSpecificPart(), | |||
"page=" + Integer.toString(pageIndex + 1)); | |||
if (log.isTraceEnabled()) { | |||
log.trace("Subimage: " + tempURI.toASCIIString()); | |||
} | |||
ImageInfo subinfo = imageManager.getImageInfo( | |||
tempURI.toASCIIString(), userAgent.getImageSessionContext()); | |||
moreImages = subinfo.getCustomObjects().get(ImageInfo.HAS_MORE_IMAGES); | |||
hasMoreImages = moreImages != null && !Boolean.FALSE.equals(moreImages); | |||
intrinsicSize = subinfo.getSize().getDimensionMpt(); | |||
layout = new ImageLayout( | |||
getExternalDocument(), this, intrinsicSize); | |||
makePageForImage(subinfo, layout); | |||
pageIndex++; | |||
} | |||
} catch (URISyntaxException e) { | |||
log.error("Error parsing or constructing URIs based on URI: " + uri); | |||
return; | |||
} | |||
} | |||
} catch (IOException ioe) { | |||
log.error("Image not available: " + uri, ioe); | |||
} catch (ImageException ie) { | |||
log.error("Error while inspecting image: " + uri + " (" + ie.getMessage() + ")"); | |||
} | |||
} | |||
private void makePageForImage(ImageInfo info, ImageLayout layout) { | |||
this.imageLayout = layout; | |||
curPage = makeNewPage(false, false); | |||
fillPage(); //TODO Implement multi-page documents (using new image package) | |||
fillPage(info.getOriginalURI()); | |||
finishPage(); | |||
} | |||
private void fillPage() { | |||
private void fillPage(String uri) { | |||
Dimension imageSize = this.imageLayout.getViewportSize(); | |||
@@ -119,7 +164,7 @@ public class ExternalDocumentLayoutManager extends AbstractPageSequenceLayoutMan | |||
blockArea.setIPD(imageSize.width); | |||
LineArea lineArea = new LineArea(); | |||
Image imageArea = new Image(getExternalDocument().getSrc()); | |||
Image imageArea = new Image(uri); | |||
TraitSetter.setProducerID(imageArea, fobj.getId()); | |||
transferForeignAttributes(imageArea); | |||
@@ -38,15 +38,15 @@ | |||
<eval expected="1" xpath="count(//pageViewport)"/> | |||
<eval expected="1" xpath="/areaTree/pageSequence/pageViewport/@formatted-nr"/> | |||
<eval expected="1" xpath="/areaTree/pageSequence/pageViewport/@nr"/> | |||
<eval expected="0 0 191975 191975" xpath="/areaTree/pageSequence/pageViewport/@bounds"/> | |||
<eval expected="0 0 191976 191976" xpath="/areaTree/pageSequence/pageViewport/@bounds"/> | |||
<eval expected="191975" xpath="//regionViewport/@ipd"/> | |||
<eval expected="191975" xpath="//regionViewport/@bpd"/> | |||
<eval expected="191975" xpath="//lineArea/@ipd"/> | |||
<eval expected="191975" xpath="//lineArea/@bpd"/> | |||
<eval expected="191975" xpath="//viewport/@ipd"/> | |||
<eval expected="191975" xpath="//viewport/@bpd"/> | |||
<eval expected="0 0 191975 191975" xpath="//viewport/@pos"/> | |||
<eval expected="191976" xpath="//regionViewport/@ipd"/> | |||
<eval expected="191976" xpath="//regionViewport/@bpd"/> | |||
<eval expected="191976" xpath="//lineArea/@ipd"/> | |||
<eval expected="191976" xpath="//lineArea/@bpd"/> | |||
<eval expected="191976" xpath="//viewport/@ipd"/> | |||
<eval expected="191976" xpath="//viewport/@bpd"/> | |||
<eval expected="0 0 191976 191976" xpath="//viewport/@pos"/> | |||
<eval expected="img" xpath="//viewport/@prod-id"/> | |||
<eval expected="img" xpath="//image/@prod-id"/> | |||
</checks> |
@@ -63,19 +63,19 @@ | |||
<eval expected="0 0 360000 360000" xpath="//pageViewport[@nr = '2']/@bounds"/> | |||
<eval expected="0 0 360000 360000" xpath="//pageViewport[@nr = '3']/@bounds"/> | |||
<eval expected="0 0 360000 360000" xpath="//pageViewport[@nr = '5']/@bounds"/> | |||
<eval expected="0 0 843913 597171" xpath="//pageViewport[@nr = '6']/@bounds"/> | |||
<eval expected="0 0 843913 597172" xpath="//pageViewport[@nr = '6']/@bounds"/> | |||
<eval expected="84012 84012 191975 191975" xpath="//viewport[@prod-id = 'img1']/@pos"/> | |||
<eval expected="84012 84012 191976 191976" xpath="//viewport[@prod-id = 'img1']/@pos"/> | |||
<eval expected="0 0 360000 360000" xpath="//viewport[@prod-id = 'img2']/@pos"/> | |||
<eval expected="0 0 191975 191975" xpath="//viewport[@prod-id = 'img3']/@pos"/> | |||
<eval expected="0 0 597171 843913" xpath="//viewport[@prod-id = 'img4']/@pos"/> | |||
<eval expected="0 0 191976 191976" xpath="//viewport[@prod-id = 'img3']/@pos"/> | |||
<eval expected="0 0 597172 843913" xpath="//viewport[@prod-id = 'img4']/@pos"/> | |||
<eval expected="0 0 843913 597171" xpath="//pageViewport[@nr = '6']/page/regionViewport/@rect"/> | |||
<eval expected="0 0 843913 597172" xpath="//pageViewport[@nr = '6']/page/regionViewport/@rect"/> | |||
<eval expected="843913" xpath="//pageViewport[@nr = '6']/page/regionViewport/@ipd"/> | |||
<eval expected="597171" xpath="//pageViewport[@nr = '6']/page/regionViewport/@bpd"/> | |||
<eval expected="597171" xpath="//pageViewport[@nr = '6']/page/regionViewport/regionBody/@ipd"/> | |||
<eval expected="597172" xpath="//pageViewport[@nr = '6']/page/regionViewport/@bpd"/> | |||
<eval expected="597172" xpath="//pageViewport[@nr = '6']/page/regionViewport/regionBody/@ipd"/> | |||
<eval expected="843913" xpath="//pageViewport[@nr = '6']/page/regionViewport/regionBody/@bpd"/> | |||
<eval expected="[0.0 -1.0 1.0 0.0 0.0 597171.0]" xpath="//pageViewport[@nr = '6']/page/regionViewport/regionBody/@ctm"/> | |||
<eval expected="[0.0 -1.0 1.0 0.0 0.0 597172.0]" xpath="//pageViewport[@nr = '6']/page/regionViewport/regionBody/@ctm"/> | |||
</checks> | |||
</testcase> |
@@ -0,0 +1,53 @@ | |||
<?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 fox:external-document with multi-page images. | |||
</p> | |||
</info> | |||
<fo> | |||
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format" | |||
xmlns:fox="http://xmlgraphics.apache.org/fop/extensions"> | |||
<!--fo:layout-master-set> | |||
<fo:simple-page-master master-name="normal" page-width="5in" page-height="5in"> | |||
<fo:region-body reference-orientation="90"/> | |||
</fo:simple-page-master> | |||
</fo:layout-master-set--> | |||
<fox:external-document id="img2" src="../../resources/images/multi-page.tiff"/> | |||
</fo:root> | |||
</fo> | |||
<checks> | |||
<eval expected="1" xpath="count(/areaTree/pageSequence)"/> | |||
<eval expected="5" xpath="count(//pageViewport)"/> | |||
<eval expected="1" xpath="//pageViewport[@nr = '1']/@formatted-nr"/> | |||
<eval expected="2" xpath="//pageViewport[@nr = '2']/@formatted-nr"/> | |||
<eval expected="3" xpath="//pageViewport[@nr = '3']/@formatted-nr"/> | |||
<eval expected="4" xpath="//pageViewport[@nr = '4']/@formatted-nr"/> | |||
<eval expected="5" xpath="//pageViewport[@nr = '5']/@formatted-nr"/> | |||
<eval expected="0 0 142000 142000" xpath="//pageViewport[@nr = '1']/@bounds"/> | |||
<eval expected="0 0 142000 142000" xpath="//pageViewport[@nr = '2']/@bounds"/> | |||
<eval expected="0 0 142000 142000" xpath="//pageViewport[@nr = '3']/@bounds"/> | |||
<eval expected="0 0 227000 227000" xpath="//pageViewport[@nr = '4']/@bounds"/> | |||
<eval expected="0 0 142000 142000" xpath="//pageViewport[@nr = '5']/@bounds"/> | |||
</checks> | |||
</testcase> |