/*
* 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.
*/
package org.apache.pdfbox.pdmodel.graphics.optionalcontent;
import java.awt.Color;
import java.io.File;
import java.util.Arrays;
import java.util.Collection;
import java.util.Set;
import junit.framework.TestCase;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.graphics.optionalcontent.PDOptionalContentProperties.BaseState;
/**
* Tests optional content group functionality (also called layers).
*/
public class TestOptionalContentGroups extends TestCase
{
private File testResultsDir = new File("target/test-output");
@Override
protected void setUp() throws Exception
{
super.setUp();
testResultsDir.mkdirs();
}
/**
* Tests OCG generation.
* @throws Exception if an error occurs
*/
public void testOCGGeneration() throws Exception
{
PDDocument doc = new PDDocument();
try
{
//OCGs have been introduced with PDF 1.5
doc.getDocument().setHeaderString("%PDF-1.5");
PDDocumentCatalog catalog = doc.getDocumentCatalog();
catalog.setVersion("1.5");
//Create new page
PDPage page = new PDPage();
doc.addPage(page);
PDResources resources = page.getResources();
if( resources == null )
{
resources = new PDResources();
page.setResources( resources );
}
//Prepare OCG functionality
PDOptionalContentProperties ocprops = new PDOptionalContentProperties();
catalog.setOCProperties(ocprops);
//ocprops.setBaseState(BaseState.ON); //ON=default
//Create OCG for background
PDOptionalContentGroup background = new PDOptionalContentGroup("background");
ocprops.addGroup(background);
assertTrue(ocprops.isGroupEnabled("background"));
//Create OCG for enabled
PDOptionalContentGroup enabled = new PDOptionalContentGroup("enabled");
ocprops.addGroup(enabled);
assertFalse(ocprops.setGroupEnabled("enabled", true));
assertTrue(ocprops.isGroupEnabled("enabled"));
//Create OCG for disabled
PDOptionalContentGroup disabled = new PDOptionalContentGroup("disabled");
ocprops.addGroup(disabled);
assertFalse(ocprops.setGroupEnabled("disabled", true));
assertTrue(ocprops.isGroupEnabled("disabled"));
assertTrue(ocprops.setGroupEnabled("disabled", false));
assertFalse(ocprops.isGroupEnabled("disabled"));
//Add property lists to page resources
COSName mc0 = COSName.getPDFName("MC0");
COSName mc1 = COSName.getPDFName("MC1");
COSName mc2 = COSName.getPDFName("MC2");
resources.put(mc0, background);
resources.put(mc1, enabled);
resources.put(mc2, disabled);
//Setup page content stream and paint background/title
PDPageContentStream contentStream = new PDPageContentStream(doc, page, false, false);
PDFont font = PDType1Font.HELVETICA_BOLD;
contentStream.beginMarkedContentSequence(COSName.OC, mc0);
contentStream.beginText();
contentStream.setFont(font, 14);
contentStream.moveTextPositionByAmount(80, 700);
contentStream.drawString("PDF 1.5: Optional Content Groups");
contentStream.endText();
font = PDType1Font.HELVETICA;
contentStream.beginText();
contentStream.setFont(font, 12);
contentStream.moveTextPositionByAmount(80, 680);
contentStream.drawString("You should see a green textline, but no red text line.");
contentStream.endText();
contentStream.endMarkedContentSequence();
//Paint enabled layer
contentStream.beginMarkedContentSequence(COSName.OC, mc1);
contentStream.setNonStrokingColor(Color.GREEN);
contentStream.beginText();
contentStream.setFont(font, 12);
contentStream.moveTextPositionByAmount(80, 600);
contentStream.drawString(
"This is from an enabled layer. If you see this, that's good.");
contentStream.endText();
contentStream.endMarkedContentSequence();
//Paint disabled layer
contentStream.beginMarkedContentSequence(COSName.OC, mc2);
contentStream.setNonStrokingColor(Color.RED);
contentStream.beginText();
contentStream.setFont(font, 12);
contentStream.moveTextPositionByAmount(80, 500);
contentStream.drawString(
"This is from a disabled layer. If you see this, that's NOT good!");
contentStream.endText();
contentStream.endMarkedContentSequence();
contentStream.close();
File targetFile = new File(testResultsDir, "ocg-generation.pdf");
doc.save(targetFile.getAbsolutePath());
}
finally
{
doc.close();
}
}
/**
* Tests OCG functions on a loaded PDF.
* @throws Exception if an error occurs
*/
public void testOCGConsumption() throws Exception
{
File pdfFile = new File(testResultsDir, "ocg-generation.pdf");
if (!pdfFile.exists())
{
testOCGGeneration();
}
PDDocument doc = PDDocument.load(pdfFile);
try
{
assertEquals("%PDF-1.5", doc.getDocument().getHeaderString());
PDDocumentCatalog catalog = doc.getDocumentCatalog();
assertEquals("1.5", catalog.getVersion());
PDPage page = doc.getPage(0);
PDOptionalContentGroup ocg = (PDOptionalContentGroup)page.getResources()
.getProperties(COSName.getPDFName("MC0"));
assertNotNull(ocg);
assertEquals("background", ocg.getName());
assertNull(page.getResources().getProperties(COSName.getPDFName("inexistent")));
PDOptionalContentProperties ocgs = catalog.getOCProperties();
assertEquals(BaseState.ON, ocgs.getBaseState());
Set<String> names = new java.util.HashSet<String>(Arrays.asList(ocgs.getGroupNames()));
assertEquals(3, names.size());
assertTrue(names.contains("background"));
assertTrue(ocgs.isGroupEnabled("background"));
assertTrue(ocgs.isGroupEnabled("enabled"));
assertFalse(ocgs.isGroupEnabled("disabled"));
ocgs.setGroupEnabled("background", false);
assertFalse(ocgs.isGroupEnabled("background"));
PDOptionalContentGroup background = ocgs.getGroup("background");
assertEquals(ocg.getName(), background.getName());
assertNull(ocgs.getGroup("inexistent"));
Collection<PDOptionalContentGroup> coll = ocgs.getOptionalContentGroups();
coll.contains(background);
}
finally
{
doc.close();
}
}
}