Skip to content

Commit 07551d7

Browse files
committed
Fix model element/form field recreation with (re)setting parameters
DEVSIX-7423
1 parent 8ab16e4 commit 07551d7

File tree

73 files changed

+580
-213
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+580
-213
lines changed

forms/src/main/java/com/itextpdf/forms/fields/PdfFormAnnotation.java

Lines changed: 71 additions & 145 deletions
Large diffs are not rendered by default.

forms/src/main/java/com/itextpdf/forms/form/element/FormField.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,25 +64,27 @@ public T setSize(float size) {
6464
}
6565

6666
/**
67-
* Set the form field's width.
67+
* {@inheritDoc}
6868
*
69-
* @param width form field's width
69+
* @param width {@inheritDoc}
7070
*
71-
* @return this {@link FormField} element.
71+
* @return {@inheritDoc}
7272
*/
73-
public T setWidth(float width) {
73+
@Override
74+
public IFormField setWidth(float width) {
7475
setProperty(Property.WIDTH, UnitValue.createPointValue(width));
7576
return (T) (Object) this;
7677
}
7778

7879
/**
79-
* Set the form field's height.
80+
* {@inheritDoc}
8081
*
81-
* @param height form field's height
82+
* @param height {@inheritDoc}
8283
*
83-
* @return this {@link FormField} element.
84+
* @return {@inheritDoc}
8485
*/
85-
public T setHeight(float height) {
86+
@Override
87+
public IFormField setHeight(float height) {
8688
setProperty(Property.HEIGHT, UnitValue.createPointValue(height));
8789
return (T) (Object) this;
8890
}

forms/src/main/java/com/itextpdf/forms/form/element/IFormField.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public interface IFormField extends IBlockElement {
4242
* Set the form field to be interactive and added into Acroform instead of drawing it on a page.
4343
*
4444
* @param interactive {@code true} if the form field element shall be added into Acroform, {@code false} otherwise.
45-
* By default, the form field element is not interactive and drawn on a page.
45+
* By default, the form field element is not interactive and drawn on a page.
4646
*
4747
* @return this same {@link IFormField} instance.
4848
*/
@@ -54,4 +54,22 @@ public interface IFormField extends IBlockElement {
5454
* @return the id.
5555
*/
5656
String getId();
57+
58+
/**
59+
* Set the form field's width.
60+
*
61+
* @param width form field's width.
62+
*
63+
* @return this {@link FormField} element.
64+
*/
65+
IFormField setWidth(float width);
66+
67+
/**
68+
* Set the form field's height.
69+
*
70+
* @param height form field's height.
71+
*
72+
* @return this {@link FormField} element.
73+
*/
74+
IFormField setHeight(float height);
5775
}

forms/src/main/java/com/itextpdf/forms/form/renderer/AbstractFormFieldRenderer.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,20 @@ This file is part of the iText (R) project.
2222
*/
2323
package com.itextpdf.forms.form.renderer;
2424

25+
import com.itextpdf.forms.fields.PdfFormAnnotation;
2526
import com.itextpdf.forms.form.FormProperty;
2627
import com.itextpdf.forms.form.element.IFormField;
2728
import com.itextpdf.forms.logs.FormsLogMessageConstants;
2829
import com.itextpdf.kernel.geom.Rectangle;
30+
import com.itextpdf.kernel.pdf.PdfDictionary;
2931
import com.itextpdf.kernel.pdf.PdfDocument;
32+
import com.itextpdf.kernel.pdf.PdfName;
33+
import com.itextpdf.kernel.pdf.annot.PdfAnnotation;
3034
import com.itextpdf.kernel.pdf.tagging.StandardRoles;
3135
import com.itextpdf.kernel.pdf.tagutils.AccessibilityProperties;
3236
import com.itextpdf.kernel.pdf.tagutils.TagTreePointer;
3337
import com.itextpdf.layout.IPropertyContainer;
38+
import com.itextpdf.layout.borders.Border;
3439
import com.itextpdf.layout.layout.LayoutArea;
3540
import com.itextpdf.layout.layout.LayoutContext;
3641
import com.itextpdf.layout.layout.LayoutResult;
@@ -276,6 +281,36 @@ protected void writeAcroFormFieldLangAttribute(PdfDocument pdfDoc) {
276281
}
277282
}
278283

284+
/**
285+
* Deletes all margin properties. Used in {@code applyAcroField} to not apply margins twice as we already use area
286+
* with margins applied (margins shouldn't be an interactive part of the field, i.e. included into its occupied
287+
* area).
288+
*/
289+
void deleteMargins() {
290+
modelElement.deleteOwnProperty(Property.MARGIN_RIGHT);
291+
modelElement.deleteOwnProperty(Property.MARGIN_LEFT);
292+
modelElement.deleteOwnProperty(Property.MARGIN_TOP);
293+
modelElement.deleteOwnProperty(Property.MARGIN_BOTTOM);
294+
}
295+
296+
/**
297+
* Applies the border property.
298+
*
299+
* @param annotation the annotation to set border characteristics to.
300+
*/
301+
void applyBorderProperty(PdfFormAnnotation annotation) {
302+
Border border = this.<Border>getProperty(Property.BORDER);
303+
if (border == null) {
304+
// For now, we set left border to an annotation, but appropriate borders for an element will be drawn.
305+
border = this.<Border>getProperty(Property.BORDER_LEFT);
306+
}
307+
if (border != null) {
308+
annotation.setBorderStyle(transformBorderTypeToBorderStyleDictionary(border.getType()));
309+
annotation.setBorderColor(border.getColor());
310+
annotation.setBorderWidth(border.getWidth());
311+
}
312+
}
313+
279314
private void processLangAttribute() {
280315
IPropertyContainer propertyContainer = flatRenderer.getModelElement();
281316
String lang = getLang();
@@ -286,4 +321,31 @@ private void processLangAttribute() {
286321
}
287322
}
288323
}
324+
325+
private static PdfDictionary transformBorderTypeToBorderStyleDictionary(int borderType) {
326+
PdfDictionary bs = new PdfDictionary();
327+
PdfName style;
328+
switch (borderType) {
329+
case 1001:
330+
style = PdfAnnotation.STYLE_UNDERLINE;
331+
break;
332+
case 1002:
333+
style = PdfAnnotation.STYLE_BEVELED;
334+
break;
335+
case 1003:
336+
style = PdfAnnotation.STYLE_INSET;
337+
break;
338+
case Border.DASHED_FIXED:
339+
case Border.DASHED:
340+
case Border.DOTTED:
341+
// Default dash array will be used.
342+
style = PdfAnnotation.STYLE_DASHED;
343+
break;
344+
default:
345+
style = PdfAnnotation.STYLE_SOLID;
346+
break;
347+
}
348+
bs.put(PdfName.S, style);
349+
return bs;
350+
}
289351
}

forms/src/main/java/com/itextpdf/forms/form/renderer/AbstractTextFieldRenderer.java

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ This file is part of the iText (R) project.
2727
import com.itextpdf.kernel.font.PdfFont;
2828
import com.itextpdf.kernel.geom.Rectangle;
2929
import com.itextpdf.kernel.pdf.annot.PdfAnnotation;
30-
import com.itextpdf.layout.borders.Border;
3130
import com.itextpdf.layout.element.Paragraph;
3231
import com.itextpdf.layout.properties.Background;
3332
import com.itextpdf.layout.properties.BoxSizingPropertyValue;
@@ -87,17 +86,7 @@ void applyDefaultFieldProperties(PdfFormField inputField) {
8786
inputField.setColor(color.getColor());
8887
}
8988
inputField.setJustification(this.<TextAlignment>getProperty(Property.TEXT_ALIGNMENT));
90-
91-
Border border = this.<Border>getProperty(Property.BORDER);
92-
if (border == null) {
93-
// TODO For now we will use left border everywhere, shall be fixed in DEVSIX-7423.
94-
border = this.<Border>getProperty(Property.BORDER_LEFT);
95-
}
96-
if (border != null) {
97-
inputField.getFirstFormAnnotation().setBorderColor(border.getColor());
98-
inputField.getFirstFormAnnotation().setBorderWidth(border.getWidth());
99-
}
100-
89+
applyBorderProperty(inputField.getFirstFormAnnotation());
10190
Background background = this.<Background>getProperty(Property.BACKGROUND);
10291
if (background != null) {
10392
inputField.getFirstFormAnnotation().setBackgroundColor(background.getColor());

forms/src/main/java/com/itextpdf/forms/form/renderer/ButtonRenderer.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ protected void applyAcroField(DrawContext drawContext) {
266266
PdfDocument doc = drawContext.getDocument();
267267
Rectangle area = getOccupiedArea().getBBox().clone();
268268
applyMargins(area, false);
269+
deleteMargins();
269270
PdfPage page = doc.getPage(occupiedArea.getPageNumber());
270271

271272
Background background = this.<Background>getProperty(Property.BACKGROUND);
@@ -287,12 +288,7 @@ protected void applyAcroField(DrawContext drawContext) {
287288
button.setFont(font).setFontSize(fontSizeValue);
288289
button.getFirstFormAnnotation().setBackgroundColor(backgroundColor);
289290
applyDefaultFieldProperties(button);
290-
Border border = getBorders()[0];
291-
if (border != null) {
292-
button.getFirstFormAnnotation().setBorderColor(border.getColor());
293-
button.getFirstFormAnnotation().setBorderWidth(border.getWidth());
294-
}
295-
button.getFirstFormAnnotation().setFormFieldElement((Button)modelElement);
291+
button.getFirstFormAnnotation().setFormFieldElement((Button) modelElement);
296292
PdfAcroForm forms = PdfAcroForm.getAcroForm(doc, true);
297293
// Fields can be already added on split, e.g. when button split into multiple pages. But now we merge fields
298294
// with the same names (and add all the widgets as kids to that merged field), so we can add it anyway.

forms/src/main/java/com/itextpdf/forms/form/renderer/CheckBoxRenderer.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,7 @@ protected void applyAcroField(DrawContext drawContext) {
217217
final String name = getModelId();
218218
final PdfDocument doc = drawContext.getDocument();
219219
final Rectangle area = flatRenderer.getOccupiedArea().getBBox().clone();
220+
deleteMargins();
220221
final PdfPage page = doc.getPage(occupiedArea.getPageNumber());
221222
final CheckBoxFormFieldBuilder builder = new CheckBoxFormFieldBuilder(doc, name).setWidgetRectangle(area)
222223
.setConformanceLevel(this.<PdfAConformanceLevel>getProperty(FormProperty.FORM_CONFORMANCE_LEVEL));
@@ -225,21 +226,16 @@ protected void applyAcroField(DrawContext drawContext) {
225226
builder.setCheckType((CheckBoxType) this.<CheckBoxType>getProperty(FormProperty.FORM_CHECKBOX_TYPE));
226227
}
227228
final PdfButtonFormField checkBox = builder.createCheckBox();
228-
checkBox.getFirstFormAnnotation().setRenderingMode(this.getRenderingMode());
229-
final Border border = this.<Border>getProperty(Property.BORDER);
230-
if (border != null) {
231-
checkBox.getFirstFormAnnotation().setBorderColor(border.getColor());
232-
checkBox.getFirstFormAnnotation().setBorderWidth(border.getWidth());
233-
}
229+
applyBorderProperty(checkBox.getFirstFormAnnotation());
234230
final Background background = this.modelElement.<Background>getProperty(Property.BACKGROUND);
235231
if (background != null) {
236232
checkBox.getFirstFormAnnotation().setBackgroundColor(background.getColor());
237233
}
238-
239234
checkBox.setValue(PdfFormAnnotation.ON_STATE_VALUE);
240235
if (!isBoxChecked()) {
241236
checkBox.setValue(PdfFormAnnotation.OFF_STATE_VALUE);
242237
}
238+
checkBox.getFirstFormAnnotation().setFormFieldElement((CheckBox) modelElement);
243239

244240
PdfAcroForm.getAcroForm(doc, true).addField(checkBox, page);
245241
writeAcroFormFieldLangAttribute(doc);

forms/src/main/java/com/itextpdf/forms/form/renderer/FormFieldValueNonTrimmingTextRenderer.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,7 @@ This file is part of the iText (R) project.
4242
*/
4343

4444
// Temporarily public, make it package private on cleanup of PdfFormAnnotation
45-
// TODO DEVSIX-7423 (or put another devsix if the usage of this class is not removed from PdfFormAnnotation
46-
// as part of DEVSIX-7423)
45+
// TODO DEVSIX-7385 Finalize code related to form fields renderers separation
4746
public class FormFieldValueNonTrimmingTextRenderer extends TextRenderer {
4847
// Determines whether we want to trim leading space. In particular we don't want to trim
4948
// the very first leading spaces of the text value. When text overflows to the next lines,

forms/src/main/java/com/itextpdf/forms/form/renderer/InputFieldRenderer.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ This file is part of the iText (R) project.
3838
import com.itextpdf.layout.element.Text;
3939
import com.itextpdf.layout.layout.LayoutContext;
4040
import com.itextpdf.layout.minmaxwidth.MinMaxWidth;
41+
import com.itextpdf.layout.properties.BoxSizingPropertyValue;
4142
import com.itextpdf.layout.properties.Property;
4243
import com.itextpdf.layout.properties.UnitValue;
4344
import com.itextpdf.layout.renderer.DrawContext;
@@ -164,9 +165,14 @@ protected void applyAcroField(DrawContext drawContext) {
164165
}
165166
final PdfDocument doc = drawContext.getDocument();
166167
final Rectangle area = this.getOccupiedArea().getBBox().clone();
168+
applyMargins(area, false);
169+
deleteMargins();
167170
final PdfPage page = doc.getPage(occupiedArea.getPageNumber());
168171
final float fontSizeValue = fontSize.getValue();
169172

173+
// Default html2pdf input field appearance differs from the default one for form fields.
174+
// That's why we got rid of several properties we set by default during InputField instance creation.
175+
modelElement.setProperty(Property.BOX_SIZING, BoxSizingPropertyValue.BORDER_BOX);
170176
final PdfFormField inputField = new TextFormFieldBuilder(doc, name).setWidgetRectangle(area).createText()
171177
.setValue(value);
172178
inputField.setFont(font).setFontSize(fontSizeValue);
@@ -180,6 +186,7 @@ protected void applyAcroField(DrawContext drawContext) {
180186
inputField.getFirstFormAnnotation().setRotation(rotation);
181187
}
182188
applyDefaultFieldProperties(inputField);
189+
inputField.getFirstFormAnnotation().setFormFieldElement((InputField) modelElement);
183190
PdfAcroForm.getAcroForm(doc, true).addField(inputField, page);
184191

185192
writeAcroFormFieldLangAttribute(doc);

forms/src/main/java/com/itextpdf/forms/form/renderer/RadioRenderer.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ protected void applyAcroField(DrawContext drawContext) {
163163
PdfDocument doc = drawContext.getDocument();
164164
PdfAcroForm form = PdfAcroForm.getAcroForm(doc, true);
165165
Rectangle area = flatRenderer.getOccupiedArea().getBBox().clone();
166+
deleteMargins();
166167

167168
PdfPage page = doc.getPage(occupiedArea.getPageNumber());
168169
String groupName = this.<String>getProperty(FormProperty.FORM_FIELD_RADIO_GROUP_NAME);
@@ -188,11 +189,8 @@ protected void applyAcroField(DrawContext drawContext) {
188189
if (background != null) {
189190
radio.setBackgroundColor(background.getColor());
190191
}
191-
Border border = this.<Border>getProperty(Property.BORDER);
192-
if (border != null) {
193-
radio.setBorderColor(border.getColor());
194-
radio.setBorderWidth(border.getWidth());
195-
}
192+
applyBorderProperty(radio);
193+
radio.setFormFieldElement((Radio) modelElement);
196194

197195
radioGroup.addKid(radio);
198196

0 commit comments

Comments
 (0)