@@ -2750,21 +2750,40 @@ public virtual bool RegenerateField() {
27502750 }
27512751 else {
27522752 if ( ( ff & PdfButtonFormField . FF_RADIO ) != 0 ) {
2753- PdfArray kids = GetKids ( ) ;
2754- if ( null != kids ) {
2755- for ( int i = 0 ; i < kids . Size ( ) ; i ++ ) {
2756- PdfObject kid = kids . Get ( i ) ;
2757- iText . Forms . Fields . PdfFormField field = new iText . Forms . Fields . PdfFormField ( ( PdfDictionary ) kid ) ;
2758- PdfWidgetAnnotation widget = field . GetWidgets ( ) [ 0 ] ;
2759- PdfDictionary apStream = field . GetPdfObject ( ) . GetAsDictionary ( PdfName . AP ) ;
2760- String state ;
2761- if ( null != apStream && null != GetValueFromAppearance ( apStream . Get ( PdfName . N ) , new PdfName ( value ) ) ) {
2762- state = value ;
2753+ if ( IsRadioButton ( ) ) {
2754+ // TODO DEVSIX-2536
2755+ // Actually only radio group has FF_RADIO type.
2756+ // This means that only radio group shall have regeneration functionality.
2757+ Rectangle rect = GetRect ( GetPdfObject ( ) ) ;
2758+ value = GetRadioButtonValue ( value ) ;
2759+ if ( rect != null && ! "" . Equals ( value ) ) {
2760+ if ( pdfAConformanceLevel != null && "1" . Equals ( pdfAConformanceLevel . GetPart ( ) ) ) {
2761+ DrawPdfA1RadioAppearance ( rect . GetWidth ( ) , rect . GetHeight ( ) , value ) ;
27632762 }
27642763 else {
2765- state = "Off" ;
2764+ DrawRadioAppearance ( rect . GetWidth ( ) , rect . GetHeight ( ) , value ) ;
2765+ }
2766+ }
2767+ }
2768+ else {
2769+ if ( GetKids ( ) != null ) {
2770+ foreach ( PdfObject kid in GetKids ( ) ) {
2771+ iText . Forms . Fields . PdfFormField field = new iText . Forms . Fields . PdfFormField ( ( PdfDictionary ) kid ) ;
2772+ PdfWidgetAnnotation widget = field . GetWidgets ( ) [ 0 ] ;
2773+ PdfDictionary apStream = field . GetPdfObject ( ) . GetAsDictionary ( PdfName . AP ) ;
2774+ if ( apStream == null ) {
2775+ //widget annotation was not merged
2776+ apStream = widget . GetPdfObject ( ) . GetAsDictionary ( PdfName . AP ) ;
2777+ }
2778+ PdfName state ;
2779+ if ( null != apStream && null != GetValueFromAppearance ( apStream . Get ( PdfName . N ) , new PdfName ( value ) ) ) {
2780+ state = new PdfName ( value ) ;
2781+ }
2782+ else {
2783+ state = new PdfName ( "Off" ) ;
2784+ }
2785+ widget . SetAppearanceState ( state ) ;
27662786 }
2767- widget . SetAppearanceState ( new PdfName ( state ) ) ;
27682787 }
27692788 }
27702789 }
@@ -2812,6 +2831,49 @@ public virtual bool RegenerateField() {
28122831 return true ;
28132832 }
28142833
2834+ // TODO DEVSIX-2536
2835+ // Actually this entire method is a mess,
2836+ // because only radio group has FF_RADIO type and there is no RadioButton at all.
2837+ // So the goal of that method is just to save backward compatibility until refactoring.
2838+ private bool IsRadioButton ( ) {
2839+ if ( IsWidgetAnnotation ( GetPdfObject ( ) ) ) {
2840+ return true ;
2841+ }
2842+ else {
2843+ if ( GetPdfObject ( ) . GetAsName ( PdfName . V ) != null ) {
2844+ return false ;
2845+ }
2846+ else {
2847+ if ( GetKids ( ) != null ) {
2848+ return IsWidgetAnnotation ( GetKids ( ) . GetAsDictionary ( 0 ) ) ;
2849+ }
2850+ else {
2851+ return false ;
2852+ }
2853+ }
2854+ }
2855+ }
2856+
2857+ private static bool IsWidgetAnnotation ( PdfDictionary pdfObject ) {
2858+ return pdfObject != null && PdfName . Widget . Equals ( pdfObject . GetAsName ( PdfName . Subtype ) ) ;
2859+ }
2860+
2861+ private String GetRadioButtonValue ( String value ) {
2862+ System . Diagnostics . Debug . Assert ( value != null ) ;
2863+ //Otherwise something wrong with getValueAsString().
2864+ if ( "" . Equals ( value ) ) {
2865+ value = "Yes" ;
2866+ //let it as default value
2867+ foreach ( String state in GetAppearanceStates ( ) ) {
2868+ if ( ! "Off" . Equals ( state ) ) {
2869+ value = state ;
2870+ break ;
2871+ }
2872+ }
2873+ }
2874+ return value ;
2875+ }
2876+
28152877 /// <summary>According to spec (ISO-32000-1, 12.7.3.3) zero font size should interpretaded as auto size.</summary>
28162878 private float NormalizeFontSize ( float fs , PdfFont localFont , PdfArray bBox , String value ) {
28172879 if ( fs == 0 ) {
@@ -3206,7 +3268,7 @@ protected internal virtual Rectangle GetRect(PdfDictionary field) {
32063268 }
32073269 rect = ( ( PdfDictionary ) kids . Get ( 0 ) ) . GetAsArray ( PdfName . Rect ) ;
32083270 }
3209- return rect . ToRectangle ( ) ;
3271+ return rect != null ? rect . ToRectangle ( ) : null ;
32103272 }
32113273
32123274 protected internal static PdfArray ProcessOptions ( String [ ] [ ] options ) {
@@ -3593,27 +3655,29 @@ protected internal virtual void DrawRadioBorder(PdfCanvas canvas, PdfFormXObject
35933655 /// <param name="height">the height of the radio button to draw</param>
35943656 /// <param name="value">the value of the button</param>
35953657 protected internal virtual void DrawRadioAppearance ( float width , float height , String value ) {
3658+ Rectangle rect = new Rectangle ( 0 , 0 , width , height ) ;
3659+ PdfWidgetAnnotation widget = GetWidgets ( ) [ 0 ] ;
3660+ widget . SetNormalAppearance ( new PdfDictionary ( ) ) ;
3661+ //On state
35963662 PdfStream streamOn = ( PdfStream ) new PdfStream ( ) . MakeIndirect ( GetDocument ( ) ) ;
35973663 PdfCanvas canvasOn = new PdfCanvas ( streamOn , new PdfResources ( ) , GetDocument ( ) ) ;
3598- Rectangle rect = new Rectangle ( 0 , 0 , width , height ) ;
35993664 PdfFormXObject xObjectOn = new PdfFormXObject ( rect ) ;
3600- PdfFormXObject xObjectOff = new PdfFormXObject ( rect ) ;
36013665 DrawRadioBorder ( canvasOn , xObjectOn , width , height ) ;
36023666 DrawRadioField ( canvasOn , width , height , true ) ;
3667+ xObjectOn . GetPdfObject ( ) . GetOutputStream ( ) . WriteBytes ( streamOn . GetBytes ( ) ) ;
3668+ widget . GetNormalAppearanceObject ( ) . Put ( new PdfName ( value ) , xObjectOn . GetPdfObject ( ) ) ;
3669+ //Off state
36033670 PdfStream streamOff = ( PdfStream ) new PdfStream ( ) . MakeIndirect ( GetDocument ( ) ) ;
36043671 PdfCanvas canvasOff = new PdfCanvas ( streamOff , new PdfResources ( ) , GetDocument ( ) ) ;
3672+ PdfFormXObject xObjectOff = new PdfFormXObject ( rect ) ;
36053673 DrawRadioBorder ( canvasOff , xObjectOff , width , height ) ;
3674+ xObjectOff . GetPdfObject ( ) . GetOutputStream ( ) . WriteBytes ( streamOff . GetBytes ( ) ) ;
3675+ widget . GetNormalAppearanceObject ( ) . Put ( new PdfName ( "Off" ) , xObjectOff . GetPdfObject ( ) ) ;
36063676 if ( pdfAConformanceLevel != null && ( pdfAConformanceLevel . GetPart ( ) . Equals ( "2" ) || pdfAConformanceLevel . GetPart
36073677 ( ) . Equals ( "3" ) ) ) {
36083678 xObjectOn . GetResources ( ) ;
36093679 xObjectOff . GetResources ( ) ;
36103680 }
3611- PdfWidgetAnnotation widget = GetWidgets ( ) [ 0 ] ;
3612- xObjectOn . GetPdfObject ( ) . GetOutputStream ( ) . WriteBytes ( streamOn . GetBytes ( ) ) ;
3613- widget . SetNormalAppearance ( new PdfDictionary ( ) ) ;
3614- widget . GetNormalAppearanceObject ( ) . Put ( new PdfName ( value ) , xObjectOn . GetPdfObject ( ) ) ;
3615- xObjectOff . GetPdfObject ( ) . GetOutputStream ( ) . WriteBytes ( streamOff . GetBytes ( ) ) ;
3616- widget . GetNormalAppearanceObject ( ) . Put ( new PdfName ( "Off" ) , xObjectOff . GetPdfObject ( ) ) ;
36173681 }
36183682
36193683 /// <summary>Draws the appearance of a radio button with a specified value.</summary>
@@ -3626,10 +3690,12 @@ protected internal virtual void DrawPdfA1RadioAppearance(float width, float heig
36263690 Rectangle rect = new Rectangle ( 0 , 0 , width , height ) ;
36273691 PdfFormXObject xObject = new PdfFormXObject ( rect ) ;
36283692 DrawBorder ( canvas , xObject , width , height ) ;
3629- DrawRadioField ( canvas , rect . GetWidth ( ) , rect . GetHeight ( ) , ! value . Equals ( "Off" ) ) ;
3693+ DrawRadioField ( canvas , rect . GetWidth ( ) , rect . GetHeight ( ) , ! "Off" . Equals ( value ) ) ;
3694+ PdfDictionary normalAppearance = new PdfDictionary ( ) ;
3695+ normalAppearance . Put ( new PdfName ( value ) , xObject . GetPdfObject ( ) ) ;
36303696 PdfWidgetAnnotation widget = GetWidgets ( ) [ 0 ] ;
36313697 xObject . GetPdfObject ( ) . GetOutputStream ( ) . WriteBytes ( stream . GetBytes ( ) ) ;
3632- widget . SetNormalAppearance ( xObject . GetPdfObject ( ) ) ;
3698+ widget . SetNormalAppearance ( normalAppearance ) ;
36333699 }
36343700
36353701 /// <summary>Draws a radio button.</summary>
0 commit comments