@@ -68,7 +68,6 @@ This file is part of the iText (R) project.
68
68
import com .itextpdf .layout .Style ;
69
69
import com .itextpdf .layout .borders .Border ;
70
70
import com .itextpdf .layout .borders .SolidBorder ;
71
- import com .itextpdf .layout .element .Div ;
72
71
import com .itextpdf .layout .element .Image ;
73
72
import com .itextpdf .layout .element .Paragraph ;
74
73
import com .itextpdf .layout .element .Text ;
@@ -84,7 +83,6 @@ This file is part of the iText (R) project.
84
83
import com .itextpdf .layout .renderer .MetaInfoContainer ;
85
84
86
85
import java .util .LinkedHashSet ;
87
- import java .util .List ;
88
86
import java .util .Set ;
89
87
import org .slf4j .Logger ;
90
88
import org .slf4j .LoggerFactory ;
@@ -117,6 +115,8 @@ public class PdfFormAnnotation extends AbstractPdfFormField {
117
115
* Default padding X offset.
118
116
*/
119
117
static final float X_OFFSET = 2 ;
118
+
119
+ private static final Logger LOGGER = LoggerFactory .getLogger (PdfFormAnnotation .class );
120
120
121
121
protected float borderWidth = 1 ;
122
122
protected Color backgroundColor ;
@@ -554,40 +554,10 @@ protected void drawTextAppearance(Rectangle rect, PdfFont font, float fontSize,
554
554
Style paragraphStyle = new Style ().setFont (font ).setFontSize (fontSize );
555
555
paragraphStyle .setProperty (Property .LEADING , new Leading (Leading .MULTIPLIED , 1 ));
556
556
paragraphStyle .setFontColor (getColor ());
557
-
558
- int maxLen = new PdfTextFormField (parent .getPdfObject ()).getMaxLen ();
559
- // check if /Comb has been set
560
- if (parent .getFieldFlag (PdfTextFormField .FF_COMB ) && 0 != maxLen ) {
561
- float widthPerCharacter = width / maxLen ;
562
- int numberOfCharacters = Math .min (maxLen , value .length ());
563
-
564
- int start ;
565
- switch (textAlignment ) {
566
- case RIGHT :
567
- start = (maxLen - numberOfCharacters );
568
- break ;
569
- case CENTER :
570
- start = (maxLen - numberOfCharacters ) / 2 ;
571
- break ;
572
- default :
573
- start = 0 ;
574
- }
575
- float startOffset = widthPerCharacter * (start + 0.5f );
576
- for (int i = 0 ; i < numberOfCharacters ; i ++) {
577
- modelCanvas .showTextAligned (new Paragraph (value .substring (i , i + 1 )).addStyle (paragraphStyle ),
578
- startOffset + widthPerCharacter * i , rect .getHeight () / 2 , TextAlignment .CENTER ,
579
- VerticalAlignment .MIDDLE );
580
- }
581
- } else {
582
- if (parent .getFieldFlag (PdfTextFormField .FF_COMB )) {
583
- Logger logger = LoggerFactory .getLogger (PdfFormAnnotation .class );
584
- logger .error (MessageFormatUtil .format (
585
- IoLogMessageConstant .COMB_FLAG_MAY_BE_SET_ONLY_IF_MAXLEN_IS_PRESENT ));
586
- }
587
- modelCanvas .showTextAligned (createParagraphForTextFieldValue (value ).addStyle (paragraphStyle )
588
- .setPaddings (0 , X_OFFSET , 0 , X_OFFSET ), x , rect .getHeight () / 2 , textAlignment ,
589
- VerticalAlignment .MIDDLE );
590
- }
557
+
558
+ modelCanvas .showTextAligned (createParagraphForTextFieldValue (value ).addStyle (paragraphStyle )
559
+ .setPaddings (0 , X_OFFSET , 0 , X_OFFSET ), x , rect .getHeight () / 2 , textAlignment ,
560
+ VerticalAlignment .MIDDLE );
591
561
canvas .
592
562
restoreState ().
593
563
endVariableText ();
@@ -1006,81 +976,6 @@ void retrieveStyles() {
1006
976
}
1007
977
}
1008
978
1009
- /**
1010
- * Draws the visual appearance of Choice box in a form field.
1011
- *
1012
- * @param rect The location on the page for the list field
1013
- * @param value The initial value
1014
- * @param appearance The appearance
1015
- */
1016
- void drawChoiceAppearance (Rectangle rect , float fontSize , String value , PdfFormXObject appearance , int topIndex ) {
1017
- PdfStream stream = (PdfStream ) new PdfStream ().makeIndirect (getDocument ());
1018
- PdfResources resources = appearance .getResources ();
1019
- PdfCanvas canvas = new PdfCanvas (stream , resources , getDocument ());
1020
-
1021
- float width = rect .getWidth ();
1022
- float height = rect .getHeight ();
1023
- float widthBorder = 6.0f ;
1024
- float heightBorder = 2.0f ;
1025
-
1026
- drawBorder (canvas , appearance , width , height );
1027
- canvas .
1028
- beginVariableText ().
1029
- saveState ().
1030
- rectangle (3 , 3 , width - widthBorder , height - heightBorder ).
1031
- clip ().
1032
- endPath ();
1033
-
1034
- Canvas modelCanvas = new Canvas (canvas , new Rectangle (3 , 0 , Math .max (0 , width - widthBorder ),
1035
- Math .max (0 , height - heightBorder )));
1036
- modelCanvas .setProperty (Property .APPEARANCE_STREAM_LAYOUT , Boolean .TRUE );
1037
-
1038
- setMetaInfoToCanvas (modelCanvas );
1039
-
1040
- Div div = new Div ();
1041
- if (parent .getFieldFlag (PdfChoiceFormField .FF_COMBO )) {
1042
- div .setVerticalAlignment (VerticalAlignment .MIDDLE );
1043
- }
1044
- div .setHeight (Math .max (0 , height - heightBorder ));
1045
- List <String > strings = getFont ().splitString (value , fontSize , width - widthBorder );
1046
- for (int index = 0 ; index < strings .size (); index ++) {
1047
- Boolean isFull = modelCanvas .getRenderer ().getPropertyAsBoolean (Property .FULL );
1048
- if (Boolean .TRUE .equals (isFull )) {
1049
- break ;
1050
- }
1051
-
1052
- Paragraph paragraph = new Paragraph (strings .get (index )).setFont (getFont ())
1053
- .setFontSize (fontSize ).setMargins (0 , 0 , 0 , 0 ).setMultipliedLeading (1 );
1054
- paragraph .setProperty (Property .FORCED_PLACEMENT , Boolean .TRUE );
1055
- paragraph .setTextAlignment (parent .getJustification ());
1056
-
1057
- if (getColor () != null ) {
1058
- paragraph .setFontColor (getColor ());
1059
- }
1060
- if (!parent .getFieldFlag (PdfChoiceFormField .FF_COMBO )) {
1061
- PdfArray indices = getParent ().getAsArray (PdfName .I );
1062
- if (indices != null && indices .size () > 0 ) {
1063
- for (PdfObject ind : indices ) {
1064
- if (!ind .isNumber ()) {
1065
- continue ;
1066
- }
1067
- if (((PdfNumber ) ind ).getValue () == index + topIndex ) {
1068
- paragraph .setBackgroundColor (new DeviceRgb (10 , 36 , 106 ));
1069
- paragraph .setFontColor (ColorConstants .LIGHT_GRAY );
1070
- }
1071
- }
1072
- }
1073
- }
1074
- div .add (paragraph );
1075
- }
1076
- modelCanvas .add (div );
1077
- canvas .
1078
- restoreState ().
1079
- endVariableText ();
1080
-
1081
- appearance .getPdfObject ().setData (stream .getBytes ());
1082
- }
1083
-
1084
979
static void setMetaInfoToCanvas (Canvas canvas ) {
1085
980
MetaInfoContainer metaInfo = FormsMetaInfoStaticContainer .getMetaInfoForLayout ();
1086
981
if (metaInfo != null ) {
@@ -1162,8 +1057,7 @@ boolean regenerateTextAndChoiceField() {
1162
1057
bBox = new PdfArray (rect );
1163
1058
} else {
1164
1059
//Avoid NPE when handling corrupt pdfs
1165
- Logger logger = LoggerFactory .getLogger (PdfFormAnnotation .class );
1166
- logger .error (FormsLogMessageConstants .INCORRECT_PAGE_ROTATION );
1060
+ LOGGER .error (FormsLogMessageConstants .INCORRECT_PAGE_ROTATION );
1167
1061
matrix = new PdfArray (new double [] {1 , 0 , 0 , 1 , 0 , 0 });
1168
1062
}
1169
1063
//Apply field rotation
@@ -1229,19 +1123,6 @@ boolean regenerateTextAndChoiceField() {
1229
1123
} else {
1230
1124
drawTextAppearance (bboxRectangle , getFont (), getFontSize (bBox , value ), value , appearance );
1231
1125
}
1232
- } else {
1233
- int topIndex = 0 ;
1234
- if (!parent .getFieldFlag (PdfChoiceFormField .FF_COMBO )) {
1235
- PdfNumber topIndexNum = this .getParent ().getAsNumber (PdfName .TI );
1236
- PdfArray options = parent .getOptions ();
1237
- if (null != options ) {
1238
- topIndex = null != topIndexNum ? topIndexNum .intValue () : 0 ;
1239
- PdfArray visibleOptions = topIndex > 0
1240
- ? new PdfArray (options .subList (topIndex , options .size ())) : (PdfArray ) options .clone ();
1241
- value = PdfFormField .optionsArrayToString (visibleOptions );
1242
- }
1243
- }
1244
- drawChoiceAppearance (bboxRectangle , getFontSize (bBox , value ), value , appearance , topIndex );
1245
1126
}
1246
1127
PdfDictionary ap = new PdfDictionary ();
1247
1128
ap .put (PdfName .N , appearance .getPdfObject ());
@@ -1257,11 +1138,15 @@ boolean regenerateWidget() {
1257
1138
}
1258
1139
final PdfName type = parent .getFormType ();
1259
1140
1260
- if (PdfName .Tx .equals (type ) && ExperimentalFeatures .ENABLE_EXPERIMENTAL_TEXT_FORM_RENDERING ) {
1261
- drawTextFormFieldAndSaveAppearance ();
1262
- return true ;
1263
- } else if (PdfName .Ch .equals (type ) || PdfName .Tx .equals (type )) {
1264
- return regenerateTextAndChoiceField ();
1141
+ if (PdfName .Ch .equals (type ) || this .isCombTextFormField ()) {
1142
+ return TextAndChoiceLegacyDrawer .regenerateTextAndChoiceField (this );
1143
+ } else if (PdfName .Tx .equals (type )) {
1144
+ if (ExperimentalFeatures .ENABLE_EXPERIMENTAL_TEXT_FORM_RENDERING ) {
1145
+ drawTextFormFieldAndSaveAppearance ();
1146
+ return true ;
1147
+ } else {
1148
+ return regenerateTextAndChoiceField ();
1149
+ }
1265
1150
} else if (PdfName .Btn .equals (type )) {
1266
1151
if (parent .getFieldFlag (PdfButtonFormField .FF_PUSH_BUTTON )) {
1267
1152
drawPushButtonFieldAndSaveAppearance ();
@@ -1350,6 +1235,18 @@ Radio createRadio() {
1350
1235
return radio ;
1351
1236
}
1352
1237
1238
+ float getFontSize (PdfArray bBox , String value ) {
1239
+ if (getFontSize () == 0 ) {
1240
+ if (bBox == null || value == null || value .isEmpty ()) {
1241
+ return DEFAULT_FONT_SIZE ;
1242
+ } else {
1243
+ return FontSizeUtil .approximateFontSizeToFitSingleLine (getFont (), bBox .toRectangle (), value ,
1244
+ MIN_FONT_SIZE , borderWidth );
1245
+ }
1246
+ }
1247
+ return getFontSize ();
1248
+ }
1249
+
1353
1250
private static double degreeToRadians (double angle ) {
1354
1251
return Math .PI * angle / 180.0 ;
1355
1252
}
@@ -1360,6 +1257,20 @@ private static Paragraph createParagraphForTextFieldValue(String value) {
1360
1257
return new Paragraph (text );
1361
1258
}
1362
1259
1260
+ private boolean isCombTextFormField () {
1261
+ final PdfName type = parent .getFormType ();
1262
+ if (PdfName .Tx .equals (type ) && parent .getFieldFlag (PdfTextFormField .FF_COMB )) {
1263
+ int maxLen = new PdfTextFormField (parent .getPdfObject ()).getMaxLen ();
1264
+ if (maxLen == 0 || parent .isMultiline ()) {
1265
+ LOGGER .error (
1266
+ MessageFormatUtil .format (IoLogMessageConstant .COMB_FLAG_MAY_BE_SET_ONLY_IF_MAXLEN_IS_PRESENT ));
1267
+ return false ;
1268
+ }
1269
+ return true ;
1270
+ }
1271
+ return false ;
1272
+ }
1273
+
1363
1274
private String getRadioButtonValue () {
1364
1275
for (String state : getAppearanceStates ()) {
1365
1276
if (!OFF_STATE_VALUE .equals (state )) {
@@ -1369,19 +1280,6 @@ private String getRadioButtonValue() {
1369
1280
return null ;
1370
1281
}
1371
1282
1372
- private float getFontSize (PdfArray bBox , String value ) {
1373
- if (getFontSize () == 0 ) {
1374
- if (bBox == null || value == null || value .isEmpty ()) {
1375
- return DEFAULT_FONT_SIZE ;
1376
- } else {
1377
- return FontSizeUtil .approximateFontSizeToFitSingleLine (getFont (), bBox .toRectangle (), value ,
1378
- MIN_FONT_SIZE , borderWidth );
1379
- }
1380
- }
1381
- return getFontSize ();
1382
- }
1383
-
1384
-
1385
1283
/**
1386
1284
* Calculate the necessary height offset after applying field rotation
1387
1285
* so that the origin of the bounding box is the lower left corner with respect to the field text.
0 commit comments