Skip to content

Commit 59efd39

Browse files
Scale flattened form fields appearance properly
DEVSIX-1741
1 parent c623cf0 commit 59efd39

File tree

1 file changed

+52
-20
lines changed

1 file changed

+52
-20
lines changed

forms/src/main/java/com/itextpdf/forms/PdfAcroForm.java

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,9 @@ This file is part of the iText (R) project.
4646
import com.itextpdf.forms.fields.PdfFormField;
4747
import com.itextpdf.forms.xfa.XfaForm;
4848
import com.itextpdf.io.LogMessageConstant;
49-
import com.itextpdf.io.font.constants.StandardFonts;
5049
import com.itextpdf.kernel.PdfException;
51-
import com.itextpdf.kernel.font.PdfFont;
52-
import com.itextpdf.kernel.font.PdfFontFactory;
50+
import com.itextpdf.kernel.geom.AffineTransform;
51+
import com.itextpdf.kernel.geom.Point;
5352
import com.itextpdf.kernel.geom.Rectangle;
5453
import com.itextpdf.kernel.pdf.PdfArray;
5554
import com.itextpdf.kernel.pdf.PdfBoolean;
@@ -60,22 +59,18 @@ This file is part of the iText (R) project.
6059
import com.itextpdf.kernel.pdf.PdfObject;
6160
import com.itextpdf.kernel.pdf.PdfObjectWrapper;
6261
import com.itextpdf.kernel.pdf.PdfPage;
63-
import com.itextpdf.kernel.pdf.PdfResources;
6462
import com.itextpdf.kernel.pdf.PdfStream;
6563
import com.itextpdf.kernel.pdf.PdfString;
6664
import com.itextpdf.kernel.pdf.PdfVersion;
6765
import com.itextpdf.kernel.pdf.VersionConforming;
6866
import com.itextpdf.kernel.pdf.annot.PdfAnnotation;
69-
import com.itextpdf.kernel.pdf.annot.da.StandardAnnotationFont;
7067
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
7168
import com.itextpdf.kernel.pdf.tagging.StandardRoles;
7269
import com.itextpdf.kernel.pdf.tagutils.TagReference;
7370
import com.itextpdf.kernel.pdf.tagutils.TagTreePointer;
7471
import com.itextpdf.kernel.pdf.xobject.PdfFormXObject;
7572

76-
import java.io.IOException;
7773
import java.util.ArrayList;
78-
import java.util.Arrays;
7974
import java.util.LinkedHashMap;
8075
import java.util.LinkedHashSet;
8176
import java.util.List;
@@ -682,7 +677,7 @@ public void flattenFields() {
682677

683678
// Subtype is required key, if there is no Subtype it is invalid XObject. DEVSIX-725
684679
if (xObject != null && xObject.getPdfObject().get(PdfName.Subtype) != null) {
685-
Rectangle box = fieldObject.getAsRectangle(PdfName.Rect);
680+
Rectangle annotBBox = fieldObject.getAsRectangle(PdfName.Rect);
686681
if (page.isFlushed()) {
687682
throw new PdfException(PdfException.PageAlreadyFlushedUseAddFieldAppearanceToPageMethodBeforePageFlushing);
688683
}
@@ -703,19 +698,11 @@ public void flattenFields() {
703698
canvas.openTag(tagRef);
704699
}
705700

706-
PdfArray oldMatrix = xObject.getPdfObject().getAsArray(PdfName.Matrix);
701+
AffineTransform at = calcFieldAppTransformToAnnotRect(xObject, annotBBox);
702+
float[] m = new float[6];
703+
at.getMatrix(m);
704+
canvas.addXObject(xObject, m[0], m[1], m[2], m[3], m[4], m[5]);
707705

708-
if ( oldMatrix != null && Arrays.equals(oldMatrix.toFloatArray(), new float[] {1, 0, 0, 1, 0, 0})) {
709-
Rectangle boundingBox = xObject.getBBox().toRectangle();
710-
PdfArray newMatrixArray = new PdfArray(
711-
new float[] {
712-
box.getWidth() / boundingBox.getWidth(), 0, 0,
713-
box.getHeight() / boundingBox.getHeight(), 0, 0
714-
});
715-
xObject.put(PdfName.Matrix, new PdfArray(newMatrixArray));
716-
}
717-
718-
canvas.addXObject(xObject, box.getX(), box.getY());
719706
if (tagPointer != null) {
720707
canvas.closeTag();
721708
}
@@ -1117,4 +1104,49 @@ private Set<PdfFormField> prepareFieldsForFlattening(PdfFormField field) {
11171104
}
11181105
return preparedFields;
11191106
}
1107+
1108+
private AffineTransform calcFieldAppTransformToAnnotRect(PdfFormXObject xObject, Rectangle annotBBox) {
1109+
PdfArray bBox = xObject.getBBox();
1110+
if (bBox.size() != 4) {
1111+
bBox = new PdfArray(new Rectangle(0, 0));
1112+
xObject.setBBox(bBox);
1113+
}
1114+
float[] xObjBBox = bBox.toFloatArray();
1115+
1116+
PdfArray xObjMatrix = xObject.getPdfObject().getAsArray(PdfName.Matrix);
1117+
Rectangle transformedRect;
1118+
if (xObjMatrix != null && xObjMatrix.size() == 6) {
1119+
Point[] xObjRectPoints = new Point[]{
1120+
new Point(xObjBBox[0], xObjBBox[1]),
1121+
new Point(xObjBBox[0], xObjBBox[3]),
1122+
new Point(xObjBBox[2], xObjBBox[1]),
1123+
new Point(xObjBBox[2], xObjBBox[3])
1124+
};
1125+
Point[] transformedAppBoxPoints = new Point[xObjRectPoints.length];
1126+
new AffineTransform(xObjMatrix.toDoubleArray()).transform(xObjRectPoints, 0, transformedAppBoxPoints, 0, xObjRectPoints.length);
1127+
1128+
float[] transformedRectArr = new float[] {
1129+
Float.MAX_VALUE, Float.MAX_VALUE,
1130+
-Float.MAX_VALUE, -Float.MAX_VALUE,
1131+
};
1132+
for (Point p : transformedAppBoxPoints) {
1133+
transformedRectArr[0] = (float) Math.min(transformedRectArr[0], p.x);
1134+
transformedRectArr[1] = (float) Math.min(transformedRectArr[1], p.y);
1135+
transformedRectArr[2] = (float) Math.max(transformedRectArr[2], p.x);
1136+
transformedRectArr[3] = (float) Math.max(transformedRectArr[3], p.y);
1137+
}
1138+
1139+
transformedRect = new Rectangle(transformedRectArr[0], transformedRectArr[1], transformedRectArr[2] - transformedRectArr[0], transformedRectArr[3] - transformedRectArr[1]);
1140+
} else {
1141+
transformedRect = new Rectangle(0, 0).setBbox(xObjBBox[0], xObjBBox[1], xObjBBox[2], xObjBBox[3]);
1142+
}
1143+
1144+
AffineTransform at = AffineTransform.getTranslateInstance(-transformedRect.getX(), -transformedRect.getY());
1145+
float scaleX = transformedRect.getWidth() == 0 ? 1 : annotBBox.getWidth() / transformedRect.getWidth();
1146+
float scaleY = transformedRect.getHeight() == 0 ? 1 : annotBBox.getHeight() / transformedRect.getHeight();
1147+
at.preConcatenate(AffineTransform.getScaleInstance(scaleX, scaleY));
1148+
at.preConcatenate(AffineTransform.getTranslateInstance(annotBBox.getX(), annotBBox.getY()));
1149+
1150+
return at;
1151+
}
11201152
}

0 commit comments

Comments
 (0)