diff --git a/itext.tests/itext.forms.tests/itext/forms/PdfFormFieldTest.cs b/itext.tests/itext.forms.tests/itext/forms/PdfFormFieldTest.cs
index b570abe7dd..d297f34141 100644
--- a/itext.tests/itext.forms.tests/itext/forms/PdfFormFieldTest.cs
+++ b/itext.tests/itext.forms.tests/itext/forms/PdfFormFieldTest.cs
@@ -38,7 +38,6 @@ You should have received a copy of the GNU Affero General Public License
using iText.Kernel.Utils;
using iText.Layout;
using iText.Layout.Element;
-using iText.Layout.Logs;
using iText.Layout.Properties;
using iText.Test;
using iText.Test.Attributes;
@@ -978,10 +977,13 @@ public virtual void PdfWithDifferentFieldsTest() {
// list
PdfChoiceFormField f = new ChoiceFormFieldBuilder(pdfDoc, "combo").SetWidgetRectangle(new Rectangle(36, 556
, 50, 100)).SetOptions(new String[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" }).CreateList();
+ f.DisableFieldRegeneration();
f.SetValue("9", true);
f.SetValue("4");
f.SetTopIndex(2);
f.SetListSelected(new String[] { "3", "5" });
+ f.SetMultiSelect(true);
+ f.EnableFieldRegeneration();
form.AddField(f);
// push button
form.AddField(new PushButtonFormFieldBuilder(pdfDoc, "push button").SetWidgetRectangle(new Rectangle(36, 526
@@ -1139,7 +1141,6 @@ public virtual void SetFont2Ways() {
[NUnit.Framework.Test]
// Acrobat removes /NeedAppearances flag when document is opened and suggests to resave the document at once.
- [LogMessage(LayoutLogMessageConstant.ELEMENT_DOES_NOT_FIT_AREA)]
[LogMessage(FormsLogMessageConstants.INPUT_FIELD_DOES_NOT_FIT)]
public virtual void AppendModeAppearance() {
String inputFile = "appendModeAppearance.pdf";
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_choiceFieldsSetValueTest.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_choiceFieldsSetValueTest.pdf
index e486ae965c..504a2fbb96 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_choiceFieldsSetValueTest.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_choiceFieldsSetValueTest.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_choiceFieldsWithUnicodeTest.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_choiceFieldsWithUnicodeTest.pdf
index 12aebb8013..9f87d03e36 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_choiceFieldsWithUnicodeTest.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_choiceFieldsWithUnicodeTest.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_comboNoHighlightCenteredTextOfChosenFirstItemTest.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_comboNoHighlightCenteredTextOfChosenFirstItemTest.pdf
index a38e49cc5d..234af1ce9a 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_comboNoHighlightCenteredTextOfChosenFirstItemTest.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_comboNoHighlightCenteredTextOfChosenFirstItemTest.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_corruptedOptAndValueSetToNullTest.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_corruptedOptAndValueSetToNullTest.pdf
index 955b6ff46c..b2d908e99e 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_corruptedOptAndValueSetToNullTest.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_corruptedOptAndValueSetToNullTest.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_longOptionWrappedIntoTwoLinesTest.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_longOptionWrappedIntoTwoLinesTest.pdf
index f77abb317a..5fdd28ee68 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_longOptionWrappedIntoTwoLinesTest.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_longOptionWrappedIntoTwoLinesTest.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_multiSelectByIndexOutOfBoundsTest.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_multiSelectByIndexOutOfBoundsTest.pdf
index 45e7b2be1d..610912e700 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_multiSelectByIndexOutOfBoundsTest.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_multiSelectByIndexOutOfBoundsTest.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_multiSelectByValueTest.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_multiSelectByValueTest.pdf
index ffc4015922..df10ca14dd 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_multiSelectByValueTest.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_multiSelectByValueTest.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_noWarningOnValueNotOfOptComboEditTest.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_noWarningOnValueNotOfOptComboEditTest.pdf
index 48b01bb850..5722b654e8 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_noWarningOnValueNotOfOptComboEditTest.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_noWarningOnValueNotOfOptComboEditTest.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_notInstanceOfPdfChoiceFormFieldTest.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_notInstanceOfPdfChoiceFormFieldTest.pdf
index 959b0cf421..523c29b0b1 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_notInstanceOfPdfChoiceFormFieldTest.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_notInstanceOfPdfChoiceFormFieldTest.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_selectByValueRemoveIKeyTest.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_selectByValueRemoveIKeyTest.pdf
index ddcb212d4e..fdc407fd3a 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_selectByValueRemoveIKeyTest.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_selectByValueRemoveIKeyTest.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_topIndexTest.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_topIndexTest.pdf
index 88f28dc0a5..127407f80b 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_topIndexTest.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/PdfChoiceFieldTest/cmp_topIndexTest.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_choiceFieldAutoSize01Test.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_choiceFieldAutoSize01Test.pdf
index 7af2298409..9f66295c44 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_choiceFieldAutoSize01Test.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_choiceFieldAutoSize01Test.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_choiceFieldAutoSize02Test.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_choiceFieldAutoSize02Test.pdf
index e6b295a72e..5fa41700d9 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_choiceFieldAutoSize02Test.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_choiceFieldAutoSize02Test.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_choiceFieldTest01.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_choiceFieldTest01.pdf
index fd731e932b..62aa5fd424 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_choiceFieldTest01.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_choiceFieldTest01.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_maxLenColoredTest.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_maxLenColoredTest.pdf
index 9be43336d5..294e248d67 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_maxLenColoredTest.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_maxLenColoredTest.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_maxLenDeepInheritanceTest.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_maxLenDeepInheritanceTest.pdf
index 2a078731f2..762f7f115f 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_maxLenDeepInheritanceTest.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_maxLenDeepInheritanceTest.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_maxLenInheritanceTest.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_maxLenInheritanceTest.pdf
index 1044150545..35a9ef00da 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_maxLenInheritanceTest.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_maxLenInheritanceTest.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_maxLenWithSetCombFlagAppearanceTest.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_maxLenWithSetCombFlagAppearanceTest.pdf
index 2eaf41080a..5a36797ec4 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_maxLenWithSetCombFlagAppearanceTest.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_maxLenWithSetCombFlagAppearanceTest.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_noMaxLenWithSetCombFlagTest.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_noMaxLenWithSetCombFlagTest.pdf
index 7918f1b2ff..0034cbe7a4 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_noMaxLenWithSetCombFlagTest.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_noMaxLenWithSetCombFlagTest.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_pdfWithDifferentFieldsTest.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_pdfWithDifferentFieldsTest.pdf
index 47b9dc46e2..6a15677748 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_pdfWithDifferentFieldsTest.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_pdfWithDifferentFieldsTest.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_regenerateMaxLenCombTest.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_regenerateMaxLenCombTest.pdf
index ff9d7db8c3..950c609c82 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_regenerateMaxLenCombTest.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_regenerateMaxLenCombTest.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_setValueWithDisplayTest.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_setValueWithDisplayTest.pdf
index 7a456b4fe4..845d123400 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_setValueWithDisplayTest.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/PdfFormFieldTest/cmp_setValueWithDisplayTest.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/XfdfReaderTest/cmp_xfdfDropDown.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/XfdfReaderTest/cmp_xfdfDropDown.pdf
index 0218a7c84b..c57e22b437 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/XfdfReaderTest/cmp_xfdfDropDown.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/XfdfReaderTest/cmp_xfdfDropDown.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/XfdfReaderTest/cmp_xfdfList.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/XfdfReaderTest/cmp_xfdfList.pdf
index db29b7fb5f..27637b7755 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/XfdfReaderTest/cmp_xfdfList.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/XfdfReaderTest/cmp_xfdfList.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_basicListBoxField.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_basicListBoxField.pdf
index f3d1ce83cf..ad543c9f93 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_basicListBoxField.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_basicListBoxField.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_colorsBorders.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_colorsBorders.pdf
index 59e98de8e6..1f683ffd8f 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_colorsBorders.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_colorsBorders.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_exportValue.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_exportValue.pdf
index 7ab9e1885f..23596f7f12 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_exportValue.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_exportValue.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_justification.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_justification.pdf
index 6de476c24e..7da2d6ce5c 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_justification.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_justification.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_listBoxFieldCannotFit.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_listBoxFieldCannotFit.pdf
index b0747fe97a..938d787215 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_listBoxFieldCannotFit.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_listBoxFieldCannotFit.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_listBoxFieldCannotFitByWidth.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_listBoxFieldCannotFitByWidth.pdf
index b1729f065a..876f01f603 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_listBoxFieldCannotFitByWidth.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_listBoxFieldCannotFitByWidth.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_listBoxFieldWithHeight.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_listBoxFieldWithHeight.pdf
index e02d5b1b4b..c0ae115524 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_listBoxFieldWithHeight.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_listBoxFieldWithHeight.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_listBoxFieldWithMargins.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_listBoxFieldWithMargins.pdf
index df56acf0b0..f9de9bd764 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_listBoxFieldWithMargins.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_listBoxFieldWithMargins.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_listBoxFieldWithMaxHeight.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_listBoxFieldWithMaxHeight.pdf
index 470ad0c7ba..14ef2bc145 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_listBoxFieldWithMaxHeight.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_listBoxFieldWithMaxHeight.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_listBoxFieldWithMinHeight.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_listBoxFieldWithMinHeight.pdf
index a23c786345..88ac402017 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_listBoxFieldWithMinHeight.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_listBoxFieldWithMinHeight.pdf differ
diff --git a/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_longList.pdf b/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_longList.pdf
index c2e67df2dd..ca8ab0d367 100644
Binary files a/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_longList.pdf and b/itext.tests/itext.forms.tests/resources/itext/forms/form/element/ListBoxFieldTest/cmp_longList.pdf differ
diff --git a/itext.tests/itext.pdfa.tests/itext/pdfa/PdfAFormFieldTest.cs b/itext.tests/itext.pdfa.tests/itext/pdfa/PdfAFormFieldTest.cs
index 17e445d865..799e18af71 100644
--- a/itext.tests/itext.pdfa.tests/itext/pdfa/PdfAFormFieldTest.cs
+++ b/itext.tests/itext.pdfa.tests/itext/pdfa/PdfAFormFieldTest.cs
@@ -196,7 +196,6 @@ public virtual void PdfA1DocWithPdfA1ComboBoxFieldTest() {
// Android-Conversion-Skip-Line (TODO DEVSIX-7377 introduce pdf\a validation on Android)
[NUnit.Framework.Test]
- [LogMessage(iText.IO.Logs.IoLogMessageConstant.MULTIPLE_VALUES_ON_A_NON_MULTISELECT_FIELD)]
public virtual void PdfA1DocWithPdfA1ListFieldTest() {
String name = "pdfA1DocWithPdfA1ListField";
String fileName = DESTINATION_FOLDER + name + ".pdf";
@@ -214,6 +213,7 @@ public virtual void PdfA1DocWithPdfA1ListFieldTest() {
f.SetValue("9").SetFont(fontFreeSans);
f.SetValue("4");
f.SetTopIndex(2);
+ f.SetMultiSelect(true);
f.SetListSelected(new String[] { "3", "5" });
form.AddField(f);
pdfDoc.Close();
diff --git a/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfAFormFieldTest/cmp_pdfA1DocWithPdfA1ChoiceField.pdf b/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfAFormFieldTest/cmp_pdfA1DocWithPdfA1ChoiceField.pdf
index 1e27c9906c..7936559ba2 100644
Binary files a/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfAFormFieldTest/cmp_pdfA1DocWithPdfA1ChoiceField.pdf and b/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfAFormFieldTest/cmp_pdfA1DocWithPdfA1ChoiceField.pdf differ
diff --git a/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfAFormFieldTest/cmp_pdfA1DocWithPdfA1ComboBoxField.pdf b/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfAFormFieldTest/cmp_pdfA1DocWithPdfA1ComboBoxField.pdf
index 619b096a9f..4d84455d50 100644
Binary files a/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfAFormFieldTest/cmp_pdfA1DocWithPdfA1ComboBoxField.pdf and b/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfAFormFieldTest/cmp_pdfA1DocWithPdfA1ComboBoxField.pdf differ
diff --git a/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfAFormFieldTest/cmp_pdfA1DocWithPdfA1ListField.pdf b/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfAFormFieldTest/cmp_pdfA1DocWithPdfA1ListField.pdf
index d7bfead506..abec3ad555 100644
Binary files a/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfAFormFieldTest/cmp_pdfA1DocWithPdfA1ListField.pdf and b/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfAFormFieldTest/cmp_pdfA1DocWithPdfA1ListField.pdf differ
diff --git a/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfAFormFieldTest/cmp_testMultipleCombinationsWriteAndLoad.pdf b/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfAFormFieldTest/cmp_testMultipleCombinationsWriteAndLoad.pdf
index 28535fd9c8..d570819439 100644
Binary files a/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfAFormFieldTest/cmp_testMultipleCombinationsWriteAndLoad.pdf and b/itext.tests/itext.pdfa.tests/resources/itext/pdfa/cmp/PdfAFormFieldTest/cmp_testMultipleCombinationsWriteAndLoad.pdf differ
diff --git a/itext/itext.forms/itext/forms/fields/PdfFormAnnotation.cs b/itext/itext.forms/itext/forms/fields/PdfFormAnnotation.cs
index f3a776f1cd..7ae69cf250 100644
--- a/itext/itext.forms/itext/forms/fields/PdfFormAnnotation.cs
+++ b/itext/itext.forms/itext/forms/fields/PdfFormAnnotation.cs
@@ -805,12 +805,14 @@ protected internal virtual void DrawListFormFieldAndSaveAppearance() {
if (rectangle == null) {
return;
}
+ bool multiselect = parent.GetFieldFlag(PdfChoiceFormField.FF_MULTI_SELECT);
if (!(formFieldElement is ListBoxField)) {
// Create it once and reset properties during each widget regeneration.
- formFieldElement = new ListBoxField("", 0, parent.GetFieldFlag(PdfChoiceFormField.FF_MULTI_SELECT));
+ formFieldElement = new ListBoxField(parent.GetPartialFieldName().ToUnicodeString(), 0, multiselect);
}
- formFieldElement.SetProperty(FormProperty.FORM_FIELD_MULTIPLE, parent.GetFieldFlag(PdfChoiceFormField.FF_MULTI_SELECT
- ));
+ formFieldElement.SetProperty(FormProperty.FORM_FIELD_MULTIPLE, multiselect);
+ ((ListBoxField)formFieldElement).SetTopIndex(parent is PdfChoiceFormField && ((PdfChoiceFormField)parent).
+ GetTopIndex() != null ? ((PdfChoiceFormField)parent).GetTopIndex().IntValue() : 0);
PdfArray indices = GetParent().GetAsArray(PdfName.I);
PdfArray options = parent.GetOptions();
for (int index = 0; index < options.Size(); ++index) {
@@ -835,13 +837,25 @@ protected internal virtual void DrawListFormFieldAndSaveAppearance() {
bool selected = indices != null && indices.Contains(new PdfNumber(index));
SelectFieldItem existingItem = ((ListBoxField)formFieldElement).GetOption(exportValue);
if (existingItem == null) {
- existingItem = new SelectFieldItem(exportValue, displayValue);
+ existingItem = displayValue == null ? new SelectFieldItem(exportValue) : new SelectFieldItem(exportValue,
+ displayValue);
((ListBoxField)formFieldElement).AddOption(existingItem);
}
existingItem.GetElement().SetProperty(Property.TEXT_ALIGNMENT, parent.GetJustification());
existingItem.GetElement().SetProperty(Property.OVERFLOW_Y, OverflowPropertyValue.VISIBLE);
existingItem.GetElement().SetProperty(Property.OVERFLOW_X, OverflowPropertyValue.VISIBLE);
existingItem.GetElement().SetProperty(FormProperty.FORM_FIELD_SELECTED, selected);
+ // Workaround for com.itextpdf.forms.form.renderer.SelectFieldListBoxRenderer.applySelectedStyle:
+ // in HTML rendering mode we want to draw gray background for flattened fields and blue one for interactive,
+ // but here we temporarily flatten formFieldElement, so blue background property is explicitly set to
+ // the selected item. We also need to clear background property for not selected items in case field
+ // is regenerated with modified indices list.
+ if (selected && (multiselect || index == indices.GetAsNumber(indices.Size() - 1).IntValue())) {
+ existingItem.GetElement().SetProperty(Property.BACKGROUND, new Background(new DeviceRgb(169, 204, 225)));
+ }
+ else {
+ existingItem.GetElement().SetProperty(Property.BACKGROUND, null);
+ }
}
formFieldElement.SetProperty(Property.FONT, GetFont());
if (GetColor() != null) {
@@ -876,9 +890,18 @@ protected internal virtual void DrawTextFormFieldAndSaveAppearance() {
formFieldElement.SetProperty(Property.FONT_SIZE, UnitValue.CreatePointValue(GetFontSize()));
}
else {
- formFieldElement.SetProperty(Property.FONT_SIZE, UnitValue.CreatePointValue(GetFontSize(new PdfArray(rectangle
- ), parent.GetValueAsString())));
+ float fontSize = GetFontSize(new PdfArray(rectangle), parent.GetValueAsString());
+ if (fontSize != 0) {
+ // We want to always draw the text using the given font size even if it's not fit into layout area.
+ // Without setting this property the height of the drawn field will be 0 which is unexpected.
+ formFieldElement.SetProperty(Property.FORCED_PLACEMENT, true);
+ }
+ formFieldElement.SetProperty(Property.FONT_SIZE, UnitValue.CreatePointValue(fontSize));
value = iText.Commons.Utils.StringUtil.ReplaceAll(value, LINE_ENDINGS_REGEXP, " ");
+ ((InputField)formFieldElement).SetComb(this.IsCombTextFormField());
+ ((InputField)formFieldElement).SetMaxLen((parent is PdfTextFormField ? (PdfTextFormField)parent : PdfFormCreator
+ .CreateTextFormField(parent.GetPdfObject())).GetMaxLen());
+ ((InputField)formFieldElement).UseAsPassword(parent.IsPassword());
}
formFieldElement.SetValue(value);
formFieldElement.SetProperty(Property.FONT, GetFont());
@@ -913,7 +936,7 @@ protected internal virtual void DrawComboBoxAndSaveAppearance() {
return;
}
if (!(formFieldElement is ComboBoxField)) {
- formFieldElement = new ComboBoxField("");
+ formFieldElement = new ComboBoxField(parent.GetPartialFieldName().ToUnicodeString());
}
ComboBoxField comboBoxField = (ComboBoxField)formFieldElement;
PrepareComboBoxFieldWithCorrectOptionsAndValues(comboBoxField);
@@ -1035,49 +1058,38 @@ internal virtual bool RegenerateWidget() {
}
PdfName type = parent.GetFormType();
RetrieveStyles();
- if ((PdfName.Ch.Equals(type) && parent.GetFieldFlag(PdfChoiceFormField.FF_COMBO)) || this.IsCombTextFormField
- ()) {
- if (parent.GetFieldFlag(PdfChoiceFormField.FF_COMBO) && formFieldElement != null) {
+ if (PdfName.Ch.Equals(type)) {
+ if (parent.GetFieldFlag(PdfChoiceFormField.FF_COMBO)) {
DrawComboBoxAndSaveAppearance();
return true;
}
- return TextAndChoiceLegacyDrawer.RegenerateTextAndChoiceField(this);
+ DrawListFormFieldAndSaveAppearance();
+ return true;
}
else {
- if (PdfName.Ch.Equals(type) && !parent.GetFieldFlag(PdfChoiceFormField.FF_COMBO)) {
- if (formFieldElement != null) {
- DrawListFormFieldAndSaveAppearance();
- return true;
- }
- else {
- return TextAndChoiceLegacyDrawer.RegenerateTextAndChoiceField(this);
- }
+ if (PdfName.Tx.Equals(type)) {
+ DrawTextFormFieldAndSaveAppearance();
+ return true;
}
else {
- if (PdfName.Tx.Equals(type)) {
- DrawTextFormFieldAndSaveAppearance();
- return true;
- }
- else {
- if (PdfName.Btn.Equals(type)) {
- if (parent.GetFieldFlag(PdfButtonFormField.FF_PUSH_BUTTON)) {
- DrawPushButtonFieldAndSaveAppearance();
+ if (PdfName.Btn.Equals(type)) {
+ if (parent.GetFieldFlag(PdfButtonFormField.FF_PUSH_BUTTON)) {
+ DrawPushButtonFieldAndSaveAppearance();
+ }
+ else {
+ if (parent.GetFieldFlag(PdfButtonFormField.FF_RADIO)) {
+ DrawRadioButtonAndSaveAppearance(GetRadioButtonValue());
}
else {
- if (parent.GetFieldFlag(PdfButtonFormField.FF_RADIO)) {
- DrawRadioButtonAndSaveAppearance(GetRadioButtonValue());
- }
- else {
- DrawCheckBoxAndSaveAppearance(GetCheckBoxValue());
- }
+ DrawCheckBoxAndSaveAppearance(GetCheckBoxValue());
}
- return true;
}
- else {
- if (PdfName.Sig.Equals(type)) {
- DrawSignatureFormFieldAndSaveAppearance();
- return true;
- }
+ return true;
+ }
+ else {
+ if (PdfName.Sig.Equals(type)) {
+ DrawSignatureFormFieldAndSaveAppearance();
+ return true;
}
}
}
@@ -1166,14 +1178,17 @@ internal virtual float GetFontSize(PdfArray bBox, String value) {
private bool IsCombTextFormField() {
PdfName type = parent.GetFormType();
- if (PdfName.Tx.Equals(type) && parent.GetFieldFlag(PdfTextFormField.FF_COMB)) {
- int maxLen = PdfFormCreator.CreateTextFormField(parent.GetPdfObject()).GetMaxLen();
- if (maxLen == 0 || parent.IsMultiline()) {
- LOGGER.LogError(MessageFormatUtil.Format(iText.IO.Logs.IoLogMessageConstant.COMB_FLAG_MAY_BE_SET_ONLY_IF_MAXLEN_IS_PRESENT
- ));
- return false;
+ if (PdfName.Tx.Equals(type)) {
+ PdfTextFormField textField = parent is PdfTextFormField ? (PdfTextFormField)parent : PdfFormCreator.CreateTextFormField
+ (parent.GetPdfObject());
+ if (textField.IsComb()) {
+ if (textField.GetMaxLen() == 0 || textField.IsMultiline() || textField.IsPassword() || textField.IsFileSelect
+ ()) {
+ LOGGER.LogError(iText.IO.Logs.IoLogMessageConstant.COMB_FLAG_MAY_BE_SET_ONLY_IF_MAXLEN_IS_PRESENT);
+ return false;
+ }
+ return true;
}
- return true;
}
return false;
}
diff --git a/itext/itext.forms/itext/forms/fields/PdfTextFormField.cs b/itext/itext.forms/itext/forms/fields/PdfTextFormField.cs
index 0864d0c907..bec270b2c3 100644
--- a/itext/itext.forms/itext/forms/fields/PdfTextFormField.cs
+++ b/itext/itext.forms/itext/forms/fields/PdfTextFormField.cs
@@ -202,7 +202,13 @@ public virtual iText.Forms.Fields.PdfTextFormField SetScroll(bool scroll) {
/// If true, the field is automatically divided into as many equally spaced positions,
/// or combs, as the value of MaxLen, and the text is laid out into those combs.
///
- /// whether or not combing is enabled
+ ///
+ ///
+ ///
+ /// if combing is enabled,
+ ///
+ /// otherwise
+ ///
public virtual bool IsComb() {
return GetFieldFlag(FF_COMB);
}
diff --git a/itext/itext.forms/itext/forms/fields/TextAndChoiceLegacyDrawer.cs b/itext/itext.forms/itext/forms/fields/TextAndChoiceLegacyDrawer.cs
deleted file mode 100644
index ef7eb03e18..0000000000
--- a/itext/itext.forms/itext/forms/fields/TextAndChoiceLegacyDrawer.cs
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
-This file is part of the iText (R) project.
-Copyright (c) 1998-2024 Apryse Group NV
-Authors: Apryse Software.
-
-This program is offered under a commercial and under the AGPL license.
-For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
-
-AGPL licensing:
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with this program. If not, see .
-*/
-using System;
-using System.Collections.Generic;
-using Microsoft.Extensions.Logging;
-using iText.Commons;
-using iText.Forms.Logs;
-using iText.Kernel.Colors;
-using iText.Kernel.Font;
-using iText.Kernel.Geom;
-using iText.Kernel.Pdf;
-using iText.Kernel.Pdf.Annot;
-using iText.Kernel.Pdf.Canvas;
-using iText.Kernel.Pdf.Xobject;
-using iText.Layout;
-using iText.Layout.Element;
-using iText.Layout.Properties;
-
-namespace iText.Forms.Fields {
-//\cond DO_NOT_DOCUMENT
- internal sealed class TextAndChoiceLegacyDrawer {
- private static readonly ILogger LOGGER = ITextLogManager.GetLogger(typeof(iText.Forms.Fields.TextAndChoiceLegacyDrawer
- ));
-
- private TextAndChoiceLegacyDrawer() {
- }
-
-//\cond DO_NOT_DOCUMENT
- //Empty constructor.
- internal static bool RegenerateTextAndChoiceField(PdfFormAnnotation formAnnotation) {
- String value = formAnnotation.parent.GetDisplayValue();
- PdfName type = formAnnotation.parent.GetFormType();
- PdfPage page = PdfAnnotation.MakeAnnotation(formAnnotation.GetPdfObject()).GetPage();
- PdfArray bBox = formAnnotation.GetPdfObject().GetAsArray(PdfName.Rect);
- //Apply Page rotation
- int pageRotation = 0;
- if (page != null) {
- pageRotation = page.GetRotation();
- //Clockwise, so negative
- pageRotation *= -1;
- }
- PdfArray matrix;
- if (pageRotation % 90 == 0) {
- //Cast angle to [-360, 360]
- double angle = pageRotation % 360;
- //Get angle in radians
- angle = DegreeToRadians(angle);
- Rectangle initialBboxRectangle = bBox.ToRectangle();
- //rotate the bounding box
- Rectangle rect = initialBboxRectangle.Clone();
- //Calculate origin offset
- double translationWidth = 0;
- double translationHeight = 0;
- if (angle >= -1 * Math.PI && angle <= -1 * Math.PI / 2) {
- translationWidth = rect.GetWidth();
- }
- if (angle <= -1 * Math.PI) {
- translationHeight = rect.GetHeight();
- }
- //Store rotation and translation in the matrix
- matrix = new PdfArray(new double[] { Math.Cos(angle), -Math.Sin(angle), Math.Sin(angle), Math.Cos(angle),
- translationWidth, translationHeight });
- // If the angle is a multiple of 90 and not a multiple of 180, height and width of the bounding box
- // need to be switched
- if (angle % (Math.PI / 2) == 0 && angle % (Math.PI) != 0) {
- rect.SetWidth(initialBboxRectangle.GetHeight());
- rect.SetHeight(initialBboxRectangle.GetWidth());
- }
- // Adapt origin
- rect.SetX(rect.GetX() + (float)translationWidth);
- rect.SetY(rect.GetY() + (float)translationHeight);
- //Copy Bounding box
- bBox = new PdfArray(rect);
- }
- else {
- //Avoid NPE when handling corrupt pdfs
- LOGGER.LogError(FormsLogMessageConstants.INCORRECT_PAGE_ROTATION);
- matrix = new PdfArray(new double[] { 1, 0, 0, 1, 0, 0 });
- }
- //Apply field rotation
- float fieldRotation = 0;
- if (formAnnotation.GetPdfObject().GetAsDictionary(PdfName.MK) != null && formAnnotation.GetPdfObject().GetAsDictionary
- (PdfName.MK).Get(PdfName.R) != null) {
- fieldRotation = (float)formAnnotation.GetPdfObject().GetAsDictionary(PdfName.MK).GetAsFloat(PdfName.R);
- //Get relative field rotation
- fieldRotation += pageRotation;
- }
- if (fieldRotation % 90 == 0) {
- Rectangle initialBboxRectangle = bBox.ToRectangle();
- //Cast angle to [-360, 360]
- double angle = fieldRotation % 360;
- //Get angle in radians
- angle = DegreeToRadians(angle);
- //Calculate origin offset
- double translationWidth = CalculateTranslationWidthAfterFieldRot(initialBboxRectangle, DegreeToRadians(pageRotation
- ), angle);
- double translationHeight = CalculateTranslationHeightAfterFieldRot(initialBboxRectangle, DegreeToRadians(pageRotation
- ), angle);
- //Concatenate rotation and translation into the matrix
- Matrix currentMatrix = new Matrix(matrix.GetAsNumber(0).FloatValue(), matrix.GetAsNumber(1).FloatValue(),
- matrix.GetAsNumber(2).FloatValue(), matrix.GetAsNumber(3).FloatValue(), matrix.GetAsNumber(4).FloatValue
- (), matrix.GetAsNumber(5).FloatValue());
- Matrix toConcatenate = new Matrix((float)Math.Cos(angle), (float)(-Math.Sin(angle)), (float)(Math.Sin(angle
- )), (float)(Math.Cos(angle)), (float)translationWidth, (float)translationHeight);
- currentMatrix = currentMatrix.Multiply(toConcatenate);
- matrix = new PdfArray(new float[] { currentMatrix.Get(0), currentMatrix.Get(1), currentMatrix.Get(3), currentMatrix
- .Get(4), currentMatrix.Get(6), currentMatrix.Get(7) });
- // Construct bounding box
- Rectangle rect = initialBboxRectangle.Clone();
- // If the angle is a multiple of 90 and not a multiple of 180, height and width of the bounding box
- // need to be switched
- if (angle % (Math.PI / 2) == 0 && angle % (Math.PI) != 0) {
- rect.SetWidth(initialBboxRectangle.GetHeight());
- rect.SetHeight(initialBboxRectangle.GetWidth());
- }
- rect.SetX(rect.GetX() + (float)translationWidth);
- rect.SetY(rect.GetY() + (float)translationHeight);
- // Copy Bounding box
- bBox = new PdfArray(rect);
- }
- // Create appearance
- Rectangle bboxRectangle = bBox.ToRectangle();
- PdfFormXObject appearance = new PdfFormXObject(new Rectangle(0, 0, bboxRectangle.GetWidth(), bboxRectangle
- .GetHeight()));
- appearance.Put(PdfName.Matrix, matrix);
- //Create text appearance
- if (PdfName.Tx.Equals(type)) {
- DrawCombTextAppearance(formAnnotation, bboxRectangle, formAnnotation.GetFont(), formAnnotation.GetFontSize
- (bBox, value), value, appearance);
- }
- else {
- int topIndex = 0;
- if (!formAnnotation.parent.GetFieldFlag(PdfChoiceFormField.FF_COMBO)) {
- PdfNumber topIndexNum = formAnnotation.GetParent().GetAsNumber(PdfName.TI);
- PdfArray options = formAnnotation.parent.GetOptions();
- if (null != options) {
- topIndex = null != topIndexNum ? topIndexNum.IntValue() : 0;
- PdfArray visibleOptions = topIndex > 0 ? new PdfArray(options.SubList(topIndex, options.Size())) : (PdfArray
- )options.Clone();
- value = PdfFormField.OptionsArrayToString(visibleOptions);
- }
- }
- DrawChoiceAppearance(formAnnotation, bboxRectangle, formAnnotation.GetFontSize(bBox, value), value, appearance
- , topIndex);
- }
- PdfDictionary ap = new PdfDictionary();
- ap.Put(PdfName.N, appearance.GetPdfObject());
- ap.SetModified();
- formAnnotation.Put(PdfName.AP, ap);
- return true;
- }
-//\endcond
-
-//\cond DO_NOT_DOCUMENT
- internal static void DrawChoiceAppearance(PdfFormAnnotation formAnnotation, Rectangle rect, float fontSize
- , String value, PdfFormXObject appearance, int topIndex) {
- PdfStream stream = (PdfStream)new PdfStream().MakeIndirect(formAnnotation.GetDocument());
- PdfResources resources = appearance.GetResources();
- PdfCanvas canvas = new PdfCanvas(stream, resources, formAnnotation.GetDocument());
- float width = rect.GetWidth();
- float height = rect.GetHeight();
- float widthBorder = 6.0f;
- float heightBorder = 2.0f;
- formAnnotation.DrawBorder(canvas, appearance, width, height);
- canvas.BeginVariableText().SaveState().Rectangle(3, 3, width - widthBorder, height - heightBorder).Clip().
- EndPath();
- iText.Layout.Canvas modelCanvas = new iText.Layout.Canvas(canvas, new Rectangle(3, 0, Math.Max(0, width -
- widthBorder), Math.Max(0, height - heightBorder)));
- modelCanvas.SetProperty(Property.APPEARANCE_STREAM_LAYOUT, true);
- PdfFormAnnotation.SetMetaInfoToCanvas(modelCanvas);
- Div div = new Div();
- if (formAnnotation.parent.GetFieldFlag(PdfChoiceFormField.FF_COMBO)) {
- div.SetVerticalAlignment(VerticalAlignment.MIDDLE);
- }
- div.SetHeight(Math.Max(0, height - heightBorder));
- IList strings = formAnnotation.GetFont().SplitString(value, fontSize, width - widthBorder);
- for (int index = 0; index < strings.Count; index++) {
- bool? isFull = modelCanvas.GetRenderer().GetPropertyAsBoolean(Property.FULL);
- if (true.Equals(isFull)) {
- break;
- }
- Paragraph paragraph = new Paragraph(strings[index]).SetFont(formAnnotation.GetFont()).SetFontSize(fontSize
- ).SetMargins(0, 0, 0, 0).SetMultipliedLeading(1);
- paragraph.SetProperty(Property.FORCED_PLACEMENT, true);
- paragraph.SetTextAlignment(formAnnotation.parent.GetJustification());
- if (formAnnotation.GetColor() != null) {
- paragraph.SetFontColor(formAnnotation.GetColor());
- }
- if (!formAnnotation.parent.GetFieldFlag(PdfChoiceFormField.FF_COMBO)) {
- PdfArray indices = formAnnotation.GetParent().GetAsArray(PdfName.I);
- if (indices != null && indices.Size() > 0) {
- foreach (PdfObject ind in indices) {
- if (!ind.IsNumber()) {
- continue;
- }
- if (((PdfNumber)ind).GetValue() == index + topIndex) {
- paragraph.SetBackgroundColor(new DeviceRgb(10, 36, 106));
- paragraph.SetFontColor(ColorConstants.LIGHT_GRAY);
- }
- }
- }
- }
- div.Add(paragraph);
- }
- modelCanvas.Add(div);
- canvas.RestoreState().EndVariableText();
- appearance.GetPdfObject().SetData(stream.GetBytes());
- }
-//\endcond
-
- private static void DrawCombTextAppearance(PdfFormAnnotation formAnnotation, Rectangle rect, PdfFont font,
- float fontSize, String value, PdfFormXObject appearance) {
- PdfStream stream = (PdfStream)new PdfStream().MakeIndirect(formAnnotation.GetDocument());
- PdfResources resources = appearance.GetResources();
- PdfCanvas canvas = new PdfCanvas(stream, resources, formAnnotation.GetDocument());
- float height = rect.GetHeight();
- float width = rect.GetWidth();
- PdfFormXObject xObject = new PdfFormXObject(new Rectangle(0, 0, width, height));
- formAnnotation.DrawBorder(canvas, xObject, width, height);
- if (formAnnotation.parent.IsPassword()) {
- value = ObfuscatePassword(value);
- }
- canvas.BeginVariableText().SaveState().EndPath();
- iText.Layout.Canvas modelCanvas = new iText.Layout.Canvas(canvas, new Rectangle(0, -height, 0, 2 * height)
- );
- modelCanvas.SetProperty(Property.APPEARANCE_STREAM_LAYOUT, true);
- PdfFormAnnotation.SetMetaInfoToCanvas(modelCanvas);
- Style paragraphStyle = new Style().SetFont(font).SetFontSize(fontSize);
- paragraphStyle.SetProperty(Property.LEADING, new Leading(Leading.MULTIPLIED, 1));
- if (formAnnotation.GetColor() != null) {
- paragraphStyle.SetProperty(Property.FONT_COLOR, new TransparentColor(formAnnotation.GetColor()));
- }
- int maxLen = PdfFormCreator.CreateTextFormField(formAnnotation.parent.GetPdfObject()).GetMaxLen();
- // check if /Comb has been set
- float widthPerCharacter = width / maxLen;
- int numberOfCharacters = Math.Min(maxLen, value.Length);
- int start;
- TextAlignment? textAlignment = formAnnotation.parent.GetJustification() == null ? TextAlignment.LEFT : formAnnotation
- .parent.GetJustification();
- switch (textAlignment) {
- case TextAlignment.RIGHT: {
- start = (maxLen - numberOfCharacters);
- break;
- }
-
- case TextAlignment.CENTER: {
- start = (maxLen - numberOfCharacters) / 2;
- break;
- }
-
- default: {
- start = 0;
- break;
- }
- }
- float startOffset = widthPerCharacter * (start + 0.5f);
- for (int i = 0; i < numberOfCharacters; i++) {
- modelCanvas.ShowTextAligned(new Paragraph(value.JSubstring(i, i + 1)).AddStyle(paragraphStyle), startOffset
- + widthPerCharacter * i, rect.GetHeight() / 2, TextAlignment.CENTER, VerticalAlignment.MIDDLE);
- }
- canvas.RestoreState().EndVariableText();
- appearance.GetPdfObject().SetData(stream.GetBytes());
- }
-
- private static String ObfuscatePassword(String text) {
- char[] pchar = new char[text.Length];
- for (int i = 0; i < text.Length; i++) {
- pchar[i] = '*';
- }
- return new String(pchar);
- }
-
- private static float CalculateTranslationHeightAfterFieldRot(Rectangle bBox, double pageRotation, double relFieldRotation
- ) {
- if (relFieldRotation == 0) {
- return 0.0f;
- }
- if (pageRotation == 0) {
- if (relFieldRotation == Math.PI / 2) {
- return bBox.GetHeight();
- }
- if (relFieldRotation == Math.PI) {
- return bBox.GetHeight();
- }
- }
- if (pageRotation == -Math.PI / 2) {
- if (relFieldRotation == -Math.PI / 2) {
- return bBox.GetWidth() - bBox.GetHeight();
- }
- if (relFieldRotation == Math.PI / 2) {
- return bBox.GetHeight();
- }
- if (relFieldRotation == Math.PI) {
- return bBox.GetWidth();
- }
- }
- if (pageRotation == -Math.PI) {
- if (relFieldRotation == -1 * Math.PI) {
- return bBox.GetHeight();
- }
- if (relFieldRotation == -1 * Math.PI / 2) {
- return bBox.GetHeight() - bBox.GetWidth();
- }
- if (relFieldRotation == Math.PI / 2) {
- return bBox.GetWidth();
- }
- }
- if (pageRotation == -3 * Math.PI / 2) {
- if (relFieldRotation == -3 * Math.PI / 2) {
- return bBox.GetWidth();
- }
- if (relFieldRotation == -Math.PI) {
- return bBox.GetWidth();
- }
- }
- return 0.0f;
- }
-
- private static float CalculateTranslationWidthAfterFieldRot(Rectangle bBox, double pageRotation, double relFieldRotation
- ) {
- if (relFieldRotation == 0) {
- return 0.0f;
- }
- if (pageRotation == 0 && (relFieldRotation == Math.PI || relFieldRotation == 3 * Math.PI / 2)) {
- return bBox.GetWidth();
- }
- if (pageRotation == -Math.PI / 2) {
- if (relFieldRotation == -Math.PI / 2 || relFieldRotation == Math.PI) {
- return bBox.GetHeight();
- }
- }
- if (pageRotation == -Math.PI) {
- if (relFieldRotation == -1 * Math.PI) {
- return bBox.GetWidth();
- }
- if (relFieldRotation == -1 * Math.PI / 2) {
- return bBox.GetHeight();
- }
- if (relFieldRotation == Math.PI / 2) {
- return -1 * (bBox.GetHeight() - bBox.GetWidth());
- }
- }
- if (pageRotation == -3 * Math.PI / 2) {
- if (relFieldRotation == -3 * Math.PI / 2) {
- return -1 * (bBox.GetWidth() - bBox.GetHeight());
- }
- if (relFieldRotation == -Math.PI) {
- return bBox.GetHeight();
- }
- if (relFieldRotation == -Math.PI / 2) {
- return bBox.GetWidth();
- }
- }
- return 0.0f;
- }
-
- private static double DegreeToRadians(double angle) {
- return Math.PI * angle / 180.0;
- }
- }
-//\endcond
-}
diff --git a/itext/itext.forms/itext/forms/form/FormProperty.cs b/itext/itext.forms/itext/forms/form/FormProperty.cs
index 6475407782..01cab91ed1 100644
--- a/itext/itext.forms/itext/forms/form/FormProperty.cs
+++ b/itext/itext.forms/itext/forms/form/FormProperty.cs
@@ -68,6 +68,21 @@ public sealed class FormProperty {
/// The Constant FORM_CONFORMANCE_LEVEL.
public const int FORM_CONFORMANCE_LEVEL = PROPERTY_START + 15;
+ /// The Constant LIST_BOX_TOP_INDEX representing the index of the first visible option in a scrollable list.
+ ///
+ public const int LIST_BOX_TOP_INDEX = PROPERTY_START + 16;
+
+ ///
+ /// The Constant TEXT_FIELD_COMB_FLAG representing
+ /// Comb
+ /// flag for the text field.
+ ///
+ public const int TEXT_FIELD_COMB_FLAG = PROPERTY_START + 17;
+
+ /// The Constant TEXT_FIELD_MAX_LEN representing the maximum length of the field's text, in characters.
+ ///
+ public const int TEXT_FIELD_MAX_LEN = PROPERTY_START + 18;
+
private FormProperty() {
}
// Empty constructor.
diff --git a/itext/itext.forms/itext/forms/form/element/InputField.cs b/itext/itext.forms/itext/forms/form/element/InputField.cs
index aa11303e0d..58ca5e557d 100644
--- a/itext/itext.forms/itext/forms/form/element/InputField.cs
+++ b/itext/itext.forms/itext/forms/form/element/InputField.cs
@@ -101,6 +101,14 @@ public override T1 GetDefaultProperty(int property) {
return (T1)(Object)20;
}
+ case FormProperty.TEXT_FIELD_COMB_FLAG: {
+ return (T1)(Object)false;
+ }
+
+ case FormProperty.TEXT_FIELD_MAX_LEN: {
+ return (T1)(Object)0;
+ }
+
default: {
return base.GetDefaultProperty(property);
}
@@ -117,11 +125,11 @@ public virtual int GetRotation() {
///
/// new rotation value, counterclockwise. Must be a multiple of 90 degrees.
/// It has sense only in interactive mode, see
- /// .
+ ///
///
///
/// the edited
- /// .
+ ///
///
public virtual iText.Forms.Form.Element.InputField SetRotation(int rotation) {
if (rotation % 90 != 0) {
@@ -131,6 +139,43 @@ public virtual iText.Forms.Form.Element.InputField SetRotation(int rotation) {
return this;
}
+ ///
+ /// Sets
+ /// Comb
+ /// flag for the text field.
+ ///
+ ///
+ /// Sets
+ /// Comb
+ /// flag for the text field. Meaningful only if the MaxLen entry is present in the text field
+ /// dictionary and if the Multiline, Password and FileSelect flags are clear.
+ ///
+ /// If true, the field is automatically divided into as many equally spaced positions, or combs,
+ /// as the value of MaxLen, and the text is laid out into those combs.
+ ///
+ /// boolean value specifying whether to enable combing
+ ///
+ /// this
+ ///
+ /// instance
+ ///
+ public virtual iText.Forms.Form.Element.InputField SetComb(bool isComb) {
+ SetProperty(FormProperty.TEXT_FIELD_COMB_FLAG, isComb);
+ return this;
+ }
+
+ /// Sets the maximum length of the field's text, in characters.
+ /// the current maximum text length
+ ///
+ /// this
+ ///
+ /// instance
+ ///
+ public virtual iText.Forms.Form.Element.InputField SetMaxLen(int maxLen) {
+ SetProperty(FormProperty.TEXT_FIELD_MAX_LEN, maxLen);
+ return this;
+ }
+
///
public override AccessibilityProperties GetAccessibilityProperties() {
if (tagProperties == null) {
diff --git a/itext/itext.forms/itext/forms/form/element/ListBoxField.cs b/itext/itext.forms/itext/forms/form/element/ListBoxField.cs
index 8de203c23c..691f4377f7 100644
--- a/itext/itext.forms/itext/forms/form/element/ListBoxField.cs
+++ b/itext/itext.forms/itext/forms/form/element/ListBoxField.cs
@@ -68,6 +68,10 @@ public override T1 GetDefaultProperty(int property) {
return (T1)(Object)4;
}
+ case FormProperty.LIST_BOX_TOP_INDEX: {
+ return (T1)(Object)0;
+ }
+
default: {
return base.GetDefaultProperty(property);
}
@@ -127,6 +131,18 @@ public virtual IList GetSelectedStrings() {
return selectedStrings;
}
+ /// Sets the index of the first visible option in a scrollable list.
+ /// the index of the first option
+ ///
+ /// this
+ ///
+ /// instance
+ ///
+ public virtual iText.Forms.Form.Element.ListBoxField SetTopIndex(int topIndex) {
+ SetProperty(FormProperty.LIST_BOX_TOP_INDEX, topIndex);
+ return this;
+ }
+
///
public override AccessibilityProperties GetAccessibilityProperties() {
if (tagProperties == null) {
diff --git a/itext/itext.forms/itext/forms/form/element/TextArea.cs b/itext/itext.forms/itext/forms/form/element/TextArea.cs
index d932492c75..62613bf043 100644
--- a/itext/itext.forms/itext/forms/form/element/TextArea.cs
+++ b/itext/itext.forms/itext/forms/form/element/TextArea.cs
@@ -56,27 +56,6 @@ public TextArea(String id)
SetProperties();
}
- /// Determines, whether the input field will be password.
- ///
- /// Determines, whether the input field will be password.
- ///
- /// Usually means that instead of glyphs '*' will be shown in case of flatten field.
- ///
- /// If the field is not flatten, value will be ignored.
- ///
- ///
- ///
- ///
- /// is this field shall be considered as password,
- ///
- /// otherwise
- ///
- /// this input field
- public virtual iText.Forms.Form.Element.TextArea UseAsPassword(bool isPassword) {
- SetProperty(FormProperty.FORM_FIELD_PASSWORD_FLAG, isPassword);
- return this;
- }
-
/* (non-Javadoc)
* @see FormField#getDefaultProperty(int)
*/
diff --git a/itext/itext.forms/itext/forms/form/renderer/AbstractSelectFieldRenderer.cs b/itext/itext.forms/itext/forms/form/renderer/AbstractSelectFieldRenderer.cs
index 43ca315178..6fc959a791 100644
--- a/itext/itext.forms/itext/forms/form/renderer/AbstractSelectFieldRenderer.cs
+++ b/itext/itext.forms/itext/forms/form/renderer/AbstractSelectFieldRenderer.cs
@@ -49,11 +49,12 @@ public abstract class AbstractSelectFieldRenderer : BlockRenderer {
/// the model element
protected internal AbstractSelectFieldRenderer(AbstractSelectField modelElement)
: base(modelElement) {
- AddChild(CreateFlatRenderer());
}
///
public override LayoutResult Layout(LayoutContext layoutContext) {
+ childRenderers.Clear();
+ AddChild(CreateFlatRenderer());
// Resolve width here in case it's relative, while parent width is still intact.
// If it's inline-block context, relative width is already resolved.
float? width = RetrieveWidth(layoutContext.GetArea().GetBBox().GetWidth());
diff --git a/itext/itext.forms/itext/forms/form/renderer/InputFieldRenderer.cs b/itext/itext.forms/itext/forms/form/renderer/InputFieldRenderer.cs
index e87abe8caf..d354ee7458 100644
--- a/itext/itext.forms/itext/forms/form/renderer/InputFieldRenderer.cs
+++ b/itext/itext.forms/itext/forms/form/renderer/InputFieldRenderer.cs
@@ -33,6 +33,7 @@ You should have received a copy of the GNU Affero General Public License
using iText.Forms.Util;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
+using iText.Layout.Element;
using iText.Layout.Font;
using iText.Layout.Layout;
using iText.Layout.Minmaxwidth;
@@ -46,6 +47,8 @@ namespace iText.Forms.Form.Renderer {
/// implementation for input fields.
///
public class InputFieldRenderer : AbstractOneLineTextFieldRenderer {
+ private const float DEFAULT_COMB_PADDING = 0;
+
///
/// Creates a new
///
@@ -83,7 +86,52 @@ internal override IRenderer CreateParagraphRenderer(String defaultValue) {
)modelElement).GetPlaceholder().IsEmpty()) {
return ((InputField)modelElement).GetPlaceholder().CreateRendererSubTree();
}
- IRenderer flatRenderer = base.CreateParagraphRenderer(defaultValue);
+ if (String.IsNullOrEmpty(defaultValue)) {
+ defaultValue = "\u00a0";
+ }
+ IRenderer flatRenderer;
+ if (IsComb()) {
+ SetProperty(Property.PADDING_LEFT, UnitValue.CreatePointValue(DEFAULT_COMB_PADDING));
+ SetProperty(Property.PADDING_RIGHT, UnitValue.CreatePointValue(DEFAULT_COMB_PADDING));
+ int maxLen = GetMaxLen();
+ int numberOfCharacters = Math.Min(maxLen, defaultValue.Length);
+ int start;
+ TextAlignment? textAlignment = this.GetProperty(Property.TEXT_ALIGNMENT, TextAlignment.LEFT
+ );
+ switch (textAlignment) {
+ case TextAlignment.RIGHT: {
+ start = (maxLen - numberOfCharacters);
+ break;
+ }
+
+ case TextAlignment.CENTER: {
+ start = (maxLen - numberOfCharacters) / 2;
+ break;
+ }
+
+ default: {
+ start = 0;
+ break;
+ }
+ }
+ Paragraph paragraph = new Paragraph();
+ for (int i = 0; i < start; i++) {
+ paragraph.Add(GetSubParagraph("", maxLen));
+ }
+ for (int i = 0; i < numberOfCharacters; i++) {
+ paragraph.Add(GetSubParagraph(defaultValue.JSubstring(i, i + 1), maxLen));
+ }
+ for (int i = start + numberOfCharacters; i < maxLen; i++) {
+ paragraph.Add(GetSubParagraph("", maxLen));
+ }
+ flatRenderer = paragraph.SetMargin(0).CreateRendererSubTree();
+ }
+ else {
+ Text text = new Text(defaultValue);
+ FormFieldValueNonTrimmingTextRenderer nextRenderer = new FormFieldValueNonTrimmingTextRenderer(text);
+ text.SetNextRenderer(nextRenderer);
+ flatRenderer = new Paragraph(text).SetMargin(0).CreateRendererSubTree();
+ }
flatRenderer.SetProperty(Property.NO_SOFT_WRAP_INLINE, true);
return flatRenderer;
}
@@ -144,17 +192,21 @@ protected internal override void ApplyAcroField(DrawContext drawContext) {
// Default html2pdf input field appearance differs from the default one for form fields.
// That's why we got rid of several properties we set by default during InputField instance creation.
modelElement.SetProperty(Property.BOX_SIZING, BoxSizingPropertyValue.BORDER_BOX);
- PdfFormField inputField = new TextFormFieldBuilder(doc, name).SetWidgetRectangle(area).SetFont(font).SetConformance
+ PdfTextFormField inputField = new TextFormFieldBuilder(doc, name).SetWidgetRectangle(area).SetFont(font).SetConformance
(GetConformance(doc)).CreateText();
inputField.DisableFieldRegeneration();
inputField.SetValue(value);
inputField.SetFontSize(fontSizeValue);
if (password) {
- inputField.SetFieldFlag(PdfFormField.FF_PASSWORD, true);
+ inputField.SetPassword(true);
}
else {
inputField.SetDefaultValue(new PdfString(value));
}
+ if (IsComb()) {
+ inputField.SetComb(true);
+ inputField.SetMaxLen(GetMaxLen());
+ }
int rotation = ((InputField)modelElement).GetRotation();
if (rotation != 0) {
inputField.GetFirstFormAnnotation().SetRotation(rotation);
@@ -213,6 +265,26 @@ protected override bool SetMinMaxWidthBasedOnFixedWidth(MinMaxWidth minMaxWidth)
return result;
}
+ private static Paragraph GetSubParagraph(String value, int maxLen) {
+ Text text = new Text(value);
+ FormFieldValueNonTrimmingTextRenderer nextRenderer = new FormFieldValueNonTrimmingTextRenderer(text);
+ text.SetNextRenderer(nextRenderer);
+ return new Paragraph(text).SetTextAlignment(TextAlignment.CENTER).SetWidth(UnitValue.CreatePercentValue((float
+ )100 / maxLen)).SetHeight(UnitValue.CreatePercentValue(100)).SetMargin(0);
+ }
+
+ /// Checks if the input field is a comb field.
+ /// true, if the input field is a comb field
+ private bool IsComb() {
+ return (bool)this.GetProperty(FormProperty.TEXT_FIELD_COMB_FLAG, false);
+ }
+
+ /// Gets the maximum length of the field's text, in characters.
+ /// the current maximum text length
+ private int GetMaxLen() {
+ return (int)this.GetProperty(FormProperty.TEXT_FIELD_MAX_LEN, 0);
+ }
+
/// Obfuscates the content of a password input field.
/// the password
/// a string consisting of '*' characters.
diff --git a/itext/itext.forms/itext/forms/form/renderer/SelectFieldListBoxRenderer.cs b/itext/itext.forms/itext/forms/form/renderer/SelectFieldListBoxRenderer.cs
index 24d21775f4..157c545c9c 100644
--- a/itext/itext.forms/itext/forms/form/renderer/SelectFieldListBoxRenderer.cs
+++ b/itext/itext.forms/itext/forms/form/renderer/SelectFieldListBoxRenderer.cs
@@ -101,7 +101,9 @@ protected internal override IRenderer CreateFlatRenderer() {
AbstractSelectField selectField = (AbstractSelectField)modelElement;
IList options = selectField.GetOptions();
Div optionsContainer = new Div();
- foreach (SelectFieldItem option in options) {
+ int topIndex = (int)this.GetProperty(FormProperty.LIST_BOX_TOP_INDEX, 0);
+ IList visibleOptions = topIndex > 0 ? options.SubList(topIndex, options.Count) : options;
+ foreach (SelectFieldItem option in visibleOptions) {
optionsContainer.Add(option.GetElement());
}
String lang = GetLang();
@@ -183,6 +185,10 @@ protected internal override void ApplyAcroField(DrawContext drawContext) {
choiceField.SetFontSize(fontSize.GetValue());
choiceField.SetMultiSelect(IsMultiple());
choiceField.SetListSelected(selectedOptions.ToArray(new String[selectedOptions.Count]));
+ int? topIndex = modelElement.GetOwnProperty(FormProperty.LIST_BOX_TOP_INDEX);
+ if (topIndex != null) {
+ choiceField.SetTopIndex((int)topIndex);
+ }
TransparentColor color = GetPropertyAsTransparentColor(Property.FONT_COLOR);
if (color != null) {
choiceField.SetColor(color.GetColor());
@@ -270,7 +276,14 @@ private bool IsMultiple() {
}
private void ApplySelectedStyle(IRenderer selectedOption) {
- selectedOption.SetProperty(Property.BACKGROUND, new Background(new DeviceRgb(0, 120, 215)));
+ RenderingMode? mode = this.GetProperty(Property.RENDERING_MODE);
+ if (RenderingMode.HTML_MODE.Equals(mode) && IsFlatten() && selectedOption.GetProperty(Property
+ .BACKGROUND) == null) {
+ selectedOption.SetProperty(Property.BACKGROUND, new Background(new DeviceRgb(206, 206, 206)));
+ }
+ else {
+ selectedOption.SetProperty(Property.BACKGROUND, new Background(new DeviceRgb(169, 204, 225)));
+ }
SetFontColorRecursively(selectedOption);
}
@@ -280,7 +293,7 @@ private void ApplySelectedStyle(IRenderer selectedOption) {
/// otherwise it will be not applied due to the css resolving mechanism.
///
private void SetFontColorRecursively(IRenderer selectedOption) {
- selectedOption.SetProperty(Property.FONT_COLOR, new TransparentColor(ColorConstants.WHITE));
+ selectedOption.SetProperty(Property.FONT_COLOR, new TransparentColor(ColorConstants.BLACK));
foreach (IRenderer renderer in selectedOption.GetChildRenderers()) {
SetFontColorRecursively(renderer);
}
diff --git a/port-hash b/port-hash
index 38a023f0cb..3bee91861b 100644
--- a/port-hash
+++ b/port-hash
@@ -1 +1 @@
-e3aab4f3d591b970957e3f568ad458ebc0d76578
+a1e83efe10856b980ebc96e01a9dfb89ddeeeee1
\ No newline at end of file