/*
* 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.interactive.annotation.handlers;
import java.io.IOException;
import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationLink;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceContentStream;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDBorderStyleDictionary;
/**
* Handler to generate the link annotations appearance.
*
*/
public class PDLinkAppearanceHandler extends PDAbstractAppearanceHandler
{
public PDLinkAppearanceHandler(PDAnnotation annotation)
{
super(annotation);
}
@Override
public void generateAppearanceStreams()
{
generateNormalAppearance();
generateRolloverAppearance();
generateDownAppearance();
}
@Override
public void generateNormalAppearance()
{
// Adobe doesn't generate an appearance for a link annotation
float lineWidth = getLineWidth();
try
{
PDAppearanceContentStream contentStream = getNormalAppearanceAsContentStream();
contentStream.setStrokingColorOnDemand(getColor());
boolean hasBackground = contentStream.setNonStrokingColorOnDemand(getAnnotation().getColor());
// TODO: handle opacity settings
contentStream.setBorderLine(lineWidth, ((PDAnnotationLink) getAnnotation()).getBorderStyle());
// the differences rectangle
// TODO: this only works for border effect solid. Cloudy needs a different approach.
setRectDifference(lineWidth);
// Acrobat applies a padding to each side of the bbox so the line is completely within
// the bbox.
PDRectangle borderEdge = getPaddedRectangle(getRectangle(),lineWidth/2);
contentStream.addRect(borderEdge.getLowerLeftX() , borderEdge.getLowerLeftY(),
borderEdge.getWidth(), borderEdge.getHeight());
contentStream.drawShape(lineWidth, hasBackground);
contentStream.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
@Override
public void generateRolloverAppearance()
{
// No rollover appearance generated for a link annotation
}
@Override
public void generateDownAppearance()
{
// No down appearance generated for a link annotation
}
/**
* Get the line with of the border.
*
* Get the width of the line used to draw a border around the annotation.
* This may either be specified by the annotation dictionaries Border
* setting or by the W entry in the BS border style dictionary. If both are
* missing the default width is 1.
*
* @return the line width
*/
// TODO: according to the PDF spec the use of the BS entry is annotation
// specific
// so we will leave that to be implemented by individual handlers.
// If at the end all annotations support the BS entry this can be handled
// here and removed from the individual handlers.
float getLineWidth()
{
PDAnnotationLink annotation = (PDAnnotationLink) getAnnotation();
PDBorderStyleDictionary bs = annotation.getBorderStyle();
if (bs != null)
{
return bs.getWidth();
} else
{
COSArray borderCharacteristics = annotation.getBorder();
if (borderCharacteristics != null && borderCharacteristics.size() >= 3)
{
return borderCharacteristics.getInt(3);
}
}
return 1;
}
}