/*
* Copyright 2006-2017 ICEsoft Technologies Canada Corp.
*
* Licensed 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.icepdf.core.pobjects.annotations;
import org.icepdf.core.pobjects.*;
import org.icepdf.core.util.Library;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.util.HashMap;
import java.util.logging.Logger;
/**
* <h2>Refer to: 8.4.5 Annotation Types</h2>
* <br>
* <table border=1 summary=""> <tr> <td>Key</td> <td>Type</td> <td>Value</td> </tr> <tr>
* <td><b>Subtype</b></td> <td>name</td> <td><i>(Required)</i> The type of
* annotation that this dictionary describes; must be <b>Link</b> for a link
* annotation.</td> </tr> <tr> <td><b>Dest</b></td> <td>array, name, or
* string</td> <td><i>(Optional; not permitted if an <b>A</b> entry is
* present)</i> A destination to be displayed when the annotation is activated
* (see Section 8.2.1, "Destinations"; see also implementation note 90 in
* Appendix H).</td> </tr> <tr> <td><b>H</b></td> <td>name</td>
* <td><i>(Optional; PDF 1.2)</i> The annotation's <i>highlighting mode</i>, the
* visual effect to be used when the mouse button is pressed or held down inside
* its active area: <table border=0 summary=""> <tr> <td>N</td> <td>(None) No
* highlighting.</td> </tr> <tr> <td>I</td> <td>(Invert) Invert the contents of
* the annotation rectangle.</td> </tr> <tr> <td>O</td> <td>(Outline) Invert the
* annotation's border.</td> </tr> <tr> <td>P</td> <td>(Push) Display the
* annotation as if it were being pushed below the surface of the page; see
* implementation note 91 in Appendix H.<br> Acrobat viewer displays the link
* appearance with bevel border, ignoring any down appearance.</td> </tr>
* </table>Default value: I.</td> </tr> <tr> <td><b>QuadPoints</b></td>
* <td>array</td> <td><i>(Optional; PDF 1.6)</i> An array of 8 x n numbers
* specifying the coordinates of n quadrilaterals in default user space that
* comprise the region in which the link should be activated. The coordinates
* for each quadrilateral are given in the order<br> x1 y1 x2 y2 x3 y3 x4 y4<br>
* specifying the four vertices of the quadrilateral in counterclockwise order.
* For orientation purposes, such as when applying an underline border style,
* the bottom of a quadrilateral is the line formed by (x1, y1) and (x2, y2). If
* this entry is not present or the viewer application does not recognize it,
* the region specified by the <b>Rect</b> entry should be used.
* <b>QuadPoints</b> should be ignored if any coordinate in the array lies
* outside the region specified by <b>Rect</b>.</td> </tr> </table>
*
* @author Mark Collette
* @since 2.5
*/
public class LinkAnnotation extends Annotation {
private static final Logger logger =
Logger.getLogger(LinkAnnotation.class.toString());
/**
* Key used to indicate highlight mode.
*/
public static final Name DESTINATION_KEY = new Name("Dest");
/**
* Key used to indcate highlight mode.
*/
public static final Name HIGHLIGHT_MODE_KEY = new Name("H");
/**
* Indicates that the annotation has no highlight effect.
*/
public static final Name HIGHLIGHT_NONE = new Name("N");
/**
* Indicates that the annotation rectangle colours should be inverted for
* its highlight effect.
*/
public static final Name HIGHLIGHT_INVERT = new Name("I");
/**
* Indicates that the annotation rectangle border should be inverted for its
* highlight effect.
*/
public static final Name HIGHLIGHT_OUTLINE = new Name("O");
/**
* Indicates that the annotation rectangle border should be pushed below the
* surface of th page.
*/
public static final Name HIGHLIGHT_PUSH = new Name("P");
/**
* Creates a new instance of a LinkAnnotation.
*
* @param l document library.
* @param h dictionary entries.
*/
public LinkAnnotation(Library l, HashMap h) {
super(l, h);
}
/**
* Gets an instance of a LinkAnnotation that has valid Object Reference.
*
* @param library document library
* @param rect bounding rectangle in user space
* @return new LinkAnnotation Instance.
*/
public static LinkAnnotation getInstance(Library library,
Rectangle rect) {
// state manager
StateManager stateManager = library.getStateManager();
// create a new entries to hold the annotation properties
HashMap<Name, Object> entries = new HashMap<Name, Object>();
// set default link annotation values.
entries.put(Dictionary.TYPE_KEY, Annotation.TYPE_VALUE);
entries.put(Dictionary.SUBTYPE_KEY, Annotation.SUBTYPE_LINK);
// coordinates
if (rect != null) {
entries.put(Annotation.RECTANGLE_KEY,
PRectangle.getPRectangleVector(rect));
} else {
entries.put(Annotation.RECTANGLE_KEY, new Rectangle(10, 10, 50, 100));
}
// write out the default highlight state.
entries.put(HIGHLIGHT_MODE_KEY, HIGHLIGHT_INVERT);
// create the new instance
LinkAnnotation linkAnnotation = null;
try {
linkAnnotation = new LinkAnnotation(library, entries);
linkAnnotation.init();
linkAnnotation.setPObjectReference(stateManager.getNewReferencNumber());
linkAnnotation.setNew(true);
// set default flags.
linkAnnotation.setFlag(Annotation.FLAG_READ_ONLY, false);
linkAnnotation.setFlag(Annotation.FLAG_NO_ROTATE, false);
linkAnnotation.setFlag(Annotation.FLAG_NO_ZOOM, false);
linkAnnotation.setFlag(Annotation.FLAG_PRINT, true);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
logger.fine("Link annotation instance creation was interrupted");
}
return linkAnnotation;
}
public void init() throws InterruptedException {
super.init();
// try and generate an appearance stream.
resetNullAppearanceStream();
}
/**
* <p>Gets the link annotations highlight mode (visual effect)taht should
* be displayed when the mouse button is pressed or held down inside it's
* active area.</p>
*
* @return one of the predefined highlight effects, HIGHLIGHT_NONE,
* HIGHLIGHT_OUTLINE or HIGHLIGHT_PUSH.
*/
public Name getHighlightMode() {
Object possibleName = getObject(HIGHLIGHT_MODE_KEY);
if (possibleName instanceof Name) {
Name name = (Name) possibleName;
if (HIGHLIGHT_NONE.equals(name)) {
return HIGHLIGHT_NONE;
} else if (HIGHLIGHT_OUTLINE.equals(name)) {
return HIGHLIGHT_OUTLINE;
} else if (HIGHLIGHT_PUSH.equals(name)) {
return HIGHLIGHT_PUSH;
}
}
return HIGHLIGHT_INVERT;
}
/**
* A destination to be displayed when the annotation is ativated. Only
* permitted if an A entry is not present.
*
* @return annotation target destination, null if not present in
* annotation.
*/
public Destination getDestination() {
Object obj = getObject(DESTINATION_KEY);
if (obj != null) {
return new Destination(library, obj);
}
return null;
}
@Override
public void resetAppearanceStream(double dx, double dy, AffineTransform pageTransform) {
}
}