1 /*
2  * $Id$
3  *
4  * Copyright 2002 Bruno Lowagie
5  *
6  * The contents of this file are subject to the Mozilla Public License Version 1.1
7  * (the "License"); you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at http://www.mozilla.org/MPL/
9  *
10  * Software distributed under the License is distributed on an "AS IS" basis,
11  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12  * for the specific language governing rights and limitations under the License.
13  *
14  * The Original Code is 'iText, a free JAVA-PDF library'.
15  *
16  * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
17  * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
18  * All Rights Reserved.
19  * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
20  * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
21  *
22  * Contributor(s): all the names of the contributors are added in the source code
23  * where applicable.
24  *
25  * Alternatively, the contents of this file may be used under the terms of the
26  * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
27  * provisions of LGPL are applicable instead of those above.  If you wish to
28  * allow use of your version of this file only under the terms of the LGPL
29  * License and not to allow others to use your version of this file under
30  * the MPL, indicate your decision by deleting the provisions above and
31  * replace them with the notice and other provisions required by the LGPL.
32  * If you do not delete the provisions above, a recipient may use your version
33  * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
34  *
35  * This library is free software; you can redistribute it and/or modify it
36  * under the terms of the MPL as stated above or under the terms of the GNU
37  * Library General Public License as published by the Free Software Foundation;
38  * either version 2 of the License, or any later version.
39  *
40  * This library is distributed in the hope that it will be useful, but WITHOUT
41  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
42  * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
43  * details.
44  *
45  * If you didn't download this code from the following link, you should check if
46  * you aren't using an obsolete version:
47  * http://www.lowagie.com/iText/
48  */
49 
50 package com.lowagie.text.pdf;
51 
52 import java.util.HashMap;
53 import java.util.Iterator;
54 
55 import com.lowagie.text.ExceptionConverter;
56 import com.lowagie.text.Rectangle;
57 
58 /**
59  * Each PDF document can contain maximum 1 AcroForm.
60  */
61 
62 public class PdfAcroForm extends PdfDictionary {
63 
64     private PdfWriter writer;
65 
66 
67     /** This is a map containing FieldTemplates. */
68     private HashMap fieldTemplates = new HashMap();
69 
70     /** This is an array containing DocumentFields. */
71     private PdfArray documentFields = new PdfArray();
72 
73     /** This is an array containing the calculationorder of the fields. */
74     private PdfArray calculationOrder = new PdfArray();
75 
76     /** Contains the signature flags. */
77     private int sigFlags = 0;
78 
79     /** Creates new PdfAcroForm
80      * @param writer
81      */
PdfAcroForm(PdfWriter writer)82     public PdfAcroForm(PdfWriter writer) {
83         super();
84         this.writer = writer;
85     }
86 
setNeedAppearances(boolean value)87     public void setNeedAppearances(boolean value) {
88     	put(PdfName.NEEDAPPEARANCES, new PdfBoolean(value));
89     }
90 
91     /**
92      * Adds fieldTemplates.
93      * @param ft
94      */
95 
addFieldTemplates(HashMap ft)96     public void addFieldTemplates(HashMap ft) {
97         fieldTemplates.putAll(ft);
98     }
99 
100     /**
101      * Adds documentFields.
102      * @param ref
103      */
104 
addDocumentField(PdfIndirectReference ref)105     public void addDocumentField(PdfIndirectReference ref) {
106         documentFields.add(ref);
107     }
108 
109     /**
110      * Checks if the Acroform is valid
111      * @return true if the Acroform is valid
112      */
113 
isValid()114     public boolean isValid() {
115         if (documentFields.size() == 0) return false;
116         put(PdfName.FIELDS, documentFields);
117         if (sigFlags != 0)
118             put(PdfName.SIGFLAGS, new PdfNumber(sigFlags));
119         if (calculationOrder.size() > 0)
120             put(PdfName.CO, calculationOrder);
121         if (fieldTemplates.isEmpty()) return true;
122         PdfDictionary dic = new PdfDictionary();
123         for (Iterator it = fieldTemplates.keySet().iterator(); it.hasNext();) {
124             PdfTemplate template = (PdfTemplate)it.next();
125             PdfFormField.mergeResources(dic, (PdfDictionary)template.getResources());
126         }
127         put(PdfName.DR, dic);
128         put(PdfName.DA, new PdfString("/Helv 0 Tf 0 g "));
129         PdfDictionary fonts = (PdfDictionary)dic.get(PdfName.FONT);
130         if (fonts != null) {
131             writer.eliminateFontSubset(fonts);
132         }
133         return true;
134     }
135 
136     /**
137      * Adds an object to the calculationOrder.
138      * @param formField
139      */
140 
addCalculationOrder(PdfFormField formField)141     public void addCalculationOrder(PdfFormField formField) {
142         calculationOrder.add(formField.getIndirectReference());
143     }
144 
145     /**
146      * Sets the signature flags.
147      * @param f
148      */
149 
setSigFlags(int f)150     public void setSigFlags(int f) {
151         sigFlags |= f;
152     }
153 
154     /**
155      * Adds a formfield to the AcroForm.
156      * @param formField
157      */
158 
addFormField(PdfFormField formField)159     public void addFormField(PdfFormField formField) {
160         writer.addAnnotation(formField);
161     }
162 
163     /**
164      * @param name
165      * @param caption
166      * @param value
167      * @param url
168      * @param font
169      * @param fontSize
170      * @param llx
171      * @param lly
172      * @param urx
173      * @param ury
174      * @return a PdfFormField
175      */
addHtmlPostButton(String name, String caption, String value, String url, BaseFont font, float fontSize, float llx, float lly, float urx, float ury)176     public PdfFormField addHtmlPostButton(String name, String caption, String value, String url, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
177         PdfAction action = PdfAction.createSubmitForm(url, null, PdfAction.SUBMIT_HTML_FORMAT);
178         PdfFormField button = new PdfFormField(writer, llx, lly, urx, ury, action);
179         setButtonParams(button, PdfFormField.FF_PUSHBUTTON, name, value);
180         drawButton(button, caption, font, fontSize, llx, lly, urx, ury);
181         addFormField(button);
182 	return button;
183     }
184 
185     /**
186      * @param name
187      * @param caption
188      * @param value
189      * @param font
190      * @param fontSize
191      * @param llx
192      * @param lly
193      * @param urx
194      * @param ury
195      * @return a PdfFormField
196      */
addResetButton(String name, String caption, String value, BaseFont font, float fontSize, float llx, float lly, float urx, float ury)197     public PdfFormField addResetButton(String name, String caption, String value, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
198         PdfAction action = PdfAction.createResetForm(null, 0);
199         PdfFormField button = new PdfFormField(writer, llx, lly, urx, ury, action);
200         setButtonParams(button, PdfFormField.FF_PUSHBUTTON, name, value);
201         drawButton(button, caption, font, fontSize, llx, lly, urx, ury);
202         addFormField(button);
203         return button;
204     }
205 
206     /**
207      * @param name
208      * @param value
209      * @param url
210      * @param appearance
211      * @param llx
212      * @param lly
213      * @param urx
214      * @param ury
215      * @return a PdfFormField
216      */
addMap(String name, String value, String url, PdfContentByte appearance, float llx, float lly, float urx, float ury)217     public PdfFormField addMap(String name, String value, String url, PdfContentByte appearance, float llx, float lly, float urx, float ury) {
218         PdfAction action = PdfAction.createSubmitForm(url, null, PdfAction.SUBMIT_HTML_FORMAT | PdfAction.SUBMIT_COORDINATES);
219         PdfFormField button = new PdfFormField(writer, llx, lly, urx, ury, action);
220         setButtonParams(button, PdfFormField.FF_PUSHBUTTON, name, null);
221         PdfAppearance pa = PdfAppearance.createAppearance(writer, urx - llx, ury - lly);
222         pa.add(appearance);
223         button.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, pa);
224         addFormField(button);
225         return button;
226     }
227 
228     /**
229      * @param button
230      * @param characteristics
231      * @param name
232      * @param value
233      */
setButtonParams(PdfFormField button, int characteristics, String name, String value)234     public void setButtonParams(PdfFormField button, int characteristics, String name, String value) {
235         button.setButton(characteristics);
236         button.setFlags(PdfAnnotation.FLAGS_PRINT);
237         button.setPage();
238         button.setFieldName(name);
239         if (value != null) button.setValueAsString(value);
240     }
241 
242     /**
243      * @param button
244      * @param caption
245      * @param font
246      * @param fontSize
247      * @param llx
248      * @param lly
249      * @param urx
250      * @param ury
251      */
drawButton(PdfFormField button, String caption, BaseFont font, float fontSize, float llx, float lly, float urx, float ury)252     public void drawButton(PdfFormField button, String caption, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
253         PdfAppearance pa = PdfAppearance.createAppearance(writer, urx - llx, ury - lly);
254         pa.drawButton(0f, 0f, urx - llx, ury - lly, caption, font, fontSize);
255         button.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, pa);
256     }
257 
258     /**
259      * @param name
260      * @param value
261      * @return a PdfFormField
262      */
addHiddenField(String name, String value)263     public PdfFormField addHiddenField(String name, String value) {
264         PdfFormField hidden = PdfFormField.createEmpty(writer);
265         hidden.setFieldName(name);
266         hidden.setValueAsName(value);
267         addFormField(hidden);
268         return hidden;
269     }
270 
271     /**
272      * @param name
273      * @param text
274      * @param font
275      * @param fontSize
276      * @param llx
277      * @param lly
278      * @param urx
279      * @param ury
280      * @return a PdfFormField
281      */
addSingleLineTextField(String name, String text, BaseFont font, float fontSize, float llx, float lly, float urx, float ury)282     public PdfFormField addSingleLineTextField(String name, String text, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
283         PdfFormField field = PdfFormField.createTextField(writer, PdfFormField.SINGLELINE, PdfFormField.PLAINTEXT, 0);
284         setTextFieldParams(field, text, name, llx, lly, urx, ury);
285         drawSingleLineOfText(field, text, font, fontSize, llx, lly, urx, ury);
286         addFormField(field);
287         return field;
288     }
289 
290     /**
291      * @param name
292      * @param text
293      * @param font
294      * @param fontSize
295      * @param llx
296      * @param lly
297      * @param urx
298      * @param ury
299      * @return a PdfFormField
300      */
addMultiLineTextField(String name, String text, BaseFont font, float fontSize, float llx, float lly, float urx, float ury)301     public PdfFormField addMultiLineTextField(String name, String text, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
302         PdfFormField field = PdfFormField.createTextField(writer, PdfFormField.MULTILINE, PdfFormField.PLAINTEXT, 0);
303         setTextFieldParams(field, text, name, llx, lly, urx, ury);
304         drawMultiLineOfText(field, text, font, fontSize, llx, lly, urx, ury);
305         addFormField(field);
306         return field;
307     }
308 
309     /**
310      * @param name
311      * @param text
312      * @param font
313      * @param fontSize
314      * @param llx
315      * @param lly
316      * @param urx
317      * @param ury
318      * @return PdfFormField
319      */
addSingleLinePasswordField(String name, String text, BaseFont font, float fontSize, float llx, float lly, float urx, float ury)320     public PdfFormField addSingleLinePasswordField(String name, String text, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
321         PdfFormField field = PdfFormField.createTextField(writer, PdfFormField.SINGLELINE, PdfFormField.PASSWORD, 0);
322         setTextFieldParams(field, text, name, llx, lly, urx, ury);
323         drawSingleLineOfText(field, text, font, fontSize, llx, lly, urx, ury);
324         addFormField(field);
325         return field;
326     }
327 
328     /**
329      * @param field
330      * @param text
331      * @param name
332      * @param llx
333      * @param lly
334      * @param urx
335      * @param ury
336      */
setTextFieldParams(PdfFormField field, String text, String name, float llx, float lly, float urx, float ury)337     public void setTextFieldParams(PdfFormField field, String text, String name, float llx, float lly, float urx, float ury) {
338         field.setWidget(new Rectangle(llx, lly, urx, ury), PdfAnnotation.HIGHLIGHT_INVERT);
339         field.setValueAsString(text);
340         field.setDefaultValueAsString(text);
341         field.setFieldName(name);
342         field.setFlags(PdfAnnotation.FLAGS_PRINT);
343         field.setPage();
344     }
345 
346     /**
347      * @param field
348      * @param text
349      * @param font
350      * @param fontSize
351      * @param llx
352      * @param lly
353      * @param urx
354      * @param ury
355      */
drawSingleLineOfText(PdfFormField field, String text, BaseFont font, float fontSize, float llx, float lly, float urx, float ury)356     public void drawSingleLineOfText(PdfFormField field, String text, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
357         PdfAppearance tp = PdfAppearance.createAppearance(writer, urx - llx, ury - lly);
358         PdfAppearance tp2 = (PdfAppearance)tp.getDuplicate();
359         tp2.setFontAndSize(font, fontSize);
360         tp2.resetRGBColorFill();
361         field.setDefaultAppearanceString(tp2);
362         tp.drawTextField(0f, 0f, urx - llx, ury - lly);
363         tp.beginVariableText();
364         tp.saveState();
365         tp.rectangle(3f, 3f, urx - llx - 6f, ury - lly - 6f);
366         tp.clip();
367         tp.newPath();
368         tp.beginText();
369         tp.setFontAndSize(font, fontSize);
370         tp.resetRGBColorFill();
371         tp.setTextMatrix(4, (ury - lly) / 2 - (fontSize * 0.3f));
372         tp.showText(text);
373         tp.endText();
374         tp.restoreState();
375         tp.endVariableText();
376         field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, tp);
377     }
378 
379     /**
380      * @param field
381      * @param text
382      * @param font
383      * @param fontSize
384      * @param llx
385      * @param lly
386      * @param urx
387      * @param ury
388      */
drawMultiLineOfText(PdfFormField field, String text, BaseFont font, float fontSize, float llx, float lly, float urx, float ury)389     public void drawMultiLineOfText(PdfFormField field, String text, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
390         PdfAppearance tp = PdfAppearance.createAppearance(writer, urx - llx, ury - lly);
391         PdfAppearance tp2 = (PdfAppearance)tp.getDuplicate();
392         tp2.setFontAndSize(font, fontSize);
393         tp2.resetRGBColorFill();
394         field.setDefaultAppearanceString(tp2);
395         tp.drawTextField(0f, 0f, urx - llx, ury - lly);
396         tp.beginVariableText();
397         tp.saveState();
398         tp.rectangle(3f, 3f, urx - llx - 6f, ury - lly - 6f);
399         tp.clip();
400         tp.newPath();
401         tp.beginText();
402         tp.setFontAndSize(font, fontSize);
403         tp.resetRGBColorFill();
404         tp.setTextMatrix(4, 5);
405         java.util.StringTokenizer tokenizer = new java.util.StringTokenizer(text, "\n");
406         float yPos = ury - lly;
407         while (tokenizer.hasMoreTokens()) {
408             yPos -= fontSize * 1.2f;
409             tp.showTextAligned(PdfContentByte.ALIGN_LEFT, tokenizer.nextToken(), 3, yPos, 0);
410         }
411         tp.endText();
412         tp.restoreState();
413         tp.endVariableText();
414         field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, tp);
415     }
416 
417     /**
418      * @param name
419      * @param value
420      * @param status
421      * @param llx
422      * @param lly
423      * @param urx
424      * @param ury
425      * @return a PdfFormField
426      */
addCheckBox(String name, String value, boolean status, float llx, float lly, float urx, float ury)427     public PdfFormField addCheckBox(String name, String value, boolean status, float llx, float lly, float urx, float ury) {
428         PdfFormField field = PdfFormField.createCheckBox(writer);
429         setCheckBoxParams(field, name, value, status, llx, lly, urx, ury);
430         drawCheckBoxAppearences(field, value, llx, lly, urx, ury);
431         addFormField(field);
432         return field;
433     }
434 
435     /**
436      * @param field
437      * @param name
438      * @param value
439      * @param status
440      * @param llx
441      * @param lly
442      * @param urx
443      * @param ury
444      */
setCheckBoxParams(PdfFormField field, String name, String value, boolean status, float llx, float lly, float urx, float ury)445     public void setCheckBoxParams(PdfFormField field, String name, String value, boolean status, float llx, float lly, float urx, float ury) {
446         field.setWidget(new Rectangle(llx, lly, urx, ury), PdfAnnotation.HIGHLIGHT_TOGGLE);
447         field.setFieldName(name);
448         if (status) {
449             field.setValueAsName(value);
450             field.setAppearanceState(value);
451         }
452         else {
453             field.setValueAsName("Off");
454             field.setAppearanceState("Off");
455         }
456         field.setFlags(PdfAnnotation.FLAGS_PRINT);
457         field.setPage();
458         field.setBorderStyle(new PdfBorderDictionary(1, PdfBorderDictionary.STYLE_SOLID));
459     }
460 
461     /**
462      * @param field
463      * @param value
464      * @param llx
465      * @param lly
466      * @param urx
467      * @param ury
468      */
drawCheckBoxAppearences(PdfFormField field, String value, float llx, float lly, float urx, float ury)469     public void drawCheckBoxAppearences(PdfFormField field, String value, float llx, float lly, float urx, float ury) {
470         BaseFont font = null;
471         try {
472             font = BaseFont.createFont(BaseFont.ZAPFDINGBATS, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED);
473         }
474         catch(Exception e) {
475             throw new ExceptionConverter(e);
476         }
477         float size = (ury - lly);
478         PdfAppearance tpOn = PdfAppearance.createAppearance(writer, urx - llx, ury - lly);
479         PdfAppearance tp2 = (PdfAppearance)tpOn.getDuplicate();
480         tp2.setFontAndSize(font, size);
481         tp2.resetRGBColorFill();
482         field.setDefaultAppearanceString(tp2);
483         tpOn.drawTextField(0f, 0f, urx - llx, ury - lly);
484         tpOn.saveState();
485         tpOn.resetRGBColorFill();
486         tpOn.beginText();
487         tpOn.setFontAndSize(font, size);
488         tpOn.showTextAligned(PdfContentByte.ALIGN_CENTER, "4", (urx - llx) / 2, (ury - lly) / 2 - (size * 0.3f), 0);
489         tpOn.endText();
490         tpOn.restoreState();
491         field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, value, tpOn);
492         PdfAppearance tpOff = PdfAppearance.createAppearance(writer, urx - llx, ury - lly);
493         tpOff.drawTextField(0f, 0f, urx - llx, ury - lly);
494         field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, "Off", tpOff);
495     }
496 
497     /**
498      * @param name
499      * @param defaultValue
500      * @param noToggleToOff
501      * @return a PdfFormField
502      */
getRadioGroup(String name, String defaultValue, boolean noToggleToOff)503     public PdfFormField getRadioGroup(String name, String defaultValue, boolean noToggleToOff) {
504         PdfFormField radio = PdfFormField.createRadioButton(writer, noToggleToOff);
505         radio.setFieldName(name);
506         radio.setValueAsName(defaultValue);
507         return radio;
508     }
509 
510     /**
511      * @param radiogroup
512      */
addRadioGroup(PdfFormField radiogroup)513     public void addRadioGroup(PdfFormField radiogroup) {
514         addFormField(radiogroup);
515     }
516 
517     /**
518      * @param radiogroup
519      * @param value
520      * @param llx
521      * @param lly
522      * @param urx
523      * @param ury
524      * @return a PdfFormField
525      */
addRadioButton(PdfFormField radiogroup, String value, float llx, float lly, float urx, float ury)526     public PdfFormField addRadioButton(PdfFormField radiogroup, String value, float llx, float lly, float urx, float ury) {
527         PdfFormField radio = PdfFormField.createEmpty(writer);
528         radio.setWidget(new Rectangle(llx, lly, urx, ury), PdfAnnotation.HIGHLIGHT_TOGGLE);
529         String name = ((PdfName)radiogroup.get(PdfName.V)).toString().substring(1);
530         if (name.equals(value)) {
531             radio.setAppearanceState(value);
532         }
533         else {
534             radio.setAppearanceState("Off");
535         }
536         drawRadioAppearences(radio, value, llx, lly, urx, ury);
537         radiogroup.addKid(radio);
538         return radio;
539     }
540 
541     /**
542      * @param field
543      * @param value
544      * @param llx
545      * @param lly
546      * @param urx
547      * @param ury
548      */
drawRadioAppearences(PdfFormField field, String value, float llx, float lly, float urx, float ury)549     public void drawRadioAppearences(PdfFormField field, String value, float llx, float lly, float urx, float ury) {
550         PdfAppearance tpOn = PdfAppearance.createAppearance(writer, urx - llx, ury - lly);
551         tpOn.drawRadioField(0f, 0f, urx - llx, ury - lly, true);
552         field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, value, tpOn);
553         PdfAppearance tpOff = PdfAppearance.createAppearance(writer, urx - llx, ury - lly);
554         tpOff.drawRadioField(0f, 0f, urx - llx, ury - lly, false);
555         field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, "Off", tpOff);
556     }
557 
558     /**
559      * @param name
560      * @param options
561      * @param defaultValue
562      * @param font
563      * @param fontSize
564      * @param llx
565      * @param lly
566      * @param urx
567      * @param ury
568      * @return a PdfFormField
569      */
addSelectList(String name, String[] options, String defaultValue, BaseFont font, float fontSize, float llx, float lly, float urx, float ury)570     public PdfFormField addSelectList(String name, String[] options, String defaultValue, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
571         PdfFormField choice = PdfFormField.createList(writer, options, 0);
572         setChoiceParams(choice, name, defaultValue, llx, lly, urx, ury);
573         StringBuffer text = new StringBuffer();
574         for (int i = 0; i < options.length; i++) {
575             text.append(options[i]).append('\n');
576         }
577         drawMultiLineOfText(choice, text.toString(), font, fontSize, llx, lly, urx, ury);
578         addFormField(choice);
579         return choice;
580     }
581 
582     /**
583      * @param name
584      * @param options
585      * @param defaultValue
586      * @param font
587      * @param fontSize
588      * @param llx
589      * @param lly
590      * @param urx
591      * @param ury
592      * @return a PdfFormField
593      */
addSelectList(String name, String[][] options, String defaultValue, BaseFont font, float fontSize, float llx, float lly, float urx, float ury)594     public PdfFormField addSelectList(String name, String[][] options, String defaultValue, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
595         PdfFormField choice = PdfFormField.createList(writer, options, 0);
596         setChoiceParams(choice, name, defaultValue, llx, lly, urx, ury);
597         StringBuffer text = new StringBuffer();
598         for (int i = 0; i < options.length; i++) {
599             text.append(options[i][1]).append('\n');
600         }
601         drawMultiLineOfText(choice, text.toString(), font, fontSize, llx, lly, urx, ury);
602         addFormField(choice);
603         return choice;
604     }
605 
606     /**
607      * @param name
608      * @param options
609      * @param defaultValue
610      * @param editable
611      * @param font
612      * @param fontSize
613      * @param llx
614      * @param lly
615      * @param urx
616      * @param ury
617      * @return a PdfFormField
618      */
addComboBox(String name, String[] options, String defaultValue, boolean editable, BaseFont font, float fontSize, float llx, float lly, float urx, float ury)619     public PdfFormField addComboBox(String name, String[] options, String defaultValue, boolean editable, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
620         PdfFormField choice = PdfFormField.createCombo(writer, editable, options, 0);
621         setChoiceParams(choice, name, defaultValue, llx, lly, urx, ury);
622         if (defaultValue == null) {
623             defaultValue = options[0];
624         }
625         drawSingleLineOfText(choice, defaultValue, font, fontSize, llx, lly, urx, ury);
626         addFormField(choice);
627         return choice;
628     }
629 
630     /**
631      * @param name
632      * @param options
633      * @param defaultValue
634      * @param editable
635      * @param font
636      * @param fontSize
637      * @param llx
638      * @param lly
639      * @param urx
640      * @param ury
641      * @return a PdfFormField
642      */
addComboBox(String name, String[][] options, String defaultValue, boolean editable, BaseFont font, float fontSize, float llx, float lly, float urx, float ury)643     public PdfFormField addComboBox(String name, String[][] options, String defaultValue, boolean editable, BaseFont font, float fontSize, float llx, float lly, float urx, float ury) {
644         PdfFormField choice = PdfFormField.createCombo(writer, editable, options, 0);
645         setChoiceParams(choice, name, defaultValue, llx, lly, urx, ury);
646         String value = null;
647         for (int i = 0; i < options.length; i++) {
648             if (options[i][0].equals(defaultValue)) {
649                 value = options[i][1];
650                 break;
651             }
652         }
653         if (value == null) {
654             value = options[0][1];
655         }
656         drawSingleLineOfText(choice, value, font, fontSize, llx, lly, urx, ury);
657         addFormField(choice);
658         return choice;
659     }
660 
661     /**
662      * @param field
663      * @param name
664      * @param defaultValue
665      * @param llx
666      * @param lly
667      * @param urx
668      * @param ury
669      */
setChoiceParams(PdfFormField field, String name, String defaultValue, float llx, float lly, float urx, float ury)670     public void setChoiceParams(PdfFormField field, String name, String defaultValue, float llx, float lly, float urx, float ury) {
671         field.setWidget(new Rectangle(llx, lly, urx, ury), PdfAnnotation.HIGHLIGHT_INVERT);
672         if (defaultValue != null) {
673             field.setValueAsString(defaultValue);
674             field.setDefaultValueAsString(defaultValue);
675         }
676         field.setFieldName(name);
677         field.setFlags(PdfAnnotation.FLAGS_PRINT);
678         field.setPage();
679         field.setBorderStyle(new PdfBorderDictionary(2, PdfBorderDictionary.STYLE_SOLID));
680     }
681 
682     /**
683      * @param name
684      * @param llx
685      * @param lly
686      * @param urx
687      * @param ury
688      * @return a PdfFormField
689      */
addSignature(String name, float llx, float lly, float urx, float ury)690     public PdfFormField addSignature(String name,
691                     float llx, float lly, float urx, float ury) {
692         PdfFormField signature = PdfFormField.createSignature(writer);
693         setSignatureParams(signature, name, llx, lly, urx, ury);
694         drawSignatureAppearences(signature, llx, lly, urx, ury);
695         addFormField(signature);
696         return signature;
697     }
698 
699     /**
700      * @param field
701      * @param name
702      * @param llx
703      * @param lly
704      * @param urx
705      * @param ury
706      */
setSignatureParams(PdfFormField field, String name, float llx, float lly, float urx, float ury)707     public void setSignatureParams(PdfFormField field, String name,
708                     float llx, float lly, float urx, float ury) {
709         field.setWidget(new Rectangle(llx, lly, urx, ury), PdfAnnotation.HIGHLIGHT_INVERT);
710         field.setFieldName(name);
711         field.setFlags(PdfAnnotation.FLAGS_PRINT);
712         field.setPage();
713         field.setMKBorderColor(java.awt.Color.black);
714         field.setMKBackgroundColor(java.awt.Color.white);
715     }
716 
717     /**
718      * @param field
719      * @param llx
720      * @param lly
721      * @param urx
722      * @param ury
723      */
drawSignatureAppearences(PdfFormField field, float llx, float lly, float urx, float ury)724     public void drawSignatureAppearences(PdfFormField field,
725                     float llx, float lly, float urx, float ury) {
726         PdfAppearance tp = PdfAppearance.createAppearance(writer, urx - llx, ury - lly);
727         tp.setGrayFill(1.0f);
728         tp.rectangle(0, 0, urx - llx, ury - lly);
729         tp.fill();
730         tp.setGrayStroke(0);
731         tp.setLineWidth(1);
732         tp.rectangle(0.5f, 0.5f, urx - llx - 0.5f, ury - lly - 0.5f);
733         tp.closePathStroke();
734         tp.saveState();
735         tp.rectangle(1, 1, urx - llx - 2, ury - lly - 2);
736         tp.clip();
737         tp.newPath();
738         tp.restoreState();
739         field.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, tp);
740     }
741 }