Skip to content

Commit a1e83ef

Browse files
committed
Get rid of legacy list box drawing
DEVSIX-7517
1 parent e3aab4f commit a1e83ef

File tree

53 files changed

+216
-494
lines changed

Some content is hidden

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

53 files changed

+216
-494
lines changed

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

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -802,12 +802,15 @@ protected void drawListFormFieldAndSaveAppearance() {
802802
return;
803803
}
804804

805+
boolean multiselect = parent.getFieldFlag(PdfChoiceFormField.FF_MULTI_SELECT);
805806
if (!(formFieldElement instanceof ListBoxField)) {
806807
// Create it once and reset properties during each widget regeneration.
807-
formFieldElement = new ListBoxField("", 0, parent.getFieldFlag(PdfChoiceFormField.FF_MULTI_SELECT));
808+
formFieldElement = new ListBoxField(parent.getPartialFieldName().toUnicodeString(), 0, multiselect);
808809
}
809-
formFieldElement.setProperty(FormProperty.FORM_FIELD_MULTIPLE,
810-
parent.getFieldFlag(PdfChoiceFormField.FF_MULTI_SELECT));
810+
formFieldElement.setProperty(FormProperty.FORM_FIELD_MULTIPLE, multiselect);
811+
((ListBoxField) formFieldElement).setTopIndex(parent instanceof PdfChoiceFormField &&
812+
((PdfChoiceFormField) parent).getTopIndex() != null ?
813+
((PdfChoiceFormField) parent).getTopIndex().intValue() : 0);
811814

812815
PdfArray indices = getParent().getAsArray(PdfName.I);
813816
PdfArray options = parent.getOptions();
@@ -831,13 +834,24 @@ protected void drawListFormFieldAndSaveAppearance() {
831834
final boolean selected = indices != null && indices.contains(new PdfNumber(index));
832835
SelectFieldItem existingItem = ((ListBoxField) formFieldElement).getOption(exportValue);
833836
if (existingItem == null) {
834-
existingItem = new SelectFieldItem(exportValue, displayValue);
837+
existingItem = displayValue == null ? new SelectFieldItem(exportValue) :
838+
new SelectFieldItem(exportValue, displayValue);
835839
((ListBoxField) formFieldElement).addOption(existingItem);
836840
}
837841
existingItem.getElement().setProperty(Property.TEXT_ALIGNMENT, parent.getJustification());
838842
existingItem.getElement().setProperty(Property.OVERFLOW_Y, OverflowPropertyValue.VISIBLE);
839843
existingItem.getElement().setProperty(Property.OVERFLOW_X, OverflowPropertyValue.VISIBLE);
840844
existingItem.getElement().setProperty(FormProperty.FORM_FIELD_SELECTED, selected);
845+
// Workaround for com.itextpdf.forms.form.renderer.SelectFieldListBoxRenderer.applySelectedStyle:
846+
// in HTML rendering mode we want to draw gray background for flattened fields and blue one for interactive,
847+
// but here we temporarily flatten formFieldElement, so blue background property is explicitly set to
848+
// the selected item. We also need to clear background property for not selected items in case field
849+
// is regenerated with modified indices list.
850+
if (selected && (multiselect || index == indices.getAsNumber(indices.size() - 1).intValue())) {
851+
existingItem.getElement().setProperty(Property.BACKGROUND, new Background(new DeviceRgb(169, 204, 225)));
852+
} else {
853+
existingItem.getElement().setProperty(Property.BACKGROUND, null);
854+
}
841855
}
842856

843857
formFieldElement.setProperty(Property.FONT, getFont());
@@ -881,9 +895,18 @@ protected void drawTextFormFieldAndSaveAppearance() {
881895
if (parent.isMultiline()) {
882896
formFieldElement.setProperty(Property.FONT_SIZE, UnitValue.createPointValue(getFontSize()));
883897
} else {
884-
formFieldElement.setProperty(Property.FONT_SIZE,
885-
UnitValue.createPointValue(getFontSize(new PdfArray(rectangle), parent.getValueAsString())));
898+
float fontSize = getFontSize(new PdfArray(rectangle), parent.getValueAsString());
899+
if (fontSize != 0) {
900+
// We want to always draw the text using the given font size even if it's not fit into layout area.
901+
// Without setting this property the height of the drawn field will be 0 which is unexpected.
902+
formFieldElement.setProperty(Property.FORCED_PLACEMENT, true);
903+
}
904+
formFieldElement.setProperty(Property.FONT_SIZE, UnitValue.createPointValue(fontSize));
886905
value = value.replaceAll(LINE_ENDINGS_REGEXP, " ");
906+
((InputField) formFieldElement).setComb(this.isCombTextFormField());
907+
((InputField) formFieldElement).setMaxLen((parent instanceof PdfTextFormField ? (PdfTextFormField) parent :
908+
PdfFormCreator.createTextFormField(parent.getPdfObject())).getMaxLen());
909+
((InputField)formFieldElement).useAsPassword(parent.isPassword());
887910
}
888911
formFieldElement.setValue(value);
889912
formFieldElement.setProperty(Property.FONT, getFont());
@@ -924,7 +947,7 @@ protected void drawComboBoxAndSaveAppearance() {
924947
return;
925948
}
926949
if (!(formFieldElement instanceof ComboBoxField)) {
927-
formFieldElement = new ComboBoxField("");
950+
formFieldElement = new ComboBoxField(parent.getPartialFieldName().toUnicodeString());
928951
}
929952

930953
ComboBoxField comboBoxField = (ComboBoxField) formFieldElement;
@@ -1057,20 +1080,13 @@ boolean regenerateWidget() {
10571080
final PdfName type = parent.getFormType();
10581081
retrieveStyles();
10591082

1060-
if ((PdfName.Ch.equals(type) && parent.getFieldFlag(PdfChoiceFormField.FF_COMBO))
1061-
|| this.isCombTextFormField()) {
1062-
if (parent.getFieldFlag(PdfChoiceFormField.FF_COMBO) && formFieldElement != null) {
1083+
if (PdfName.Ch.equals(type)) {
1084+
if (parent.getFieldFlag(PdfChoiceFormField.FF_COMBO)) {
10631085
drawComboBoxAndSaveAppearance();
10641086
return true;
10651087
}
1066-
return TextAndChoiceLegacyDrawer.regenerateTextAndChoiceField(this);
1067-
} else if (PdfName.Ch.equals(type) && !parent.getFieldFlag(PdfChoiceFormField.FF_COMBO)) {
1068-
if (formFieldElement != null) {
1069-
drawListFormFieldAndSaveAppearance();
1070-
return true;
1071-
} else {
1072-
return TextAndChoiceLegacyDrawer.regenerateTextAndChoiceField(this);
1073-
}
1088+
drawListFormFieldAndSaveAppearance();
1089+
return true;
10741090
} else if (PdfName.Tx.equals(type)) {
10751091
drawTextFormFieldAndSaveAppearance();
10761092
return true;
@@ -1164,14 +1180,17 @@ float getFontSize(PdfArray bBox, String value) {
11641180

11651181
private boolean isCombTextFormField() {
11661182
final PdfName type = parent.getFormType();
1167-
if (PdfName.Tx.equals(type) && parent.getFieldFlag(PdfTextFormField.FF_COMB)) {
1168-
int maxLen = PdfFormCreator.createTextFormField(parent.getPdfObject()).getMaxLen();
1169-
if (maxLen == 0 || parent.isMultiline()) {
1170-
LOGGER.error(
1171-
MessageFormatUtil.format(IoLogMessageConstant.COMB_FLAG_MAY_BE_SET_ONLY_IF_MAXLEN_IS_PRESENT));
1172-
return false;
1183+
if (PdfName.Tx.equals(type)) {
1184+
PdfTextFormField textField = parent instanceof PdfTextFormField ? (PdfTextFormField) parent :
1185+
PdfFormCreator.createTextFormField(parent.getPdfObject());
1186+
if (textField.isComb()) {
1187+
if (textField.getMaxLen() == 0 ||
1188+
textField.isMultiline() || textField.isPassword() || textField.isFileSelect()) {
1189+
LOGGER.error(IoLogMessageConstant.COMB_FLAG_MAY_BE_SET_ONLY_IF_MAXLEN_IS_PRESENT);
1190+
return false;
1191+
}
1192+
return true;
11731193
}
1174-
return true;
11751194
}
11761195
return false;
11771196
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,8 @@ public PdfTextFormField setScroll(boolean scroll) {
174174
* and if the Multiline, Password, and FileSelect flags are clear.
175175
* If true, the field is automatically divided into as many equally spaced positions,
176176
* or combs, as the value of MaxLen, and the text is laid out into those combs.
177-
* @return whether or not combing is enabled
177+
*
178+
* @return {@code true} if combing is enabled, {@code false} otherwise
178179
*/
179180
public boolean isComb() {
180181
return getFieldFlag(FF_COMB);

0 commit comments

Comments
 (0)