@@ -2750,21 +2750,40 @@ public virtual bool RegenerateField() {
2750
2750
}
2751
2751
else {
2752
2752
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 ) ;
2763
2762
}
2764
2763
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 ) ;
2766
2786
}
2767
- widget . SetAppearanceState ( new PdfName ( state ) ) ;
2768
2787
}
2769
2788
}
2770
2789
}
@@ -2812,6 +2831,49 @@ public virtual bool RegenerateField() {
2812
2831
return true ;
2813
2832
}
2814
2833
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
+
2815
2877
/// <summary>According to spec (ISO-32000-1, 12.7.3.3) zero font size should interpretaded as auto size.</summary>
2816
2878
private float NormalizeFontSize ( float fs , PdfFont localFont , PdfArray bBox , String value ) {
2817
2879
if ( fs == 0 ) {
@@ -3206,7 +3268,7 @@ protected internal virtual Rectangle GetRect(PdfDictionary field) {
3206
3268
}
3207
3269
rect = ( ( PdfDictionary ) kids . Get ( 0 ) ) . GetAsArray ( PdfName . Rect ) ;
3208
3270
}
3209
- return rect . ToRectangle ( ) ;
3271
+ return rect != null ? rect . ToRectangle ( ) : null ;
3210
3272
}
3211
3273
3212
3274
protected internal static PdfArray ProcessOptions ( String [ ] [ ] options ) {
@@ -3593,27 +3655,29 @@ protected internal virtual void DrawRadioBorder(PdfCanvas canvas, PdfFormXObject
3593
3655
/// <param name="height">the height of the radio button to draw</param>
3594
3656
/// <param name="value">the value of the button</param>
3595
3657
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
3596
3662
PdfStream streamOn = ( PdfStream ) new PdfStream ( ) . MakeIndirect ( GetDocument ( ) ) ;
3597
3663
PdfCanvas canvasOn = new PdfCanvas ( streamOn , new PdfResources ( ) , GetDocument ( ) ) ;
3598
- Rectangle rect = new Rectangle ( 0 , 0 , width , height ) ;
3599
3664
PdfFormXObject xObjectOn = new PdfFormXObject ( rect ) ;
3600
- PdfFormXObject xObjectOff = new PdfFormXObject ( rect ) ;
3601
3665
DrawRadioBorder ( canvasOn , xObjectOn , width , height ) ;
3602
3666
DrawRadioField ( canvasOn , width , height , true ) ;
3667
+ xObjectOn . GetPdfObject ( ) . GetOutputStream ( ) . WriteBytes ( streamOn . GetBytes ( ) ) ;
3668
+ widget . GetNormalAppearanceObject ( ) . Put ( new PdfName ( value ) , xObjectOn . GetPdfObject ( ) ) ;
3669
+ //Off state
3603
3670
PdfStream streamOff = ( PdfStream ) new PdfStream ( ) . MakeIndirect ( GetDocument ( ) ) ;
3604
3671
PdfCanvas canvasOff = new PdfCanvas ( streamOff , new PdfResources ( ) , GetDocument ( ) ) ;
3672
+ PdfFormXObject xObjectOff = new PdfFormXObject ( rect ) ;
3605
3673
DrawRadioBorder ( canvasOff , xObjectOff , width , height ) ;
3674
+ xObjectOff . GetPdfObject ( ) . GetOutputStream ( ) . WriteBytes ( streamOff . GetBytes ( ) ) ;
3675
+ widget . GetNormalAppearanceObject ( ) . Put ( new PdfName ( "Off" ) , xObjectOff . GetPdfObject ( ) ) ;
3606
3676
if ( pdfAConformanceLevel != null && ( pdfAConformanceLevel . GetPart ( ) . Equals ( "2" ) || pdfAConformanceLevel . GetPart
3607
3677
( ) . Equals ( "3" ) ) ) {
3608
3678
xObjectOn . GetResources ( ) ;
3609
3679
xObjectOff . GetResources ( ) ;
3610
3680
}
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 ( ) ) ;
3617
3681
}
3618
3682
3619
3683
/// <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
3626
3690
Rectangle rect = new Rectangle ( 0 , 0 , width , height ) ;
3627
3691
PdfFormXObject xObject = new PdfFormXObject ( rect ) ;
3628
3692
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 ( ) ) ;
3630
3696
PdfWidgetAnnotation widget = GetWidgets ( ) [ 0 ] ;
3631
3697
xObject . GetPdfObject ( ) . GetOutputStream ( ) . WriteBytes ( stream . GetBytes ( ) ) ;
3632
- widget . SetNormalAppearance ( xObject . GetPdfObject ( ) ) ;
3698
+ widget . SetNormalAppearance ( normalAppearance ) ;
3633
3699
}
3634
3700
3635
3701
/// <summary>Draws a radio button.</summary>
0 commit comments