Skip to content

Commit

Permalink
Merge branch 'develop' into devsecops
Browse files Browse the repository at this point in the history
  • Loading branch information
aleks-ivanov committed Apr 16, 2024
2 parents 02d2085 + d7c8fac commit fa2a742
Show file tree
Hide file tree
Showing 24 changed files with 555 additions and 49 deletions.

Large diffs are not rendered by default.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
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 <https://www.gnu.org/licenses/>.
*/
using System;
using iText.Kernel.XMP.Options;
using iText.Test;

namespace iText.Kernel.XMP.Impl
{
[NUnit.Framework.Category("UnitTest")]
public class XMPNodeTest : ExtendedITextTest
{
[NUnit.Framework.Test]
public virtual void XmpNodeTreeUnmodifiableChildrenTest() {
XMPNode node = new XMPNode("rdf:RDF", "idk", new PropertyOptions());
node.AddChild(new XMPNode("rdf:Description", "idk", new PropertyOptions()));
var a = node.GetUnmodifiableChildren().GetEnumerator();
while (a.MoveNext())
{
//Modifying original tree after getting an iterator on unmodifiable collection
//If we wouldn't create a copy of original children we would get System.InvalidOperationException
NUnit.Framework.Assert.DoesNotThrow(() =>
node.AddChild(new XMPNode("rdf:Description1", "idk", new PropertyOptions())));
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -302,41 +302,6 @@ protected internal virtual void WriteAcroFormFieldLangAttribute(PdfDocument pdfD
}
}

/// <summary>Deletes all margin properties.</summary>
/// <remarks>
/// Deletes all margin properties. Used in
/// <c>applyAcroField</c>
/// to not apply margins twice as we already use area
/// with margins applied (margins shouldn't be an interactive part of the field, i.e. included into its occupied
/// area).
/// </remarks>
/// <returns>the map of deleted margins.</returns>
internal virtual IDictionary<int, Object> DeleteMargins() {
IDictionary<int, Object> margins = new Dictionary<int, Object>();
margins.Put(Property.MARGIN_TOP, this.modelElement.GetOwnProperty<UnitValue>(Property.MARGIN_TOP));
margins.Put(Property.MARGIN_BOTTOM, this.modelElement.GetOwnProperty<UnitValue>(Property.MARGIN_BOTTOM));
margins.Put(Property.MARGIN_LEFT, this.modelElement.GetOwnProperty<UnitValue>(Property.MARGIN_LEFT));
margins.Put(Property.MARGIN_RIGHT, this.modelElement.GetOwnProperty<UnitValue>(Property.MARGIN_RIGHT));
modelElement.DeleteOwnProperty(Property.MARGIN_RIGHT);
modelElement.DeleteOwnProperty(Property.MARGIN_LEFT);
modelElement.DeleteOwnProperty(Property.MARGIN_TOP);
modelElement.DeleteOwnProperty(Property.MARGIN_BOTTOM);
return margins;
}

/// <summary>Applies the properties to the model element.</summary>
/// <param name="properties">the properties to apply</param>
internal virtual void ApplyProperties(IDictionary<int, Object> properties) {
foreach (KeyValuePair<int, Object> integerObjectEntry in properties) {
if (integerObjectEntry.Value != null) {
modelElement.SetProperty(integerObjectEntry.Key, integerObjectEntry.Value);
}
else {
modelElement.DeleteOwnProperty(integerObjectEntry.Key);
}
}
}

private void ProcessLangAttribute() {
IPropertyContainer propertyContainer = flatRenderer.GetModelElement();
String lang = GetLang();
Expand Down
5 changes: 3 additions & 2 deletions itext/itext.forms/itext/forms/form/renderer/ButtonRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ You should have received a copy of the GNU Affero General Public License
using iText.Forms.Form;
using iText.Forms.Form.Element;
using iText.Forms.Logs;
using iText.Forms.Util;
using iText.Kernel.Colors;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
Expand Down Expand Up @@ -226,7 +227,7 @@ protected internal override void ApplyAcroField(DrawContext drawContext) {
PdfDocument doc = drawContext.GetDocument();
Rectangle area = GetOccupiedArea().GetBBox().Clone();
ApplyMargins(area, false);
IDictionary<int, Object> margins = DeleteMargins();
IDictionary<int, Object> properties = FormFieldRendererUtil.RemoveProperties(modelElement);
PdfPage page = doc.GetPage(occupiedArea.GetPageNumber());
Background background = this.GetProperty<Background>(Property.BACKGROUND);
// Background is light gray by default, but can be set to null by user.
Expand Down Expand Up @@ -254,7 +255,7 @@ protected internal override void ApplyAcroField(DrawContext drawContext) {
// Fields can be already added on split, e.g. when button split into multiple pages. But now we merge fields
// with the same names (and add all the widgets as kids to that merged field), so we can add it anyway.
forms.AddField(button, page);
ApplyProperties(margins);
FormFieldRendererUtil.ReapplyProperties(modelElement, properties);
}

/// <summary><inheritDoc/></summary>
Expand Down
21 changes: 19 additions & 2 deletions itext/itext.forms/itext/forms/form/renderer/CheckBoxRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,23 @@ protected internal override void AdjustFieldLayout(LayoutContext layoutContext)
}

// We don't need any layout adjustments
/// <summary>Applies given paddings to the given rectangle.</summary>
/// <remarks>
/// Applies given paddings to the given rectangle.
/// Checkboxes don't support setting of paddings as they are always centered.
/// So that this method returns the rectangle as is.
/// </remarks>
/// <param name="rect">a rectangle paddings will be applied on.</param>
/// <param name="paddings">the paddings to be applied on the given rectangle</param>
/// <param name="reverse">
/// indicates whether paddings will be applied
/// inside (in case of false) or outside (in case of true) the rectangle.
/// </param>
/// <returns>The rectangle NOT modified by the paddings.</returns>
protected override Rectangle ApplyPaddings(Rectangle rect, UnitValue[] paddings, bool reverse) {
return rect;
}

/// <summary>Creates a flat renderer for the checkbox.</summary>
/// <returns>an IRenderer object for the flat renderer</returns>
protected internal override IRenderer CreateFlatRenderer() {
Expand Down Expand Up @@ -181,7 +198,7 @@ protected internal override void ApplyAcroField(DrawContext drawContext) {
String name = GetModelId();
PdfDocument doc = drawContext.GetDocument();
Rectangle area = flatRenderer.GetOccupiedArea().GetBBox().Clone();
IDictionary<int, Object> margins = DeleteMargins();
IDictionary<int, Object> properties = FormFieldRendererUtil.RemoveProperties(this.modelElement);
PdfPage page = doc.GetPage(occupiedArea.GetPageNumber());
CheckBoxFormFieldBuilder builder = new CheckBoxFormFieldBuilder(doc, name).SetWidgetRectangle(area).SetGenericConformanceLevel
(this.GetProperty<IConformanceLevel>(FormProperty.FORM_CONFORMANCE_LEVEL));
Expand All @@ -203,7 +220,7 @@ protected internal override void ApplyAcroField(DrawContext drawContext) {
checkBox.GetFirstFormAnnotation().SetFormFieldElement((CheckBox)modelElement);
checkBox.EnableFieldRegeneration();
PdfFormCreator.GetAcroForm(doc, true).AddField(checkBox, page);
ApplyProperties(margins);
FormFieldRendererUtil.ReapplyProperties(modelElement, properties);
}

/// <summary><inheritDoc/></summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ You should have received a copy of the GNU Affero General Public License
using iText.Forms.Form;
using iText.Forms.Form.Element;
using iText.Forms.Logs;
using iText.Forms.Util;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Layout.Font;
Expand Down Expand Up @@ -129,7 +130,7 @@ protected internal override void ApplyAcroField(DrawContext drawContext) {
PdfDocument doc = drawContext.GetDocument();
Rectangle area = this.GetOccupiedArea().GetBBox().Clone();
ApplyMargins(area, false);
IDictionary<int, Object> margins = DeleteMargins();
IDictionary<int, Object> properties = FormFieldRendererUtil.RemoveProperties(this.modelElement);
PdfPage page = doc.GetPage(occupiedArea.GetPageNumber());
float fontSizeValue = fontSize.GetValue();
// Some properties are set to the HtmlDocumentRenderer, which is root renderer for this ButtonRenderer, but
Expand Down Expand Up @@ -161,7 +162,7 @@ protected internal override void ApplyAcroField(DrawContext drawContext) {
inputField.GetFirstFormAnnotation().SetFormFieldElement((InputField)modelElement);
inputField.EnableFieldRegeneration();
PdfFormCreator.GetAcroForm(doc, true).AddField(inputField, page);
ApplyProperties(margins);
FormFieldRendererUtil.ReapplyProperties(modelElement, properties);
}

/// <summary><inheritDoc/></summary>
Expand Down
4 changes: 2 additions & 2 deletions itext/itext.forms/itext/forms/form/renderer/RadioRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ protected internal override void ApplyAcroField(DrawContext drawContext) {
PdfDocument doc = drawContext.GetDocument();
PdfAcroForm form = PdfFormCreator.GetAcroForm(doc, true);
Rectangle area = flatRenderer.GetOccupiedArea().GetBBox().Clone();
IDictionary<int, Object> margins = DeleteMargins();
IDictionary<int, Object> properties = FormFieldRendererUtil.RemoveProperties(this.modelElement);
PdfPage page = doc.GetPage(occupiedArea.GetPageNumber());
String groupName = this.GetProperty<String>(FormProperty.FORM_FIELD_RADIO_GROUP_NAME);
if (groupName == null || String.IsNullOrEmpty(groupName)) {
Expand Down Expand Up @@ -179,7 +179,7 @@ protected internal override void ApplyAcroField(DrawContext drawContext) {
radioGroup.EnableFieldRegeneration();
ApplyAccessibilityProperties(radioGroup, doc);
form.AddField(radioGroup, page);
ApplyProperties(margins);
FormFieldRendererUtil.ReapplyProperties(this.modelElement, properties);
}

/// <summary><inheritDoc/></summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ protected internal override void ApplyAcroField(DrawContext drawContext) {
PdfFont font = GetResolvedFont(doc);
ChoiceFormFieldBuilder builder = new ChoiceFormFieldBuilder(doc, name).SetWidgetRectangle(area).SetFont(font
).SetGenericConformanceLevel(GetGenericConformanceLevel(doc));
ApplyMargins(area, false);
IDictionary<int, Object> properties = FormFieldRendererUtil.RemoveProperties(this.modelElement);
modelElement.SetProperty(Property.FONT_PROVIDER, this.GetProperty<FontProvider>(Property.FONT_PROVIDER));
modelElement.SetProperty(Property.RENDERING_MODE, this.GetProperty<RenderingMode?>(Property.RENDERING_MODE
));
Expand Down Expand Up @@ -132,6 +134,7 @@ protected internal override void ApplyAcroField(DrawContext drawContext) {
comboBoxField.GetFirstFormAnnotation().SetFormFieldElement(comboBoxFieldModelElement);
comboBoxField.EnableFieldRegeneration();
PdfFormCreator.GetAcroForm(doc, true).AddField(comboBoxField, page);
FormFieldRendererUtil.ReapplyProperties(this.modelElement, properties);
}

private UnitValue GetFontSize() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ protected internal override void ApplyAcroField(DrawContext drawContext) {
PdfDocument doc = drawContext.GetDocument();
Rectangle area = this.GetOccupiedArea().GetBBox().Clone();
PdfPage page = doc.GetPage(occupiedArea.GetPageNumber());
ApplyMargins(area, false);
IDictionary<int, Object> properties = FormFieldRendererUtil.RemoveProperties(this.modelElement);
// Some properties are set to the HtmlDocumentRenderer, which is root renderer for this ButtonRenderer, but
// in forms logic root renderer is CanvasRenderer, and these properties will have default values. So
// we get them from renderer and set these properties to model element, which will be passed to forms logic.
Expand Down Expand Up @@ -194,6 +196,7 @@ protected internal override void ApplyAcroField(DrawContext drawContext) {
choiceField.GetFirstFormAnnotation().SetFormFieldElement(lbModelElement);
choiceField.EnableFieldRegeneration();
PdfFormCreator.GetAcroForm(doc, true).AddField(choiceField, page);
FormFieldRendererUtil.ReapplyProperties(this.modelElement, properties);
}

private float GetCalculatedHeight(IRenderer flatRenderer) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ You should have received a copy of the GNU Affero General Public License
using iText.Forms;
using iText.Forms.Fields;
using iText.Forms.Form.Element;
using iText.Forms.Util;
using iText.Kernel.Colors;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
Expand Down Expand Up @@ -106,6 +107,7 @@ protected internal override void AdjustFieldLayout(LayoutContext layoutContext)
Rectangle bBox = GetOccupiedArea().GetBBox().Clone();
ApplyPaddings(bBox, false);
ApplyBorderBox(bBox, false);
ApplyMargins(bBox, false);
if (bBox.GetY() < 0) {
bBox.SetHeight(bBox.GetY() + bBox.GetHeight());
bBox.SetY(0);
Expand Down Expand Up @@ -201,7 +203,7 @@ protected internal override void ApplyAcroField(DrawContext drawContext) {
PdfDocument doc = drawContext.GetDocument();
Rectangle area = GetOccupiedArea().GetBBox().Clone();
ApplyMargins(area, false);
DeleteMargins();
IDictionary<int, Object> properties = FormFieldRendererUtil.RemoveProperties(this.modelElement);
PdfPage page = doc.GetPage(occupiedArea.GetPageNumber());
Background background = this.GetProperty<Background>(Property.BACKGROUND);
// Background is light gray by default, but can be set to null by user.
Expand All @@ -227,6 +229,7 @@ protected internal override void ApplyAcroField(DrawContext drawContext) {
sigField.EnableFieldRegeneration();
PdfAcroForm forms = PdfFormCreator.GetAcroForm(doc, true);
forms.AddField(sigField, page);
FormFieldRendererUtil.ReapplyProperties(modelElement, properties);
}

private void AdjustChildrenLayout(SignatureAppearanceRenderer.RenderingMode renderingMode, Rectangle signatureRect
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ You should have received a copy of the GNU Affero General Public License
using iText.Forms.Form;
using iText.Forms.Form.Element;
using iText.Forms.Logs;
using iText.Forms.Util;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Layout.Layout;
Expand Down Expand Up @@ -157,7 +158,7 @@ protected internal override void ApplyAcroField(DrawContext drawContext) {
PdfDocument doc = drawContext.GetDocument();
Rectangle area = GetOccupiedArea().GetBBox().Clone();
ApplyMargins(area, false);
IDictionary<int, Object> margins = DeleteMargins();
IDictionary<int, Object> properties = FormFieldRendererUtil.RemoveProperties(modelElement);
PdfPage page = doc.GetPage(occupiedArea.GetPageNumber());
float fontSizeValue = fontSize.GetValue();
PdfString defaultValue = new PdfString(GetDefaultValue());
Expand All @@ -175,7 +176,7 @@ protected internal override void ApplyAcroField(DrawContext drawContext) {
inputField.EnableFieldRegeneration();
ApplyAccessibilityProperties(inputField, doc);
PdfFormCreator.GetAcroForm(doc, true).AddField(inputField, page);
ApplyProperties(margins);
FormFieldRendererUtil.ReapplyProperties(modelElement, properties);
}

/// <summary><inheritDoc/></summary>
Expand Down
73 changes: 73 additions & 0 deletions itext/itext.forms/itext/forms/util/FormFieldRendererUtil.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
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 <https://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using iText.Layout;
using iText.Layout.Properties;

namespace iText.Forms.Util {
/// <summary>Utility class for centralized logic related to form field rendering.</summary>
public sealed class FormFieldRendererUtil {
//These properties are related to the outer box of the element.
private static readonly int[] PROPERTIES_THAT_IMPACT_LAYOUT = new int[] { Property.MARGIN_TOP, Property.MARGIN_BOTTOM
, Property.MARGIN_LEFT, Property.MARGIN_RIGHT, Property.WIDTH, Property.BOTTOM, Property.LEFT, Property
.POSITION };

/// <summary>
/// Creates a new instance of
/// <see cref="FormFieldRendererUtil"/>.
/// </summary>
private FormFieldRendererUtil() {
}

// empty constructor
/// <summary>Removes properties that impact the lay outing of interactive form fields.</summary>
/// <param name="modelElement">The model element to remove the properties from.</param>
/// <returns>A map containing the removed properties.</returns>
public static IDictionary<int, Object> RemoveProperties(IPropertyContainer modelElement) {
IDictionary<int, Object> properties = new Dictionary<int, Object>(PROPERTIES_THAT_IMPACT_LAYOUT.Length);
foreach (int i in PROPERTIES_THAT_IMPACT_LAYOUT) {
properties.Put(i, modelElement.GetOwnProperty<Object>(i));
modelElement.DeleteOwnProperty(i);
}
return properties;
}

/// <summary>
/// Reapplies the properties
/// <see cref="iText.Layout.IPropertyContainer"/>.
/// </summary>
/// <param name="modelElement">The model element to reapply the properties to.</param>
/// <param name="properties">The properties to reapply.</param>
public static void ReapplyProperties(IPropertyContainer modelElement, IDictionary<int, Object> properties) {
foreach (KeyValuePair<int, Object> integerObjectEntry in properties) {
if (integerObjectEntry.Value != null) {
modelElement.SetProperty(integerObjectEntry.Key, integerObjectEntry.Value);
}
else {
modelElement.DeleteOwnProperty(integerObjectEntry.Key);
}
}
}
}
}
Loading

0 comments on commit fa2a742

Please sign in to comment.