@@ -2058,6 +2058,52 @@ describe("annotation", function () {
2058
2058
) ;
2059
2059
} ) ;
2060
2060
2061
+ it ( "should save rotated text" , async function ( ) {
2062
+ const textWidgetRef = Ref . get ( 123 , 0 ) ;
2063
+ const xref = new XRefMock ( [
2064
+ { ref : textWidgetRef , data : textWidgetDict } ,
2065
+ helvRefObj ,
2066
+ ] ) ;
2067
+ partialEvaluator . xref = xref ;
2068
+ const task = new WorkerTask ( "test save" ) ;
2069
+
2070
+ const annotation = await AnnotationFactory . create (
2071
+ xref ,
2072
+ textWidgetRef ,
2073
+ pdfManagerMock ,
2074
+ idFactoryMock
2075
+ ) ;
2076
+ const annotationStorage = new Map ( ) ;
2077
+ annotationStorage . set ( annotation . data . id , {
2078
+ value : "hello world" ,
2079
+ rotation : 90 ,
2080
+ } ) ;
2081
+
2082
+ const data = await annotation . save (
2083
+ partialEvaluator ,
2084
+ task ,
2085
+ annotationStorage
2086
+ ) ;
2087
+ expect ( data . length ) . toEqual ( 2 ) ;
2088
+ const [ oldData , newData ] = data ;
2089
+ expect ( oldData . ref ) . toEqual ( Ref . get ( 123 , 0 ) ) ;
2090
+ expect ( newData . ref ) . toEqual ( Ref . get ( 2 , 0 ) ) ;
2091
+
2092
+ oldData . data = oldData . data . replace ( / \( D : \d + \) / , "(date)" ) ;
2093
+ expect ( oldData . data ) . toEqual (
2094
+ "123 0 obj\n" +
2095
+ "<< /Type /Annot /Subtype /Widget /FT /Tx /DA (/Helv 5 Tf) /DR " +
2096
+ "<< /Font << /Helv 314 0 R>>>> /Rect [0 0 32 10] " +
2097
+ "/V (hello world) /AP << /N 2 0 R>> /M (date) /MK << /R 90>>>>\nendobj\n"
2098
+ ) ;
2099
+ expect ( newData . data ) . toEqual (
2100
+ "2 0 obj\n<< /Length 74 /Subtype /Form /Resources " +
2101
+ "<< /Font << /Helv 314 0 R>>>> /BBox [0 0 32 10] /Matrix [0 1 -1 0 32 0]>> stream\n" +
2102
+ "/Tx BMC q BT /Helv 5 Tf 1 0 0 1 0 0 Tm 2 3.04 Td (hello world) Tj " +
2103
+ "ET Q EMC\nendstream\nendobj\n"
2104
+ ) ;
2105
+ } ) ;
2106
+
2061
2107
it ( "should get field object for usage in JS sandbox" , async function ( ) {
2062
2108
const textWidgetRef = Ref . get ( 123 , 0 ) ;
2063
2109
const xDictRef = Ref . get ( 141 , 0 ) ;
@@ -2612,6 +2658,57 @@ describe("annotation", function () {
2612
2658
expect ( data ) . toEqual ( null ) ;
2613
2659
} ) ;
2614
2660
2661
+ it ( "should save rotated checkboxes" , async function ( ) {
2662
+ const appearanceStatesDict = new Dict ( ) ;
2663
+ const normalAppearanceDict = new Dict ( ) ;
2664
+
2665
+ normalAppearanceDict . set ( "Checked" , Ref . get ( 314 , 0 ) ) ;
2666
+ normalAppearanceDict . set ( "Off" , Ref . get ( 271 , 0 ) ) ;
2667
+ appearanceStatesDict . set ( "N" , normalAppearanceDict ) ;
2668
+
2669
+ buttonWidgetDict . set ( "AP" , appearanceStatesDict ) ;
2670
+ buttonWidgetDict . set ( "V" , Name . get ( "Off" ) ) ;
2671
+
2672
+ const buttonWidgetRef = Ref . get ( 123 , 0 ) ;
2673
+ const xref = new XRefMock ( [
2674
+ { ref : buttonWidgetRef , data : buttonWidgetDict } ,
2675
+ ] ) ;
2676
+ partialEvaluator . xref = xref ;
2677
+ const task = new WorkerTask ( "test save" ) ;
2678
+
2679
+ const annotation = await AnnotationFactory . create (
2680
+ xref ,
2681
+ buttonWidgetRef ,
2682
+ pdfManagerMock ,
2683
+ idFactoryMock
2684
+ ) ;
2685
+ const annotationStorage = new Map ( ) ;
2686
+ annotationStorage . set ( annotation . data . id , { value : true , rotation : 180 } ) ;
2687
+
2688
+ const [ oldData ] = await annotation . save (
2689
+ partialEvaluator ,
2690
+ task ,
2691
+ annotationStorage
2692
+ ) ;
2693
+ oldData . data = oldData . data . replace ( / \( D : \d + \) / , "(date)" ) ;
2694
+ expect ( oldData . ref ) . toEqual ( Ref . get ( 123 , 0 ) ) ;
2695
+ expect ( oldData . data ) . toEqual (
2696
+ "123 0 obj\n" +
2697
+ "<< /Type /Annot /Subtype /Widget /FT /Btn " +
2698
+ "/AP << /N << /Checked 314 0 R /Off 271 0 R>>>> " +
2699
+ "/V /Checked /AS /Checked /M (date) /MK << /R 180>>>>\nendobj\n"
2700
+ ) ;
2701
+
2702
+ annotationStorage . set ( annotation . data . id , { value : false } ) ;
2703
+
2704
+ const data = await annotation . save (
2705
+ partialEvaluator ,
2706
+ task ,
2707
+ annotationStorage
2708
+ ) ;
2709
+ expect ( data ) . toEqual ( null ) ;
2710
+ } ) ;
2711
+
2615
2712
it ( "should handle radio buttons with a field value" , async function ( ) {
2616
2713
const parentDict = new Dict ( ) ;
2617
2714
parentDict . set ( "V" , Name . get ( "1" ) ) ;
@@ -3485,6 +3582,67 @@ describe("annotation", function () {
3485
3582
) ;
3486
3583
} ) ;
3487
3584
3585
+ it ( "should save rotated choice" , async function ( ) {
3586
+ choiceWidgetDict . set ( "Opt" , [ "A" , "B" , "C" ] ) ;
3587
+ choiceWidgetDict . set ( "V" , "A" ) ;
3588
+
3589
+ const choiceWidgetRef = Ref . get ( 123 , 0 ) ;
3590
+ const xref = new XRefMock ( [
3591
+ { ref : choiceWidgetRef , data : choiceWidgetDict } ,
3592
+ fontRefObj ,
3593
+ ] ) ;
3594
+ partialEvaluator . xref = xref ;
3595
+ const task = new WorkerTask ( "test save" ) ;
3596
+
3597
+ const annotation = await AnnotationFactory . create (
3598
+ xref ,
3599
+ choiceWidgetRef ,
3600
+ pdfManagerMock ,
3601
+ idFactoryMock
3602
+ ) ;
3603
+ const annotationStorage = new Map ( ) ;
3604
+ annotationStorage . set ( annotation . data . id , { value : "C" , rotation : 270 } ) ;
3605
+
3606
+ const data = await annotation . save (
3607
+ partialEvaluator ,
3608
+ task ,
3609
+ annotationStorage
3610
+ ) ;
3611
+ expect ( data . length ) . toEqual ( 2 ) ;
3612
+ const [ oldData , newData ] = data ;
3613
+ expect ( oldData . ref ) . toEqual ( Ref . get ( 123 , 0 ) ) ;
3614
+ expect ( newData . ref ) . toEqual ( Ref . get ( 2 , 0 ) ) ;
3615
+
3616
+ oldData . data = oldData . data . replace ( / \( D : \d + \) / , "(date)" ) ;
3617
+ expect ( oldData . data ) . toEqual (
3618
+ "123 0 obj\n" +
3619
+ "<< /Type /Annot /Subtype /Widget /FT /Ch /DA (/Helv 5 Tf) /DR " +
3620
+ "<< /Font << /Helv 314 0 R>>>> " +
3621
+ "/Rect [0 0 32 10] /Opt [(A) (B) (C)] /V (C) " +
3622
+ "/AP << /N 2 0 R>> /M (date) /MK << /R 270>>>>\nendobj\n"
3623
+ ) ;
3624
+ expect ( newData . data ) . toEqual (
3625
+ [
3626
+ "2 0 obj" ,
3627
+ "<< /Length 170 /Subtype /Form /Resources << /Font << /Helv 314 0 R>>>> " +
3628
+ "/BBox [0 0 32 10] /Matrix [0 -1 1 0 0 10]>> stream" ,
3629
+ "/Tx BMC q" ,
3630
+ "1 1 10 32 re W n" ,
3631
+ "0.600006 0.756866 0.854904 rg" ,
3632
+ "1 11.75 10 6.75 re f" ,
3633
+ "BT" ,
3634
+ "/Helv 5 Tf" ,
3635
+ "1 0 0 1 0 32 Tm" ,
3636
+ "2 -5.88 Td (A) Tj" ,
3637
+ "0 -6.75 Td (B) Tj" ,
3638
+ "0 -6.75 Td (C) Tj" ,
3639
+ "ET Q EMC" ,
3640
+ "endstream" ,
3641
+ "endobj\n" ,
3642
+ ] . join ( "\n" )
3643
+ ) ;
3644
+ } ) ;
3645
+
3488
3646
it ( "should save choice" , async function ( ) {
3489
3647
choiceWidgetDict . set ( "Opt" , [ "A" , "B" , "C" ] ) ;
3490
3648
choiceWidgetDict . set ( "V" , "A" ) ;
0 commit comments