blob: 91787aca1e9abb1c26c86b53a71f2ace8f5eb156 [file] [log] [blame]
/*
* 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 static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.Set;
import org.apache.commons.io.IOUtils;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.render.intermediate.IFContext;
import org.apache.xmlgraphics.ps.DSCConstants;
import org.apache.xmlgraphics.ps.PSResource;
import org.apache.xmlgraphics.ps.dsc.DSCException;
import org.apache.xmlgraphics.ps.dsc.DSCListener;
import org.apache.xmlgraphics.ps.dsc.DSCParser;
import org.apache.xmlgraphics.ps.dsc.DefaultNestedDocumentHandler;
import org.apache.xmlgraphics.ps.dsc.events.AbstractResourcesDSCComment;
import org.apache.xmlgraphics.ps.dsc.events.DSCAtend;
import org.apache.xmlgraphics.ps.dsc.events.DSCCommentBeginDocument;
import org.apache.xmlgraphics.ps.dsc.events.DSCCommentDocumentNeededResources;
import org.apache.xmlgraphics.ps.dsc.events.DSCCommentDocumentSuppliedResources;
import org.apache.xmlgraphics.ps.dsc.events.DSCCommentEndOfFile;
import org.apache.xmlgraphics.ps.dsc.events.DSCCommentIncludeResource;
import org.apache.xmlgraphics.ps.dsc.events.DSCCommentPage;
import org.apache.xmlgraphics.ps.dsc.events.DSCCommentPages;
import org.junit.Test;
/**
* Tests the PostScript resource optimization (selective de-duplication of
* images that are used multiple times).
*/
public class ResourceOptimizationTestCase extends AbstractPostScriptTestCase {
/**
* Tests resource optimization.
* @throws Exception if an error occurs
*/
@Test
public void testResourceOptimization() throws Exception {
FOUserAgent ua = fopFactory.newFOUserAgent();
PSDocumentHandler handler = new PSDocumentHandler();
handler.setContext(new IFContext(ua));
// This is the important part: we're enabling resource optimization
handler.getPSUtil().setOptimizeResources(true);
ua.setDocumentHandlerOverride(handler);
// Prepare output file
File outputFile = renderFile(ua, "ps-resources.fo",
"-if-l" + handler.getPSUtil().getLanguageLevel());
verifyPostScriptFile(outputFile);
}
private void verifyPostScriptFile(File psFile) throws IOException, DSCException {
InputStream in = new java.io.FileInputStream(psFile);
in = new java.io.BufferedInputStream(in);
try {
DSCParser parser = new DSCParser(in);
//The first form is for arrow_down_small.png (to be reused)
PSResource form1 = new PSResource(PSResource.TYPE_FORM, "FOPForm:1");
PSResource helvetica = new PSResource(PSResource.TYPE_FONT, "Helvetica");
PSResource helveticaBold = new PSResource(PSResource.TYPE_FONT, "Helvetica-Bold");
PSResource res;
DSCCommentPages pages = (DSCCommentPages)gotoDSCComment(parser, DSCConstants.PAGES);
assertEquals(2, pages.getPageCount());
DSCCommentDocumentSuppliedResources supplied
= (DSCCommentDocumentSuppliedResources)gotoDSCComment(parser,
DSCConstants.DOCUMENT_SUPPLIED_RESOURCES);
Set resources = supplied.getResources();
assertEquals(5, resources.size());
assertTrue(resources.contains(form1));
assertTrue("Expected barcode.eps as supplied resource",
resources.contains(new PSResource(PSResource.TYPE_FILE,
"test/resources/images/barcode.eps")));
DSCCommentDocumentNeededResources needed
= (DSCCommentDocumentNeededResources)gotoDSCComment(parser,
DSCConstants.DOCUMENT_NEEDED_RESOURCES);
resources = needed.getResources();
assertEquals(2, resources.size());
assertTrue("Expected Helvetica as needed resource",
resources.contains(new PSResource(PSResource.TYPE_FONT, "Helvetica")));
assertTrue("Expected Helvetica-Bold as needed resource",
resources.contains(new PSResource(PSResource.TYPE_FONT, "Helvetica-Bold")));
//Some document structure checking
assertNotNull(gotoDSCComment(parser, DSCConstants.BEGIN_DEFAULTS));
assertNotNull(gotoDSCComment(parser, DSCConstants.END_DEFAULTS));
assertNotNull(gotoDSCComment(parser, DSCConstants.BEGIN_PROLOG));
assertNotNull(gotoDSCComment(parser, DSCConstants.END_PROLOG));
assertNotNull(gotoDSCComment(parser, DSCConstants.BEGIN_SETUP));
//Check includes for the two referenced base 14 fonts
DSCCommentIncludeResource include;
Collection strings = new java.util.HashSet(
Arrays.asList(new String[] {"Helvetica", "Helvetica-Bold"}));
for (int i = 0; i < 2; i++) {
include = (DSCCommentIncludeResource)gotoDSCComment(
parser, DSCConstants.INCLUDE_RESOURCE);
res = include.getResource();
assertEquals(PSResource.TYPE_FONT, res.getType());
strings.remove(res.getName());
}
assertEquals(0, strings.size());
checkResourceComment(parser, DSCConstants.BEGIN_RESOURCE,
new PSResource(PSResource.TYPE_ENCODING, "WinAnsiEncoding"));
//Here, we encounter form 1 again
checkResourceComment(parser, DSCConstants.BEGIN_RESOURCE, form1);
assertNotNull(gotoDSCComment(parser, DSCConstants.END_SETUP));
//Now the actual pages begin
//---=== Page 1 ===---
DSCCommentPage page = (DSCCommentPage)gotoDSCComment(parser, DSCConstants.PAGE);
assertEquals(1, page.getPagePosition());
assertEquals(DSCAtend.class,
gotoDSCComment(parser, DSCConstants.PAGE_RESOURCES).getClass());
assertNotNull(gotoDSCComment(parser, DSCConstants.BEGIN_PAGE_SETUP));
assertNotNull(gotoDSCComment(parser, DSCConstants.END_PAGE_SETUP));
PSResource form2 = new PSResource(PSResource.TYPE_FORM, "FOPForm:2");
checkResourceComment(parser, DSCConstants.BEGIN_RESOURCE, form2);
assertNotNull(gotoDSCComment(parser, DSCConstants.PAGE_TRAILER));
AbstractResourcesDSCComment pageResources;
pageResources = (AbstractResourcesDSCComment)gotoDSCComment(
parser, DSCConstants.PAGE_RESOURCES);
resources = pageResources.getResources();
assertEquals(5, resources.size());
assertTrue(resources.contains(form1));
assertTrue(resources.contains(form2));
assertTrue(resources.contains(helvetica));
assertTrue(resources.contains(helveticaBold));
//---=== Page 2 ===---
page = (DSCCommentPage)gotoDSCComment(parser, DSCConstants.PAGE);
assertEquals(2, page.getPagePosition());
assertEquals(DSCAtend.class,
gotoDSCComment(parser, DSCConstants.PAGE_RESOURCES).getClass());
assertNotNull(gotoDSCComment(parser, DSCConstants.BEGIN_PAGE_SETUP));
assertNotNull(gotoDSCComment(parser, DSCConstants.END_PAGE_SETUP));
DSCCommentBeginDocument beginDocument;
beginDocument = (DSCCommentBeginDocument)gotoDSCComment(
parser, DSCConstants.BEGIN_DOCUMENT);
assertEquals("test/resources/images/barcode.eps",
beginDocument.getResource().getName());
DSCListener listener = new DefaultNestedDocumentHandler(null);
listener.processEvent(beginDocument, parser);
//And again (the barcode is generated twice)
beginDocument = (DSCCommentBeginDocument)gotoDSCComment(
parser, DSCConstants.BEGIN_DOCUMENT);
assertEquals("test/resources/images/barcode.eps",
beginDocument.getResource().getName());
listener.processEvent(beginDocument, parser);
assertNotNull(gotoDSCComment(parser, DSCConstants.PAGE_TRAILER));
pageResources = (AbstractResourcesDSCComment)gotoDSCComment(
parser, DSCConstants.PAGE_RESOURCES);
resources = pageResources.getResources();
assertEquals(6, resources.size());
assertTrue(resources.contains(form1));
assertFalse(resources.contains(form2));
assertTrue(resources.contains(helvetica));
assertTrue(resources.contains(helveticaBold));
assertTrue(resources.contains(beginDocument.getResource()));
assertNotNull(gotoDSCComment(parser, DSCConstants.TRAILER));
//No headers in between, as they should have been put at the beginning of the file
assertEquals(DSCCommentEndOfFile.class, parser.nextEvent().asDSCComment().getClass());
} finally {
IOUtils.closeQuietly(in);
}
}
}