/*
 * 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: ExternalDocumentLayoutManager.java 1531769 2013-10-13 23:31:46Z lbernardo $ */

package org.apache.fop.layoutmgr;

import java.awt.Dimension;
import java.awt.Rectangle;
import java.io.FileNotFoundException;
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.ResourceEventProducer;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.area.AreaTreeHandler;
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;
import org.apache.fop.area.inline.InlineViewport;
import org.apache.fop.datatypes.FODimension;
import org.apache.fop.datatypes.URISpecification;
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.extensions.ExternalDocument;
import org.apache.fop.layoutmgr.inline.ImageLayout;
import org.apache.fop.traits.WritingMode;

LayoutManager for an external-document extension element. This class is instantiated by area.AreaTreeHandler for each fo:external-document found in the input document.
/** * LayoutManager for an external-document extension element. This class is instantiated by * area.AreaTreeHandler for each fo:external-document found in the * input document. */
public class ExternalDocumentLayoutManager extends AbstractPageSequenceLayoutManager { private static Log log = LogFactory.getLog(ExternalDocumentLayoutManager.class); private ImageLayout imageLayout;
Constructor
Params:
  • ath – the area tree handler object
  • document – fox:external-document to process
/** * Constructor * * @param ath the area tree handler object * @param document fox:external-document to process */
public ExternalDocumentLayoutManager(AreaTreeHandler ath, ExternalDocument document) { super(ath, document); }
Returns:the ExternalDocument being managed by this layout manager
/** * @return the ExternalDocument being managed by this layout manager */
protected ExternalDocument getExternalDocument() { return (ExternalDocument)pageSeq; }
{@inheritDoc}
/** {@inheritDoc} */
public PageSequenceLayoutManager getPSLM() { throw new IllegalStateException("getPSLM() is illegal for " + getClass().getName()); }
{@inheritDoc}
/** {@inheritDoc} */
public void activateLayout() { initialize(); FOUserAgent userAgent = pageSeq.getUserAgent(); ImageManager imageManager = userAgent.getImageManager(); String uri = URISpecification.getURL(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); PageSequence pageSequence = new PageSequence(null); transferExtensions(pageSequence); areaTreeHandler.getAreaTreeModel().startPageSequence(pageSequence); 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(URISpecification.escapeURI(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) { getResourceEventProducer().uriError(this, uri, e, getExternalDocument().getLocator()); } } } catch (FileNotFoundException fnfe) { getResourceEventProducer().imageNotFound(this, uri, fnfe, getExternalDocument().getLocator()); } catch (IOException ioe) { getResourceEventProducer().imageIOError(this, uri, ioe, getExternalDocument().getLocator()); } catch (ImageException ie) { getResourceEventProducer().imageError(this, uri, ie, getExternalDocument().getLocator()); } } private ResourceEventProducer getResourceEventProducer() { return ResourceEventProducer.Provider.get( getExternalDocument().getUserAgent().getEventBroadcaster()); } private void makePageForImage(ImageInfo info, ImageLayout layout) { this.imageLayout = layout; curPage = makeNewPage(false); fillPage(info.getOriginalURI()); finishPage(); } private void fillPage(String uri) { Dimension imageSize = this.imageLayout.getViewportSize(); Block blockArea = new Block(); blockArea.setIPD(imageSize.width); LineArea lineArea = new LineArea(); Image imageArea = new Image(uri); TraitSetter.setProducerID(imageArea, fobj.getId()); transferForeignAttributes(imageArea); InlineViewport vp = new InlineViewport(imageArea, fobj.getBidiLevel()); TraitSetter.setProducerID(vp, fobj.getId()); vp.setIPD(imageSize.width); vp.setBPD(imageSize.height); vp.setContentPosition(imageLayout.getPlacement()); vp.setBlockProgressionOffset(0); //Link them all together... lineArea.addInlineArea(vp); lineArea.updateExtentsFromChildren(); blockArea.addLineArea(lineArea); curPage.getPageViewport().getCurrentFlow().addBlock(blockArea); curPage.getPageViewport().getCurrentSpan().notifyFlowsFinished(); }
{@inheritDoc}
/** {@inheritDoc} */
public void finishPageSequence() { if (pageSeq.hasId()) { idTracker.signalIDProcessed(pageSeq.getId()); } pageSeq.getRoot().notifyPageSequenceFinished(currentPageNum, (currentPageNum - startPageNum) + 1); areaTreeHandler.notifyPageSequenceFinished(pageSeq, (currentPageNum - startPageNum) + 1); if (log.isDebugEnabled()) { log.debug("Ending layout"); } }
{@inheritDoc}
/** {@inheritDoc} */
protected Page createPage(int pageNumber, boolean isBlank) { String pageNumberString = pageSeq.makeFormattedPageNumber(pageNumber); Dimension imageSize = this.imageLayout.getViewportSize(); // Set up the CTM on the page reference area based on writing-mode // and reference-orientation Rectangle referenceRect; if (pageSeq.getReferenceOrientation() % 180 == 0) { referenceRect = new Rectangle(0, 0, imageSize.width, imageSize.height); } else { referenceRect = new Rectangle(0, 0, imageSize.height, imageSize.width); } FODimension reldims = new FODimension(0, 0); // [TBD] BIDI ALERT CTM pageCTM = CTM.getCTMandRelDims(pageSeq.getReferenceOrientation(), WritingMode.LR_TB, referenceRect, reldims); Page page = new Page(referenceRect, pageNumber, pageNumberString, isBlank); PageViewport pv = page.getPageViewport(); org.apache.fop.area.Page pageArea = new org.apache.fop.area.Page(); pv.setPage(pageArea); RegionViewport rv = new RegionViewport(referenceRect); if (pageSeq.getReferenceOrientation() % 180 == 0) { rv.setIPD(referenceRect.width); rv.setBPD(referenceRect.height); } else { rv.setIPD(referenceRect.height); rv.setBPD(referenceRect.width); } rv.setClip(true); BodyRegion body = new BodyRegion(Constants.FO_REGION_BODY, "fop-image-region", rv, 1, 0); body.setIPD(imageSize.width); body.setBPD(imageSize.height); body.setCTM(pageCTM); rv.setRegionReference(body); pageArea.setRegionViewport( Constants.FO_REGION_BODY, rv); //Set unique key obtained from the AreaTreeHandler pv.setKey(areaTreeHandler.generatePageViewportKey()); //Also creates first normal flow region pv.createSpan(false); return page; } }