001: /*
002: * Copyright (c) 2007, intarsys consulting GmbH
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * - Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * - Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * - Neither the name of intarsys nor the names of its contributors may be used
015: * to endorse or promote products derived from this software without specific
016: * prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
022: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
028: * POSSIBILITY OF SUCH DAMAGE.
029: */
030: package de.intarsys.pdf.pd;
031:
032: import java.util.Iterator;
033: import java.util.Set;
034:
035: import de.intarsys.pdf.cds.CDSMatrix;
036: import de.intarsys.pdf.cds.CDSRectangle;
037: import de.intarsys.pdf.cos.COSBasedObject;
038: import de.intarsys.pdf.cos.COSName;
039: import de.intarsys.pdf.cos.COSObject;
040:
041: /**
042: * The annotation representing a field in an AcroForm.
043: */
044: public class PDWidgetAnnotation extends PDAnnotation {
045: /**
046: * The meta class implementation
047: */
048: public static class MetaClass extends PDAnnotation.MetaClass {
049: protected MetaClass(Class instanceClass) {
050: super (instanceClass);
051: }
052:
053: protected COSBasedObject doCreateCOSBasedObject(COSObject object) {
054: return new PDWidgetAnnotation(object);
055: }
056: }
057:
058: /** The meta class instance */
059: public static final MetaClass META = new MetaClass(MetaClass.class
060: .getDeclaringClass());
061:
062: /** Highlighting Mode */
063: public static final COSName DK_H = COSName.constant("H");
064:
065: /** highlightning: N: None */
066: public static final COSName CN_H_N = COSName.constant("N");
067:
068: /** highlightning: I: Invert */
069: public static final COSName CN_H_I = COSName.constant("I");
070:
071: /** highlightning: O: Outline */
072: public static final COSName CN_H_O = COSName.constant("O");
073:
074: /** highlightning: P: Push */
075: public static final COSName CN_H_P = COSName.constant("P");
076:
077: /** highlightning: T: Toggle */
078: public static final COSName CN_H_T = COSName.constant("T");
079:
080: public static final COSName DK_MK = COSName.constant("MK");
081:
082: public static final COSName CN_Subtype_Widget = COSName
083: .constant("Widget");
084:
085: public static final COSName CN_State_Off = COSName.constant("Off");
086:
087: protected PDWidgetAnnotation(COSObject object) {
088: super (object);
089: }
090:
091: public PDAcroFormField getAcroFormField() {
092: return (PDAcroFormField) PDAcroFormField.META
093: .createFromCos(cosGetDict());
094: }
095:
096: public COSName getAltAppearanceState() {
097: Set states = getAppearanceStates();
098: states.add(COSName.create("Off"));
099: COSName oldState = getAppearanceState();
100: for (Iterator it = states.iterator(); it.hasNext();) {
101: COSName state = (COSName) it.next();
102: if (!state.equals(oldState)) {
103: return state;
104: }
105: }
106: return null;
107: }
108:
109: public void setAppearanceCharacteristics(
110: PDAppearanceCharacteristics newAppearanceCharacteristics) {
111: setFieldObject(DK_MK, newAppearanceCharacteristics);
112: }
113:
114: public PDAppearanceCharacteristics getAppearanceCharacteristics() {
115: return (PDAppearanceCharacteristics) PDAppearanceCharacteristics.META
116: .createFromCos(cosGetField(DK_MK));
117: }
118:
119: public void setHighlightingMode(COSName newHighlightingMode) {
120: if ((newHighlightingMode == null)
121: || CN_H_I.equals(newHighlightingMode)) {
122: cosRemoveField(DK_H);
123: } else {
124: cosSetField(DK_H, newHighlightingMode);
125: }
126: }
127:
128: public COSName getHighlightingMode() {
129: COSName mode = cosGetField(DK_H).asName();
130: if (mode != null) {
131: return mode;
132: }
133: return CN_H_I; // default
134: }
135:
136: /*
137: * (non-Javadoc)
138: *
139: * @see de.intarsys.pdf.pd.PDAnnotation#getNormalizedRectangle()
140: */
141: public CDSRectangle getNormalizedRectangle() {
142: CDSRectangle bbox = super .getNormalizedRectangle();
143: CDSMatrix matrix = new CDSMatrix();
144: transform(bbox, matrix);
145: return bbox;
146: }
147:
148: public boolean isOff() {
149: COSName state = getAppearanceState();
150: return (state == null) || state.equals(CN_State_Off);
151: }
152:
153: /*
154: * (non-Javadoc)
155: *
156: * @see de.intarsys.pdf.pd.PDObject#cosGetExpectedSubtype()
157: */
158: protected COSName cosGetExpectedSubtype() {
159: return CN_Subtype_Widget;
160: }
161:
162: public boolean isWidgetAnnotation() {
163: return true;
164: }
165:
166: public boolean canReceiveFocus() {
167: if (super .canReceiveFocus()) {
168: PDAcroFormField field = getAcroFormField();
169: return !field.isReadOnly()
170: && (field.isTypeTx() || field.isTypeBtn() || field
171: .isTypeCh());
172: }
173: return false;
174: }
175:
176: /**
177: * Change a given rectangle and matrix (belonging to a form) according to
178: * the annotations defined rotation.
179: *
180: * @param rect
181: * The rectangle to transform
182: * @param matrix
183: * The matrix to change
184: */
185: public void transform(CDSRectangle rect, CDSMatrix matrix) {
186: int rotation = 0;
187: PDAppearanceCharacteristics ac = getAppearanceCharacteristics();
188: if (ac != null) {
189: rotation = ac.getRotation();
190: }
191: if (rotation == 90) {
192: matrix.setTransformation(CDSMatrix.MATRIX_90);
193: } else if (rotation == 180) {
194: matrix.setTransformation(CDSMatrix.MATRIX_180);
195: } else if (rotation == 270) {
196: matrix.setTransformation(CDSMatrix.MATRIX_270);
197: }
198: float[] vec = new float[] { rect.getWidth(), rect.getHeight() };
199: float[] tVec = matrix.transform(vec);
200: if (rotation == 90) {
201: matrix.setE(rect.getWidth());
202: } else if (rotation == 180) {
203: matrix.setE(rect.getWidth());
204: matrix.setF(rect.getHeight());
205: } else if (rotation == 270) {
206: matrix.setF(rect.getHeight());
207: }
208: rect.setCorners(0, 0, tVec[0], tVec[1]);
209: rect.normalize();
210: }
211:
212: public String getSubtypeLabel() {
213: return "Widget";
214: }
215:
216: public void dispose() {
217: // remove the annotation
218: super .dispose();
219: // dispose the field if there are no more annotations associated with it
220: getAcroFormField().dispose(true);
221: }
222:
223: public COSObject cosSetField(COSName name, COSObject cosObj) {
224: if (!DK_M.equals(name)) {
225: touch();
226: }
227: return super.cosSetField(name, cosObj);
228: }
229: }
|