@@ -2118,20 +2118,34 @@ public boolean regenerateField() {
2118
2118
throw new PdfException (e );
2119
2119
}
2120
2120
} else if ((ff & PdfButtonFormField .FF_RADIO ) != 0 ) {
2121
- PdfArray kids = getKids ();
2122
- if (null != kids ) {
2123
- for (int i = 0 ; i < kids .size (); i ++) {
2124
- PdfObject kid = kids .get (i );
2121
+ if (isRadioButton ()) {
2122
+ // TODO DEVSIX-2536
2123
+ // Actually only radio group has FF_RADIO type.
2124
+ // This means that only radio group shall have regeneration functionality.
2125
+ Rectangle rect = getRect (getPdfObject ());
2126
+ value = getRadioButtonValue (value );
2127
+ if (rect != null && !"" .equals (value )) {
2128
+ if (pdfAConformanceLevel != null && "1" .equals (pdfAConformanceLevel .getPart ())) {
2129
+ drawPdfA1RadioAppearance (rect .getWidth (), rect .getHeight (), value );
2130
+ } else {
2131
+ drawRadioAppearance (rect .getWidth (), rect .getHeight (), value );
2132
+ }
2133
+ }
2134
+ } else if (getKids () != null ) {
2135
+ for (PdfObject kid : getKids ()) {
2125
2136
PdfFormField field = new PdfFormField ((PdfDictionary ) kid );
2126
2137
PdfWidgetAnnotation widget = field .getWidgets ().get (0 );
2127
2138
PdfDictionary apStream = field .getPdfObject ().getAsDictionary (PdfName .AP );
2128
- String state ;
2139
+ if (apStream == null ) { //widget annotation was not merged
2140
+ apStream = widget .getPdfObject ().getAsDictionary (PdfName .AP );
2141
+ }
2142
+ PdfName state ;
2129
2143
if (null != apStream && null != getValueFromAppearance (apStream .get (PdfName .N ), new PdfName (value ))) {
2130
- state = value ;
2144
+ state = new PdfName ( value ) ;
2131
2145
} else {
2132
- state = "Off" ;
2146
+ state = new PdfName ( "Off" ) ;
2133
2147
}
2134
- widget .setAppearanceState (new PdfName ( state ) );
2148
+ widget .setAppearanceState (state );
2135
2149
}
2136
2150
}
2137
2151
} else {
@@ -2168,6 +2182,40 @@ public boolean regenerateField() {
2168
2182
return true ;
2169
2183
}
2170
2184
2185
+ // TODO DEVSIX-2536
2186
+ // Actually this entire method is a mess,
2187
+ // because only radio group has FF_RADIO type and there is no RadioButton at all.
2188
+ // So the goal of that method is just to save backward compatibility until refactoring.
2189
+ private boolean isRadioButton () {
2190
+ if (isWidgetAnnotation (getPdfObject ())) {
2191
+ return true ;
2192
+ } else if (getPdfObject ().getAsName (PdfName .V ) != null ) {
2193
+ return false ;
2194
+ } else if (getKids () != null ) {
2195
+ return isWidgetAnnotation (getKids ().getAsDictionary (0 ));
2196
+ } else {
2197
+ return false ;
2198
+ }
2199
+ }
2200
+
2201
+ private static boolean isWidgetAnnotation (PdfDictionary pdfObject ) {
2202
+ return pdfObject != null && PdfName .Widget .equals (pdfObject .getAsName (PdfName .Subtype ));
2203
+ }
2204
+
2205
+ private String getRadioButtonValue (String value ) {
2206
+ assert value != null ; //Otherwise something wrong with getValueAsString().
2207
+ if ("" .equals (value )) {
2208
+ value = "Yes" ; //let it as default value
2209
+ for (String state : getAppearanceStates ()) {
2210
+ if (!"Off" .equals (state )) {
2211
+ value = state ;
2212
+ break ;
2213
+ }
2214
+ }
2215
+ }
2216
+ return value ;
2217
+ }
2218
+
2171
2219
/**
2172
2220
* According to spec (ISO-32000-1, 12.7.3.3) zero font size should interpretaded as auto size.
2173
2221
*/
@@ -2599,7 +2647,7 @@ protected Rectangle getRect(PdfDictionary field) {
2599
2647
rect = ((PdfDictionary ) kids .get (0 )).getAsArray (PdfName .Rect );
2600
2648
}
2601
2649
2602
- return rect .toRectangle ();
2650
+ return rect != null ? rect .toRectangle () : null ;
2603
2651
}
2604
2652
2605
2653
protected static PdfArray processOptions (String [][] options ) {
@@ -2989,31 +3037,36 @@ protected void drawRadioBorder(PdfCanvas canvas, PdfFormXObject xObject, float w
2989
3037
* @param value the value of the button
2990
3038
*/
2991
3039
protected void drawRadioAppearance (float width , float height , String value ) {
3040
+ Rectangle rect = new Rectangle (0 , 0 , width , height );
3041
+ PdfWidgetAnnotation widget = getWidgets ().get (0 );
3042
+ widget .setNormalAppearance (new PdfDictionary ());
3043
+
3044
+ //On state
2992
3045
PdfStream streamOn = (PdfStream ) new PdfStream ().makeIndirect (getDocument ());
2993
3046
PdfCanvas canvasOn = new PdfCanvas (streamOn , new PdfResources (), getDocument ());
2994
- Rectangle rect = new Rectangle (0 , 0 , width , height );
2995
3047
PdfFormXObject xObjectOn = new PdfFormXObject (rect );
2996
- PdfFormXObject xObjectOff = new PdfFormXObject (rect );
2997
3048
2998
3049
drawRadioBorder (canvasOn , xObjectOn , width , height );
2999
3050
drawRadioField (canvasOn , width , height , true );
3000
3051
3052
+ xObjectOn .getPdfObject ().getOutputStream ().writeBytes (streamOn .getBytes ());
3053
+ widget .getNormalAppearanceObject ().put (new PdfName (value ), xObjectOn .getPdfObject ());
3054
+
3055
+ //Off state
3001
3056
PdfStream streamOff = (PdfStream ) new PdfStream ().makeIndirect (getDocument ());
3002
3057
PdfCanvas canvasOff = new PdfCanvas (streamOff , new PdfResources (), getDocument ());
3003
- drawRadioBorder (canvasOff , xObjectOff , width , height );
3004
- if (pdfAConformanceLevel != null && (pdfAConformanceLevel .getPart ().equals ("2" ) || pdfAConformanceLevel .getPart ().equals ("3" ))) {
3005
- xObjectOn .getResources ();
3006
- xObjectOff .getResources ();
3007
- }
3008
-
3009
- PdfWidgetAnnotation widget = getWidgets ().get (0 );
3058
+ PdfFormXObject xObjectOff = new PdfFormXObject (rect );
3010
3059
3011
- xObjectOn .getPdfObject ().getOutputStream ().writeBytes (streamOn .getBytes ());
3012
- widget .setNormalAppearance (new PdfDictionary ());
3013
- widget .getNormalAppearanceObject ().put (new PdfName (value ), xObjectOn .getPdfObject ());
3060
+ drawRadioBorder (canvasOff , xObjectOff , width , height );
3014
3061
3015
3062
xObjectOff .getPdfObject ().getOutputStream ().writeBytes (streamOff .getBytes ());
3016
3063
widget .getNormalAppearanceObject ().put (new PdfName ("Off" ), xObjectOff .getPdfObject ());
3064
+
3065
+ if (pdfAConformanceLevel != null
3066
+ && (pdfAConformanceLevel .getPart ().equals ("2" ) || pdfAConformanceLevel .getPart ().equals ("3" ))) {
3067
+ xObjectOn .getResources ();
3068
+ xObjectOff .getResources ();
3069
+ }
3017
3070
}
3018
3071
3019
3072
/**
@@ -3031,12 +3084,15 @@ protected void drawPdfA1RadioAppearance(float width, float height, String value)
3031
3084
3032
3085
3033
3086
drawBorder (canvas , xObject , width , height );
3034
- drawRadioField (canvas , rect .getWidth (), rect .getHeight (), !value .equals ("Off" ));
3087
+ drawRadioField (canvas , rect .getWidth (), rect .getHeight (), !"Off" .equals (value ));
3088
+
3089
+ PdfDictionary normalAppearance = new PdfDictionary ();
3090
+ normalAppearance .put (new PdfName (value ), xObject .getPdfObject ());
3035
3091
3036
3092
PdfWidgetAnnotation widget = getWidgets ().get (0 );
3037
3093
3038
3094
xObject .getPdfObject ().getOutputStream ().writeBytes (stream .getBytes ());
3039
- widget .setNormalAppearance (xObject . getPdfObject () );
3095
+ widget .setNormalAppearance (normalAppearance );
3040
3096
}
3041
3097
3042
3098
/**
0 commit comments