@@ -43,15 +43,17 @@ This file is part of the iText (R) project.
43
43
*/
44
44
package com .itextpdf .forms .fields ;
45
45
46
+ import com .itextpdf .commons .utils .ExperimentalFeatures ;
46
47
import com .itextpdf .commons .utils .MessageFormatUtil ;
47
48
import com .itextpdf .forms .fields .borders .FormBorderFactory ;
48
49
import com .itextpdf .forms .fields .properties .CheckBoxType ;
49
50
import com .itextpdf .forms .form .FormProperty ;
51
+ import com .itextpdf .forms .form .element .CheckBox ;
50
52
import com .itextpdf .forms .form .element .Radio ;
51
53
import com .itextpdf .forms .logs .FormsLogMessageConstants ;
52
54
import com .itextpdf .forms .util .DrawingUtil ;
53
- import com .itextpdf .io .logs .IoLogMessageConstant ;
54
55
import com .itextpdf .io .font .FontProgram ;
56
+ import com .itextpdf .io .logs .IoLogMessageConstant ;
55
57
import com .itextpdf .kernel .colors .Color ;
56
58
import com .itextpdf .kernel .colors .ColorConstants ;
57
59
import com .itextpdf .kernel .colors .DeviceCmyk ;
@@ -102,7 +104,6 @@ This file is part of the iText (R) project.
102
104
import java .util .LinkedHashSet ;
103
105
import java .util .List ;
104
106
import java .util .Set ;
105
-
106
107
import org .slf4j .Logger ;
107
108
import org .slf4j .LoggerFactory ;
108
109
@@ -663,6 +664,7 @@ protected void drawBorder(PdfCanvas canvas, PdfFormXObject xObject, float width,
663
664
* @param height the height of the checkbox to draw
664
665
* @param onStateName the state of the form field that will be drawn
665
666
*/
667
+ //TODO DEVSIX-7426 remove method
666
668
protected void drawCheckAppearance (float width , float height , String onStateName ) {
667
669
Rectangle rect = new Rectangle (0 , 0 , width , height );
668
670
@@ -703,6 +705,7 @@ protected void drawCheckAppearance(float width, float height, String onStateName
703
705
* @param onStateName name that corresponds to the "On" state of the checkbox
704
706
* @param checkType the type that determines how the checkbox will look like. Instance of {@link CheckBoxType}
705
707
*/
708
+ //TODO DEVSIX-7426 remove method
706
709
protected void drawPdfA2CheckAppearance (float width , float height , String onStateName , CheckBoxType checkType ) {
707
710
parent .checkType = checkType ;
708
711
Rectangle rect = new Rectangle (0 , 0 , width , height );
@@ -813,6 +816,7 @@ protected void drawButton(PdfCanvas canvas, float x, float y, float width, float
813
816
* @param height the width of the button
814
817
* @param fontSize the size of the font
815
818
*/
819
+ //TODO DEVSIX-7426 remove method
816
820
protected void drawCheckBox (PdfCanvas canvas , float width , float height , float fontSize ) {
817
821
if (parent .checkType == CheckBoxType .CROSS ) {
818
822
DrawingUtil .drawCross (canvas , width , height , borderWidth );
@@ -834,6 +838,7 @@ protected void drawCheckBox(PdfCanvas canvas, float width, float height, float f
834
838
endText ();
835
839
}
836
840
841
+ //TODO DEVSIX-7426 remove method
837
842
protected void drawPdfACheckBox (PdfCanvas canvas , float width , float height , boolean on ) {
838
843
if (!on ) {
839
844
return ;
@@ -1024,13 +1029,13 @@ void regeneratePushButtonField() {
1024
1029
}
1025
1030
}
1026
1031
1032
+ //TODO DEVSIX-7426 remove method
1027
1033
void regenerateCheckboxField (CheckBoxType checkType ) {
1028
1034
parent .setCheckType (checkType );
1029
1035
final String value = parent .getValueAsString ();
1030
1036
Rectangle rect = getRect (getPdfObject ());
1031
1037
1032
1038
PdfWidgetAnnotation widget = (PdfWidgetAnnotation ) PdfAnnotation .makeAnnotation (getPdfObject ());
1033
-
1034
1039
if (getPdfAConformanceLevel () == null ) {
1035
1040
drawCheckAppearance (rect .getWidth (), rect .getHeight (),
1036
1041
OFF_STATE_VALUE .equals (value ) ? ON_STATE_VALUE : value );
@@ -1203,7 +1208,13 @@ boolean regenerateWidget() {
1203
1208
} else if (parent .getFieldFlag (PdfButtonFormField .FF_RADIO )) {
1204
1209
drawRadioButtonAndSaveAppearance (getRadioButtonValue ());
1205
1210
} else {
1206
- regenerateCheckboxField (parent .checkType );
1211
+ //TODO DEVSIX-7426 remove flag
1212
+ if (ExperimentalFeatures .ENABLE_EXPERIMENTAL_CHECKBOX_RENDERING ){
1213
+ drawCheckBoxAndSaveAppearanceExperimental (parent .getValueAsString ());
1214
+ }else {
1215
+ //TODO DEVSIX-7426 remove method
1216
+ regenerateCheckboxField (parent .checkType );
1217
+ }
1207
1218
}
1208
1219
return true ;
1209
1220
}
@@ -1476,4 +1487,80 @@ private static Color appearancePropToColor(PdfDictionary appearanceCharacteristi
1476
1487
}
1477
1488
return null ;
1478
1489
}
1490
+
1491
+ /**
1492
+ * Experimental method to draw a checkbox and save its appearance.
1493
+ *
1494
+ * @param onStateName the name of the appearance state for the checked state
1495
+ */
1496
+ //TODO DEVSIX-7426 rename experimental method
1497
+ protected void drawCheckBoxAndSaveAppearanceExperimental (String onStateName ) {
1498
+ final Rectangle rect = getRect (this .getPdfObject ());
1499
+ if (rect == null ) {
1500
+ return ;
1501
+ }
1502
+
1503
+ final CheckBox formField = createCheckBox ();
1504
+ if (formField == null ) {
1505
+ return ;
1506
+ }
1507
+ // First draw off appearance
1508
+ if (getWidget ().getNormalAppearanceObject () == null ){
1509
+ getWidget ().setNormalAppearance (new PdfDictionary ());
1510
+ }
1511
+ final PdfDictionary normalAppearance = getWidget ().getNormalAppearanceObject ();
1512
+ // Draw on appearance
1513
+ formField .setChecked (false );
1514
+ final PdfFormXObject xObjectOff = new PdfFormXObject (new Rectangle (0 , 0 , rect .getWidth (), rect .getHeight ()));
1515
+ final Canvas canvasOff = new Canvas (xObjectOff , getDocument ());
1516
+ canvasOff .add (formField );
1517
+ normalAppearance .put (new PdfName (OFF_STATE_VALUE ), xObjectOff .getPdfObject ());
1518
+ if (onStateName != null && !onStateName .isEmpty () && !PdfFormAnnotation .OFF_STATE_VALUE .equals (onStateName )) {
1519
+ formField .setChecked (true );
1520
+ final PdfFormXObject xObject = new PdfFormXObject (new Rectangle (0 , 0 , rect .getWidth (), rect .getHeight ()));
1521
+ final Canvas canvas = new Canvas (xObject , this .getDocument ());
1522
+ canvas .add (formField );
1523
+ normalAppearance .put (new PdfName (onStateName ), xObject .getPdfObject ());
1524
+ }
1525
+
1526
+ final PdfDictionary mk = new PdfDictionary ();
1527
+ mk .put (PdfName .CA , new PdfString (parent .text ));
1528
+ getWidget ().put (PdfName .MK , mk );
1529
+ final PdfWidgetAnnotation widget = getWidget ();
1530
+ if (widget .getNormalAppearanceObject () != null &&
1531
+ widget .getNormalAppearanceObject ().containsKey (new PdfName (onStateName ))) {
1532
+ widget .setAppearanceState (new PdfName (onStateName ));
1533
+ } else {
1534
+ widget .setAppearanceState (new PdfName (OFF_STATE_VALUE ));
1535
+ }
1536
+ }
1537
+
1538
+ private CheckBox createCheckBox (){
1539
+ final Rectangle rect = getRect (getPdfObject ());
1540
+ if (rect == null ) {
1541
+ return null ;
1542
+ }
1543
+
1544
+ // id doesn't matter here
1545
+ CheckBox checkBox = new CheckBox ("" );
1546
+ if (getBorderWidth () > 0 && borderColor != null ) {
1547
+ Border border = new SolidBorder (Math .max (1 , getBorderWidth ()));
1548
+ border .setColor (borderColor );
1549
+ checkBox .setBorder (border );
1550
+ }
1551
+
1552
+ if (backgroundColor != null ) {
1553
+ checkBox .setBackgroundColor (backgroundColor );
1554
+ }
1555
+
1556
+ // Set fixed size
1557
+ checkBox .setProperty (Property .WIDTH , UnitValue .createPointValue (rect .getWidth ()));
1558
+ checkBox .setProperty (Property .HEIGHT , UnitValue .createPointValue (rect .getHeight ()));
1559
+ // Always flatten
1560
+ checkBox .setInteractive (false );
1561
+ checkBox .setPdfAConformanceLevel (getPdfAConformanceLevel ());
1562
+ checkBox .setCheckBoxType (parent .checkType );
1563
+
1564
+ return checkBox ;
1565
+ }
1479
1566
}
0 commit comments