This file is indexed.

/usr/share/ghostscript/9.06/Resource/Init/pdf_draw.ps is in libgs9-common 9.06~dfsg-2+deb8u7.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 161
 162
 163
 164
 165
 166
 167
 168
 169
 170
 171
 172
 173
 174
 175
 176
 177
 178
 179
 180
 181
 182
 183
 184
 185
 186
 187
 188
 189
 190
 191
 192
 193
 194
 195
 196
 197
 198
 199
 200
 201
 202
 203
 204
 205
 206
 207
 208
 209
 210
 211
 212
 213
 214
 215
 216
 217
 218
 219
 220
 221
 222
 223
 224
 225
 226
 227
 228
 229
 230
 231
 232
 233
 234
 235
 236
 237
 238
 239
 240
 241
 242
 243
 244
 245
 246
 247
 248
 249
 250
 251
 252
 253
 254
 255
 256
 257
 258
 259
 260
 261
 262
 263
 264
 265
 266
 267
 268
 269
 270
 271
 272
 273
 274
 275
 276
 277
 278
 279
 280
 281
 282
 283
 284
 285
 286
 287
 288
 289
 290
 291
 292
 293
 294
 295
 296
 297
 298
 299
 300
 301
 302
 303
 304
 305
 306
 307
 308
 309
 310
 311
 312
 313
 314
 315
 316
 317
 318
 319
 320
 321
 322
 323
 324
 325
 326
 327
 328
 329
 330
 331
 332
 333
 334
 335
 336
 337
 338
 339
 340
 341
 342
 343
 344
 345
 346
 347
 348
 349
 350
 351
 352
 353
 354
 355
 356
 357
 358
 359
 360
 361
 362
 363
 364
 365
 366
 367
 368
 369
 370
 371
 372
 373
 374
 375
 376
 377
 378
 379
 380
 381
 382
 383
 384
 385
 386
 387
 388
 389
 390
 391
 392
 393
 394
 395
 396
 397
 398
 399
 400
 401
 402
 403
 404
 405
 406
 407
 408
 409
 410
 411
 412
 413
 414
 415
 416
 417
 418
 419
 420
 421
 422
 423
 424
 425
 426
 427
 428
 429
 430
 431
 432
 433
 434
 435
 436
 437
 438
 439
 440
 441
 442
 443
 444
 445
 446
 447
 448
 449
 450
 451
 452
 453
 454
 455
 456
 457
 458
 459
 460
 461
 462
 463
 464
 465
 466
 467
 468
 469
 470
 471
 472
 473
 474
 475
 476
 477
 478
 479
 480
 481
 482
 483
 484
 485
 486
 487
 488
 489
 490
 491
 492
 493
 494
 495
 496
 497
 498
 499
 500
 501
 502
 503
 504
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
% Copyright (C) 2001-2012 Artifex Software, Inc.
% All Rights Reserved.
%
% This software is provided AS-IS with no warranty, either express or
% implied.
%
% This software is distributed under license and may not be copied,
% modified or distributed except as expressly authorized under the terms
% of the license contained in the file LICENSE in this distribution.
%
% Refer to licensing information at http://www.artifex.com or contact
% Artifex Software, Inc.,  7 Mt. Lassen Drive - Suite A-134, San Rafael,
% CA  94903, U.S.A., +1(415)492-9861, for further information.
%

% pdf_draw.ps
% PDF drawing operations (graphics, text, and images).

/.setlanguagelevel where { pop 2 .setlanguagelevel } if
.currentglobal //true .setglobal
/pdfdict where { pop } { /pdfdict 100 dict def } ifelse
GS_PDF_ProcSet begin
pdfdict begin

% For simplicity, we use a single interpretation dictionary for all
% PDF graphics operations, even though this is too liberal.
/drawopdict 100 dict def

/SetGroupExtGStateDict
<<
  /AlphaIsShape //AIS
  /FillConstantAlpha //ca
  % We don't have to worry about the enumeration order, even
  % with the color/space settings, since we only store, not
  % not set them.
  /FillColor //sc1
  /FillColorSpace { /FillColorSpace gput } bind
  /FillOverprint //op
  /SoftMask //SMask
  /StrokeConstantAlpha //CA
  /StrokeColor //SC1
  /StrokeColorSpace { /StrokeColorSpace gput } bind
  /StrokeOverprint //OP
  /TextSpacing //Tc
  % We can't use //Tz as we've stored the value we actually use,
  % not value * 100 (see /Tz in pdf_ops.ps)
  /TextHScaling { /TextHScaling gput } bind
  /Leading //TD
  /TextFont { /TextFont gput} bind
  /TextLineMatrix { /TextLineMatrix gput } bind
  /TextMatrix { /TextMatrix gput } bind
  /TextRise { /TextRise gput } bind
  /TextRenderingMode { /TextRenderingMode gput } bind
  /WordSpacing //Tw
>> def

% ================================ Graphics ================================ %

% ---------------- Functions ---------------- %

% Note that resolvefunction converts a PDF Function to a PostScript Function;
% resolve*fnproc converts a PDF function to a PostScript procedure.
% We need to process all required and optional parameters to resolve any
% use of indirect references.

/fnrdict mark
  0 { .resolvefn0 }
  2 { .resolvefn2 }
  3 { .resolvefn3 }
  4 { .resolvefn4 }
.dicttomark readonly def

/.resolvefn0 {
  dup length 1 add dict .copydict	% make room for DataSource
  % now resolve any indirect references
  dup /Size 2 copy knownoget { put } { pop pop } ifelse
  dup /BitsPerSample 2 copy knownoget { put } { pop pop } ifelse
  dup /Order 2 copy knownoget { put } { pop pop } ifelse
  dup /Encode 2 copy knownoget { put } { pop pop } ifelse
  dup /Decode 2 copy knownoget { put } { pop pop } ifelse

                % Don't lose our place in PDFfile.
  PDFfile fileposition exch
  dup //true resolvestream
                % The stream isn't positionable, so read all the data now.
                % Stack: filepos fndict stream
  1 index /Range get length 2 idiv 2 index /BitsPerSample get mul
  2 index /Size get { mul } forall
  7 add 8 idiv
  dup 65535 le {
    string 1 index exch readstring pop
  } {
    1 index exch () /SubFileDecode filter /ReusableStreamDecode filter
  } ifelse
  exch closefile
                % Stack: filepos fndict data
  exch dup /DataSource 4 -1 roll put
  exch PDFfile exch setfileposition
} bdef

/.resolvefn2 {
  dup length dict .copydict
  dup /C0 2 copy knownoget { put } { pop pop } ifelse
  dup /C1 2 copy knownoget { put } { pop pop } ifelse
  dup /N 2 copy knownoget { put } { pop pop } ifelse
} bdef

/.resolvefn3 {
  dup length dict .copydict
  dup /Bounds 2 copy knownoget { put } { pop pop } ifelse
  dup /Encode 2 copy knownoget { put } { pop pop } ifelse
  dup /Functions 2 copy oget mark exch dup {
    oforce .resolvefn
  } forall
  counttomark -1 roll astore exch pop put
} bdef

/.resolvefn4 {
  PDFfile fileposition exch             % filepos fndict
  dup //true resolvestream              % filepos fndict stream
  exch dup length dict copy             % filepos stream fndict2
  dup /Function undef                   % filepos stream fndict2
  exch dup token not {
    () /rangecheck cvx signalerror
  } if
  exch token {
    /rangecheck cvx signalerror
  } if
                % Use .bind to avoid idiom recognition.
  .bind
  1 index /Function 3 -1 roll put
  exch PDFfile exch setfileposition
} bdef

/.resolvefn {		% <fndict> .resolvefn <fndict'>
  dup length dict .copydict
  dup /Domain 2 copy knownoget { put } { pop pop } ifelse
  dup /Range 2 copy knownoget { put } { pop pop } ifelse
  dup /FunctionType oget //fnrdict exch get exec
} bdef

/resolvefunction {	% <fndict> resolvefunction <function>
  .resolvefn
  PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Function: ) print dup === flush } if } if
} bdef

/resolvefnproc {	% <fndict> resolvefnproc <proc>
  resolvefunction .buildfunction
} bdef

/resolveidfnproc {	% <fndict> resolveidfnproc <proc>
  dup /Identity eq { pop { } } { resolvefnproc } ifelse
} bdef

/resolvedefaultfnproc {	% <fndict> <default> resolved'fnproc <proc>
  1 index /Default eq { exch pop } { pop resolveidfnproc } ifelse
} bdef

% ---------------- Shadings ---------------- %

/shrdict mark
  /BBox {
    dup dup dup aload pop normrect_elems
    5 -1 roll astore
  } bind
  /ColorSpace {
    resolvecolorspace
  } bind
  /Function {
    dup type /dicttype eq {
      resolvefunction
    } {
      [ exch { oforce resolvefunction } forall ]
    } ifelse
  } bind
.dicttomark readonly def

/resolveshading {	% <shadingstream> resolveshading <shading>
  dup /.shading_dict .knownget {
    exch pop
    dup /ShadingType get 4 ge {
      dup /DataSource get 0 setfileposition
    } if
  } {
    dup
    PDFfile fileposition exch
    mark exch {
      oforce //shrdict 2 index .knownget { exec } if
    } forall .dicttomark
    dup /ShadingType get 4 ge {
      dup dup //true resolvestream
                % Make a reusable stream so that the shading doesn't
                % reposition PDFfile at unexpected times.
      /ReusableStreamDecode filter /DataSource exch put
    } if
    exch PDFfile exch setfileposition
    dup 3 1 roll /.shading_dict exch put
  } ifelse
} bdef
/resolvesh {		% <shname> resolvesh <shading>
                        % <shname> resolvesh <null>
  Page /Shading rget {
    resolveshading
  } {
    //null
  }ifelse
} bdef

% ---------------- Halftones ---------------- %

/spotfunctions mark
  /Round {
    abs exch abs 2 copy add 1 le {
      dup mul exch dup mul add 1 exch sub
    } {
      1 sub dup mul exch 1 sub dup mul add 1 sub
    } ifelse
  } bind
  /Diamond {
    abs exch abs 2 copy add .75 le {
      dup mul exch dup mul add 1 exch sub
    } {
      2 copy add 1.23 le {
        .85 mul add 1 exch sub
      } {
        1 sub dup mul exch 1 sub dup mul add 1 sub
      } ifelse
    } ifelse
  } bind
  /Ellipse {
    abs exch abs 2 copy 3 mul exch 4 mul add 3 sub dup 0 lt {
      pop dup mul exch .75 div dup mul add 4 div 1 exch sub
    } {
      dup 1 gt {
        pop 1 exch sub dup mul exch 1 exch sub
        .75 div dup mul add 4 div 1 sub
      } {
        .5 exch sub exch pop exch pop
      } ifelse
    } ifelse
  } bind
  /EllipseA { dup mul .9 mul exch dup mul add 1 exch sub } bind
  /InvertedEllipseA { dup mul .9 mul exch dup mul add 1 sub } bind
  /EllipseB { dup 5 mul 8 div mul exch dup mul exch add sqrt 1 exch sub } bind
  /EllipseC { dup mul .9 mul exch dup mul add 1 exch sub } bind
  /InvertedEllipseC { dup mul .9 mul exch dup mul add 1 sub } bind
  /Line { exch pop abs neg } bind
  /LineX { pop } bind
  /LineY { exch pop } bind
  /Square { abs exch abs 2 copy lt { exch } if pop neg } bind
  /Cross { abs exch abs 2 copy gt { exch } if pop neg } bind
  /Rhomboid { abs exch abs 0.9 mul add 2 div } bind
  /DoubleDot { 2 {360 mul sin 2 div exch } repeat add } bind
  /InvertedDoubleDot { 2 {360 mul sin 2 div exch } repeat add neg } bind
  /SimpleDot { dup mul exch dup mul add 1 exch sub } bind
  /InvertedSimpleDot { dup mul exch dup mul add 1 sub } bind
  /CosineDot { 180 mul cos exch 180 mul cos add 2 div } bind
  /Double { exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add } bind
  /InvertedDouble {
    exch 2 div exch 2 { 360 mul sin 2 div exch } repeat add neg
  } bind
.dicttomark readonly def

/.resolveht1 {
  mark exch {
    oforce
    1 index /SpotFunction eq {
      dup type /nametype eq
        { //spotfunctions exch get } { resolvefnproc }
      ifelse
    } {
      1 index /TransferFunction eq {
        resolveidfnproc
      } if
    } ifelse
  } forall .dicttomark
} bdef

/.resolveht5 {
  mark exch {
    oforce dup type /dicttype eq { resolvehalftone } if
  } forall .dicttomark
} bdef

/.resolveht6 {
  mark exch { oforce } forall .dicttomark
  dup dup //false resolvestream /ReusableStreamDecode filter
  /Thresholds exch put
  dup /TransferFunction .knownget {
    resolveidfnproc
    1 index exch /TransferFunction exch put
  } if
} bdef

/htrdict mark
  1 //.resolveht1
  5 //.resolveht5
  6 //.resolveht6
 10 //.resolveht6
 16 //.resolveht6
.dicttomark readonly def

currentdict /.resolveht1 undef
currentdict /.resolveht5 undef
currentdict /.resolveht6 undef

/resolvehalftone {	% <dict> resolvehalftone <halftone>
  dup /HalftoneType oget
  dup //htrdict exch .knownget {
    exch pop exec
  } {
    =string cvs
    (   **** Warning: Incorrect halftone type ) exch concatstrings
    (. Using defailt.\n) concatstrings pdfformaterror
    gsave .setdefaulthalftone currenthalftone grestore
  } ifelse
} bdef

% ---------------- Graphics state management ---------------- %

/cmmatrix matrix def
drawopdict begin
                        % Graphics state stack
  /q { q } def
  /Q { Q } def
                        % Graphics state setting
  /cm { //cmmatrix astore
        .getpath
        exch concat
        newpath { exec } forall
        % If inside a BT/ET block, we need to update the TextSaveMatrix
        currentdict /TextSaveMatrix .knownget {
          //cmmatrix exch dup concatmatrix pop
        } if
      } bdef

  /i { 1 .min setflat } bdef
  /J { setlinecap } bind 0 get def
  /d { setdash } bind 0 get def
  /j { setlinejoin } bind 0 get def
  /w { setlinewidth } bind 0 get def
  /M { 1 .max setmiterlimit } bdef
  /gs { gs } def
end

% Each entry in this dictionary is
%	<gsres> <value> -proc- <gsres>
/gsbg {
  /BGDefault load resolvedefaultfnproc setblackgeneration
} bdef
/gsucr {
  /UCRDefault load resolvedefaultfnproc setundercolorremoval
} bdef
/gstr {
  dup type /arraytype eq {
    { oforce /TRDefault load resolvedefaultfnproc } forall
    setcolortransfer
  } {
    /TRDefault load resolvedefaultfnproc settransfer
  } ifelse
} bdef
/gsparamdict mark
  /SA { setstrokeadjust }
  /OP { 1 index /op known not { dup op } if OP }
        % The PDF 1.3 specification says that the name /Default is only
        % recognized for {BG,UCR,TR}2.  However, PDF 1.3 files produced
        % by Adobe Acrobat Distiller 4.0 for Windows use the name /Default
        % with the older keys, so we have to implement this.
  /BG { 1 index /BG2 known { pop } { gsbg } ifelse }
  /UCR { 1 index /UCR2 known { pop } { gsucr } ifelse }
  /TR { 1 index /TR2 known { pop } { gstr } ifelse }

  % Some functions used to implement phases of HT and HTP
  /sethalftones {
    dup /Default eq {
      pop .setdefaulthalftone
    } {
      resolvehalftone sethalftone
    } ifelse
  } bdef
  /sethalftonephases {
    /sethalftonephase where { pop aload pop sethalftonephase } { pop } ifelse
  } bdef

  /HT {
    dup sethalftones .swapcolors sethalftones .swapcolors
    % the transfer function may dependent on the halftone, so make sure
    % it is set if included in the graphic state (otherwise this is
    % subject to order of a dictionary forall, which is unpredictable)
    dup /TR2 .knownget {
      dup /Default eq { oforce gsparamdict /TR2 get exec } { pop } ifelse
    } {
      dup /TR .knownget {
        /dup /Default eq { oforce gsparamdict /TR get exec } { pop } ifelse
      } if
    } ifelse
  }
  /HTP {
    % HTP may be present even if this isn't a DPS interpreter.
    dup sethalftonephases .swapcolors sethalftonephases .swapcolors
  }
        % PDF 1.3
  % The font is an indirect reference, not a resource name
  /Font { aload pop exch oforce resourcefont exch Tf }
  /LW { setlinewidth }
  /LC { setlinecap }
  /LJ { setlinejoin }
  /ML { 1 .max setmiterlimit }
  /D { aload pop setdash }
  /RI { ri }
  /op { op }
  /OPM { OPM }
  /BG2 { gsbg }
  /UCR2 { gsucr }
  /TR2 { gstr }
  /FL { 1 .min setflat }
  /SM {
        % SM may be present even if this is only a Level 2 interpreter.
    /setsmoothness where { pop setsmoothness } { pop } ifelse
  }
        % PDF 1.4
        % All of these require the "transparency" feature in the interpreter.
  /ca { ca }
  /CA { CA }
  /SMask { gssmask }
  /AIS { AIS }
  /BM { BM }
  /TK { TK }
.dicttomark readonly def
/gs {			% <gsres> gs -
  Page /ExtGState rget {
        % We keep the dictionary on the stack during the forall so that
        % keys that interact with each other have access to it.
    dup {
      oforce exch gsparamdict exch .knownget { exec } { pop } ifelse
    } forall pop
  } if
} bdef

% ------ Transparency support ------ %

/gssmask {
  {
    dup /None eq 1 index //null eq or PDFusingtransparency not or {
      pop //null exit
    } if
        % Preprocess the SMask value into a parameter dictionary for
        % .begintransparencymaskgroup, with added /BBox and /Draw keys.
    mark exch		% Stack: mark smaskdict
    dup /S oget /Subtype exch 3 2 roll
                        % Stack: mark ... smaskdict
    dup /BC knownoget {
      dup /Background exch 4 2 roll
      1 index /G oget /Group knownoget not {
        (   **** Warning: Dropping transparency group XObject without /Group attribute.\n)
        pdfformaterror
        cleartomark //null exit
      } if
      gsave //nodict begin
        /CS knownoget {
          resolvecolorspace dup setgcolorspace csput
        } if
        aload pop setcolor [ currentgray ]
      end grestore
      /GrayBackground exch 3 2 roll
    } if
    dup /TR knownoget {
      dup /Identity eq {
        pop
      } {
        resolvefnproc /TransferFunction exch 3 2 roll
      } ifelse
    } if
    dup /G oget dup /BBox oget /BBox exch 4 2 roll
    % Because we don't execute the group form stream until we find
    % out whether we're actually going to draw through it, we need
    % to save the current gstate with the other parameters, so
    % we can subsequently execute it in the correct graphics state.
    /GroupGState gstate currentgstate 6 2 roll
    /GroupMat matrix currentmatrix 8 2 roll
    /GroupExtGState 1 dict
    //SetGroupExtGStateDict
    {
      exch dup where
      {
        exch get 2 index 3 1 roll put
      }
      {
        pop pop
      } ifelse
    } forall
    10 2 roll
    /.execmaskgroup cvx 2 packedarray cvx /Draw exch 3 2 roll
    pop
    .dicttomark
    exit
  } loop
  SMask
} bdef

% Functions specific to the Device* colorspaces to force the switch to
% the Device* colorspace so that the SMask will not get a CIEBased* colorspace
% in the case when UseCIEColor changes the Device* colorspace to something else.
% Also see the logic in pdf_main.ps:pdfopen that similarly defines these resources.
/forceDefaultCS <<
  {
    currentcolorspace setcolorspace	% this will switch to Device colorspace
  } bind
  /DeviceGray exch
  /DeviceRGB 1 index
  /DeviceCMYK 1 index
>>
def

% This procedure is called to actually render the soft mask.
/.execmaskgroup {	% <masknum> <paramdict> <formdict> .execmaskgroup -
    % Save our place in PDFfile. Do not use gsave-grestore when creating
    % a soft mask with .begintransparencygroup because high level devices
    % need to modify the graphic state by storing the soft mask ID.
    % Save the ExtGState (//nodict begin) BEFORE changing the colorspace
  //nodict begin
  matrix currentmatrix 4 1 roll
  mark currentcolor counttomark dup 4 add exch roll pop
  currentcolorspace 4 1 roll .getuseciecolor 4 1 roll

  % We can't simply set the group's gstate here because
  % we can't use gsave/grestore. So we actually set it
  % in .execgroup. But the matrix needs set here for
  % .begintransparencymaskgroup to correctly work.
  % It might seem we should also set the colorspace
  % in case the group doesn't have one, *but* empirical
  % suggests that is not the case - fts_26_2600.pdf and
  % fts_26_2603.pdf render incorrectly if we set the
  % colrospace
  1 index /GroupMat .knownget { setmatrix } if

  PDFfile fileposition 4 1 roll
        % We have to select the group's color space so that the
        % background color will be interpreted correctly.
        % [save/restore]DefaultCS make sure that the SMask logic sees
        % the Device* spaces, not CIEBased* that UseCIEColor may have
        % established.
  //false .setuseciecolor	% SMask gets processed without UseCIEColor
  dup /Group oget /CS knownoget {
    resolvecolorspace dup setgcolorspace csput
    //true		% use currentcolorspace
  } {
    % inheriting the colorspace -- make sure Device* spaces are not CIEBased
    forceDefaultCS currentcolorspace 0 get .knownget { exec } if
    //false		% no defined colorspace
  } ifelse
  3 -1 roll dup
  dup 4 1 roll /BBox get aload pop .begintransparencymaskgroup {
    exch dup /Resources knownoget { oforce } { 2 dict } ifelse
    3 -1 roll dup /GroupGState .knownget { 2 index /GroupGState 3 -1 roll put} if
    /GroupExtGState .knownget { 1 index /GroupExtGState 3 -1 roll put} if
    exch //false resolvestream
    .execgroup .endtransparencymask
  } stopped {
    .discardtransparencymask stop
  } if
  PDFfile exch setfileposition
  .setuseciecolor setcolorspace setcolor
  setmatrix
  end	% restore colorspace, color and ExtGState (end)
} bdef

% Paint a Form+Group XObject, either for a transparency mask or for a Do.
/.execgroup {		% <resdict> <stream> .execgroup -
  pdfemptycount 3 1 roll
  /pdfemptycount count 3 sub store
  gsave //nodict begin

  % We have to set the gstate correctly for lazy evaluation of a softmask group.
  % we also must preserve the color(space) as setup in .execmaskgroup.
  % This stuff must be done here, as .execmaskgroup can't use gsave/grestore to
  % manipulate the gstates, due to the requirements of .begintransparencymaskgroup.
  % We also must set the ExtGState values.
  % It may seem redundant to do the color(space) twice (once here and once in
  % .execmaskgroup) but we have to set it in .execmaskgroup for the background
  % color and set it here once in the correct gstate.
  mark currentcolor currentcolorspace counttomark 2 add index dup
  /GroupGState .knownget { setgstate } if
  /GroupExtGState .knownget { { exch exec } forall } if
  setcolorspace setcolor pop
  newpath //null SMask
  1 .setopacityalpha 1 .setshapealpha
  1 CA 1 ca
  /Compatible .setblendmode
        % Execute the body of the Form, similar to DoForm.
  pdfopdict .pdfruncontext
  end grestore
  /pdfemptycount exch store
} bdef

/.beginformgroup {	% groupdict bbox .beginformgroup -
  exch mark exch			% bbox mark groupdict
  dup /CS knownoget { resolvecolorspace dup setgcolorspace /CS exch 3 2 roll} if
  dup /I knownoget { /Isolated exch 3 2 roll } if
  dup /K knownoget { /Knockout exch 3 2 roll } if
  pop .dicttomark
                % Stack: bbox paramdict
  exch aload pop
  .begintransparencygroup
} bdef

% .paintgroupform implements the Form PaintProc in the case where the
% Form XObject dictionary includes a Group key.  See .paintform below.
/.paintgroupform {	% <resdict> <stream> <formdict> .paintgroupform -
  dup /Group oget exch /BBox oget
                % Stack: resdict stream groupdict bbox
  .beginformgroup {
    .execgroup
  } stopped {
    .discardtransparencygroup stop
  } if .endtransparencygroup
} bdef

% Make an ImageType 103 (soft-masked) image.
/makesoftmaskimage {	% <datasource> <imagemask> <SMask> makesoftmaskimage
                        %   <datasource> <imagemask>, updates currentdict =
                        %   imagedict
                % See the ImageType 3 case of makemaskimage below.
                % SMask is a stream, another Image XObject.
                % Stack: datasource imagemask(false) smaskstreamdict
  PDFfile fileposition exch
  dup /Matte knownoget { /Matte exch def } if
  dup length dict makeimagedict pop
                % In order to prevent the two data sources from being
                % aliased, we need to make at least one a reusable stream.
                % We pick the mask, since it's smaller (in case we need to
                % read all its data now).
                % Stack: datasource imagemask(false) savedpos
                % maskdict is currentdict
  /DataSource DataSource mark
    /Intent 1
    /AsyncRead //true
  .dicttomark .reusablestreamdecode def
  PDFfile exch setfileposition
  currentdict end currentdict end
  5 dict begin
  /ImageType 103 def
  /DataDict exch def
  dup /InterleaveType 3 put
  DataDict /Matte knownoget {
    /Matte exch def
  } if
  AlphaIsShape { /ShapeMaskDict } { /OpacityMaskDict } ifelse exch def
  /ColorSpace DataDict /ColorSpace get def
} bdef

% ---------------- Color setting ---------------- %

/01_1 [0 1] readonly def
/01_3 [0 1 0 1 0 1] readonly def
/01_4 [0 1 0 1 0 1 0 1] readonly def

% The keys here are resolved (PostScript, not PDF) color space names.
/csncompdict 9 dict begin
  /DeviceGray { pop 1 } bdef
  /DeviceRGB { pop 3 } bdef
  /DeviceCMYK { pop 4 } bdef
  /CIEBasedA //DeviceGray def
  /CIEBasedABC //DeviceRGB def
  /CalGray //DeviceGray def
  /CalRGB //DeviceRGB def
  /Lab //DeviceRGB def
  /ICCBased { 1 oget /N oget } bdef
  /Separation //DeviceGray def
  /DeviceN { 1 oget length } bdef
  /Indexed  //DeviceGray def
currentdict end readonly def

% <colorspace> csncomp <n>
/csncomp {
  dup dup type /arraytype eq { 0 oget } if
  //csncompdict exch get exec
} bdef

currentdict /csncompdict undef

/ICCBased-resolve {
  PDFfile fileposition exch
  dup dup 1 oget
  mark exch { oforce } forall .dicttomark
  dup dup //true resolvestream
  /ReusableStreamDecode filter /DataSource exch put
  1 exch put
  exch PDFfile exch setfileposition
  % Resolve alternate color space
  dup 1 get			% Get colorspace dictionary
  dup /Alternate .knownget {	% Check for alternate color space
    oforce resolvecolorspace /Alternate exch put 	% resolve and replace
  } {
    pop 			% remove colorspace dictionary
  } ifelse
} bdef

/csrdict 13 dict begin
  /DeviceGray { } bdef
  /DeviceRGB { } bdef
  /DeviceCMYK { } bdef

  /CalGray { 1 oget [ exch /CalGray exch ] } bdef
  /CalRGB { 1 oget [ exch /CalRGB exch ] } bdef
  /Lab { 1 oget [ exch /Lab exch ] } bdef

  /CalCMYK {
    pop /DeviceCMYK		% not defined by Adobe
  } bdef

  /ICCBased {
    dup 1 get type /dicttype ne {	% don't resolve more than once
      ICCBased-resolve
    } if
  } bdef

  /Separation {
    aload pop exch oforce resolvecolorspace
                % Contrary to PDF manuals up to v.1.5, Acrobat Distiller 3.01
                % can use /Identity name here instead of a function.
    exch oforce resolveidfnproc
    4 array astore
  } bdef

  /DeviceN {
    [ exch aload pop ]			% Copy into a new array
    dup dup 1 oget			% Resolve Names array
    [ exch { oforce } forall ]		% resolve each of the names
    1 exch put
    dup dup 2 oget resolvecolorspace
    2 exch put
    dup dup 3 oget resolvefnproc
    3 exch put
    dup length 4 gt {			% Check for attributes dict
      dup dup 4 oget			% devn_array devn_array attr_dict
      dup /Colorants knownoget		% Check for Colorants Dict
        {	% Create a new attribute dict with only a Colorants dict entry.
                % Resolve all of the Colorant dict entries.  This is needed
                % to prevent a conflict if we attempt to resolve the tint
                % transform functions of the Colorant color spaces multiple
                % times.
          exch pop			% Remove old attributes dict
          << exch			% Start new attributes dict
                % Build new Colorants dict with resolved entries
          << exch { oforce resolvecolorspace } forall >>
          /Colorants exch >>		% Finish new attributes dict
        } if
      4 exch put			% Put resolved or new attributes dict
    } if
  } bdef

  /Indexed {
    aload pop 3 -1 roll oforce resolvecolorspace
                % Stack: /Indexed hival lookup basespace
                % If the underlying space is a Lab space, we must scale
                % the output of the lookup table as part of DecodeABC.
    dup dup type /arraytype eq { 0 get } if /CIEBasedABC eq {
      dup 1 get /DecodeLMN known {
        1 get dup length dict copy
        begin /DecodeABC [ 0 2 4 {
          RangeABC 1 index 1 add get RangeABC 2 index get sub /mul load
          RangeABC 3 index get /add load
          DecodeABC 6 -1 roll 2 idiv get [ 6 1 roll aload pop ] cvx
        } for ] def
        /RangeABC //01_3 def
        currentdict end /CIEBasedABC exch 2 array astore
      } if
    } if
    3 1 roll  % Stack: /Indexed csp comp table 
    oforce dup type /stringtype ne {
                % The color lookup table is a stream.
                % Get its contents.  Don't lose our place in PDFfile.
                % Stack: /Indexed basespace hival lookup
        PDFfile fileposition 5 1 roll 
        dup /Filter oknown not { % For Bug691941.pdf and similar lossage
          dup /Length knownoget not { 0 } if
        } {
          0 
        } ifelse
                % Stack: filepos /Indexed basespace hival lookup Length
        2 index 1 add
                % Stack: filepos /Indexed basespace hival lookup Length len
        4 index csncomp mul .max string 
                % Stack: filepos /Indexed basespace hival lookup (...)
        exch //true resolvestream 
        1 index readstring not { 
          % The string is padded with 0s
          (   **** Warning: Short look-up table in the Indexed color space was padded with 0's.\n)
          pdfformaterror
        } if
        pop
                % Stack: filepos /Indexed basespace hival (...)
        PDFfile 6 -1 roll setfileposition
    } if 
    4 array astore
                % Stack: [filepos /Indexed basespace hival (...)]
                % Replace the PDFColorSpace with the Indexed space if needed.
    dup 1 get
    dup type /arraytype eq {
      dup length 2 ge {
        dup 1 get type /dicttype eq {
          dup 1 get /PDFColorSpace known {
            dup 1 get /PDFColorSpace 3 index put
          } if
        } if
      } if
    } if pop
  } bdef

  /I { % Bug 689815
    (   **** Warning: The name /Indexed cannot be abbreviated to /I in the color space\n)
    pdfformaterror
    dup 0 /Indexed put
    //Indexed exec
  } bdef

  /Pattern {
    dup type /nametype ne {
      dup length 1 gt {
        1 oget resolvecolorspace
        /Pattern exch 2 array astore
      } if
    } if
  } bdef

currentdict end readonly def

/cssubst {		% <csname> cssubst <cspace'> true
                        % <csname> cssubst false
  dup resolvecolorspace
  dup 1 index ne { exch pop //true } { pop pop //false } ifelse
} bdef

/csnames mark
  /DeviceGray dup  /DeviceRGB dup  /DeviceCMYK dup  /Pattern dup
.dicttomark readonly def
/csresolve {		% <csresourcename> csresolve <cspace> <true> | <false>
  dup type /nametype ne {
    (\n   **** Warning: CS/cs (setcolorspace) operand not a name: ) pdfformaterror
    dup stderrfile dup 3 -1 roll write==only flushfile
    ( ****\n) pdfformaterror
    dup type /arraytype eq {	% Adobe InDesign + PDF Library has array
      resolvecolorspace
    } if //true
  } {
    dup Page /ColorSpace rget {
      exch pop resolvecolorspace //true
    } {
      //csnames 1 index known {
        //true
      } { 
        (   **** Warning: Undefined space resource: /)
        exch .namestring concatstrings (\n) concatstrings pdfformaterror
        //false
      } ifelse
    } ifelse
  } ifelse
} bdef
/resolvecolorspace {	% <cspace> resolvecolorspace <cspace'>
  dup type /dicttype eq { dup /N known } { //false } ifelse {
      (   **** ICCBased color space is a bare stream dictionary\n)
      pdfformaterror
      [ /ICCBased 3 -1 roll ] ICCBased-resolve exec
  } {
    dup dup type /arraytype eq { 0 get } if
    //csrdict exch .knownget  {
      exec dup type /nametype ne { dup length 1 eq { 0 get } if } if
    } {
      dup type /nametype eq {
        csresolve not { /DeviceRGB } if   % Arbitrary
      } { 
        csset exch pop 
      } ifelse
    } ifelse
  } ifelse
} bdef

/scresolve {	% <c0> ... scresolve <multi>
                % We can't really make sc[n] and SC[N] work, because
                % the color space information isn't available at
                % conversion time; so we hack it by assuming that
                % all the operands on the stack are used, and that
                % if the top operand is a name, it's a Pattern resource.
  dup type /nametype eq
    { Page /Pattern rget { resolvepattern } { //null } ifelse }
  if
  dup type /dicttype eq {
                % Check the PaintType, if any (shading patterns don't
                % have one).
    dup /PaintType knownoget { 2 eq } { //false } ifelse
  } {
    .pdfcount 1 gt
  } ifelse
} bdef

/.pdfpaintproc {         % <patdict> <resdict> .pdfpaintproc -
  PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Begin PaintProc) print dup === flush } if } if
  PDFfile fileposition 3 1 roll
  q
  1 index /PaintType oget 1 eq {
    % For colored patterns, set default fill and stroke colors.
    0 g 0 G
  } {
    % For uncolored patterns, we have to unbind the current
    % color and color space before running the PaintProc.
    //null sc1 //null SC1
  } ifelse

  % Save old values on opstack, set pdfemptycount to new value.
  pdfemptycount countdictstack mark
  
  /pdfemptycount count 3 sub def 5 3 roll
  %
  % Stack: ... <old emptycount> <dictcount> mark <patdict> <resdict>
  %                                                  |
  %           New empty count points here -----------+

  exch //false resolvestream pdfopdict .pdfruncontext
  cleartomark
  
  //false
  { countdictstack 
    2 index le { exit } if
    currentdict /n known not or
    Q
  } loop {
    (   **** Warning: Pattern stream has unbalanced q/Q operators \(too many q's\)\n)
    pdfformaterror
  } if
  pop

  % restore pdfemptycount
  /pdfemptycount exch def

  Q
  PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%End PaintProc) print dup === flush } if } if
  PDFfile exch setfileposition
} bdef

/resolvepattern {	% <patternstreamdict> resolvepattern <patterndict>
                % Don't do the resolvestream now: just capture the data
                % from the file if necessary.
  dup length dict copy
  dup /FilePosition .knownget {
    1 index /File get dup fileposition 3 1 roll
                % Stack: dict savepos pos file
    dup 3 -1 roll setfileposition
    dup 3 index /Length knownoget {
      dup 65535 le {
        dup 0 eq {
          pop pop ()
        } {
          string readstring pop
        } ifelse
      } {
        () /SubFileDecode filter /ReusableStreamDecode filter
      } ifelse
    } {
      0 (endstream) /SubFileDecode filter /ReusableStreamDecode filter
    } ifelse
                % Stack: dict savepos file string
    3 1 roll exch setfileposition
    1 index /File 3 -1 roll put
    dup /FilePosition undef
  } if
  dup /Shading knownoget {
    resolveshading 1 index /Shading 3 -1 roll put
  } if
  dup /PaintProc [
                % Bind the resource dictionary into the PaintProc.
    2 index /Resources knownoget { oforce } { 0 dict } ifelse
    /.pdfpaintproc cvx
  ] cvx put
  dup /BBox 2 copy knownoget { normrect put } { pop pop } ifelse
  dup /.pattern_uses_transparency  1 index patternusestransparency put
  PDFDEBUG { pdfdict /PDFSTEPcount .knownget { 1 le } { //true } ifelse { (%Pattern: ) print dup === flush } if } if
} bdef

/ignore_color_op  (   **** Warning: Ignoring a color operation in a cached context.\n) readonly def

drawopdict begin
  /g  { .incachedevice { % Bug 689302
          pop //ignore_color_op pdfformaterror
        } {
          /DeviceGray cssubst { cs sc1 } { g } ifelse
        } ifelse
      } bdef

  /rg { .incachedevice {
          pop pop pop //ignore_color_op pdfformaterror
        } {
          /DeviceRGB cssubst { cs sc* } { rg } ifelse
        } ifelse
      } bdef

  /k  { .incachedevice {
          pop pop pop pop //ignore_color_op pdfformaterror
        } {
          k
        } ifelse
      } bdef

  /cs { .incachedevice {
          pop //ignore_color_op pdfformaterror
        } {
          csresolve { cs } if
        } ifelse
      } bdef

  /sc { .incachedevice {
          .pdfcount { pop } repeat //ignore_color_op pdfformaterror
        } {
          scresolve { sc* } { sc1 } ifelse
        } ifelse
      } bdef

  /scn /sc load def

  /G  { .incachedevice {
          pop //ignore_color_op pdfformaterror
        } {
          /DeviceGray cssubst { CS SC1 } { G } ifelse
        } ifelse
      } bdef

  /RG { .incachedevice {
          pop pop pop //ignore_color_op pdfformaterror
        } {
          /DeviceRGB cssubst { CS SC* } { RG } ifelse
        } ifelse
      } bdef

  /K  { .incachedevice {
          pop pop pop pop //ignore_color_op pdfformaterror
        } {
          K
        } ifelse
      } bdef

  /CS { .incachedevice {
          pop //ignore_color_op pdfformaterror
        } {
          csresolve { CS } if
        } ifelse
      } bdef

  /ri { .incachedevice {
          pop //ignore_color_op pdfformaterror
        } {
          ri
        } ifelse
      } bdef

  /SC { .incachedevice {
          .pdfcount { pop } repeat //ignore_color_op pdfformaterror
        } {
          scresolve { SC* } { SC1 } ifelse
        } ifelse
      } bdef

  /SCN /SC load def
end

currentdict /ignore_color_op undef

% ---------------- Paths ---------------- %

drawopdict begin
                        % Path construction
  /m { moveto } bind 0 get def
  /l { { lineto } stopped { pop pop } if } bdef
  /c { { curveto } stopped { pop pop pop pop pop pop } if } bdef
  /v { { currentpoint } stopped { pop pop pop pop } { 6 2 roll curveto } ifelse } bdef
  /y { 2 copy { curveto } stopped { pop pop pop pop pop pop } if } bdef
  /re {
   4 2 roll moveto  exch dup 0 rlineto  0 3 -1 roll rlineto  neg 0 rlineto
   closepath
  } bdef
  /h { closepath } bind 0 get def
                        % Path painting and clipping
  /n { n } def
  /S { S } def
  /s { s } def
  /f { f } def
  /f* { f* } def
  /B { B } def
  /b { b } def
  /B* { B* } def
  /b* { b* } def
  /W { W } def
  /W* { W* } def

  /sh_save 1 array def
  /sh_group  << /Subtype /Group /Isolated //true >> readonly def
  /sh {
      OFFlevels length 0 eq {
        setfillstate resolvesh
        //sh_save 0 save put
        SoftMask //null ne {
          //sh_group
          1 index /BBox knownoget {
            { oforce } forall
          } {
            gsave clippath pathbbox grestore
          } ifelse
          .begintransparencygroup
        } if
        0 .setoverprintmode
        dup /.shading .knownget {
          exch
          pop
        } {
          .buildshading
        } ifelse
        { .shfill } stopped { 
          pop 
          (   **** Warning: Dropping incorrect smooth shading object.\n)
          pdfformaterror
        } if
        SoftMask //null ne { .endtransparencygroup } if
        //sh_save 0 get restore
      } {
        pop
      } ifelse
    } bdef
  currentdict dup /sh_save undef /sh_group undef
end

% ---------------- XObjects ---------------- %

/xobjectprocs mark		% <dict> -proc- -
  /Image { DoImage }
  /Form { DoForm }
  /PS { DoPS }
.dicttomark readonly def

% Note that the keys in defaultdecodedict are resolved (PostScript, not PDF)
% color space names.
/defaultdecodedict mark
  /DeviceGray { pop //01_1 } bind
  /DeviceRGB { pop //01_3 } bind
  /DeviceCMYK { pop //01_4 } bind
  /CIEBasedA { 1 get /RangeA knownoget not { //01_1 } if } bind
  /CIEBasedABC { 1 get /RangeABC knownoget not { //01_3 } if } bind
  /CalGray { pop //01_1 } bind
  /CalRGB { pop //01_3 } bind
  /Lab { 1 get /Range knownoget not { [-100 100 -100 100] } if } bind
  /ICCBased {
     1 oget dup /Range knownoget {
       exch pop
     }{
       /N get [ exch {0 1} repeat ] readonly
     } ifelse
  } bind
  /Separation { pop //01_1 } bind
  /DeviceN {
    1 oget length [ exch {0 1} repeat ] readonly
  } bind
  /Indexed {
    pop [ 0 1 BitsPerComponent bitshift 1 sub ]
  } bind
.dicttomark readonly def

/checkaltimage {	% <resdict> checkaltimage <resdict[']>
  Printed {
    dup /Alternates knownoget {
      {
        dup /DefaultForPrinting knownoget {
          {
            /Image oget exch pop exit
          } {
            pop
          } ifelse
        } {
          pop
        } ifelse
      } forall
    } if
  } if
} bdef

% <string> <index> getu16 <integer>
/getu16 {
  2 copy get 8 bitshift 3 1 roll 1 add get add
} bind def

% <string> <index> getu32 <integer>
/getu32 {
  2 copy getu16 16 bitshift 3 1 roll 2 add getu16 add
} bind def

/jp2_csp_dict mark
  12 { /DeviceCMYK }       % CMYK
  14 { /Lab }              % LAB
  16 { /sRGBICC /ColorSpace findresource } bind
  17 { /sGrayICC /ColorSpace findresource } bind
  18 3 index               % YCC is converted to RGB
% 19                       % CIEJab not supportec by PDF 1.7
% 20                       % e-sRGB
% 21                       % ROMMRGB
% 24                       % e-sYCC
.dicttomark readonly def

% Process jp2 blocks (aka boxes). All procedures have the signature
% <file> <length> -> ... <file> <flush_length>
/jp2_tag_dict 10 dict begin

  /jp2h { % descend into a sub-stream, don't return.
    () /SubFileDecode filter 0
  } bdef

  /ihdr {
    14 sub                                   % file len-14
    1 index (1234567890abcd) readstring pop  % file len-14 (14)
    /JPXComponents 1 index 8 getu16          % file len-14 (14) /JPXComponents NC
    def                                      % file len-14 (14)
    10 get 16#7F and 1 add
    dup 12 eq { pop 16 } if
    /BitsPerComponent exch def               % file len-14
  } bdef

  /colr {
    currentdict /ColorSpace known not {
      3 sub
      1 index (123) readstring pop      % file len-3 (3)
      0 get dup 1 eq {
        pop 4 sub                          % file len-7
        1 index (1234) readstring pop    % file len-16 (4)
        0 getu32                           % file len-16 enum
        //jp2_csp_dict exch .knownget {
          exec /ColorSpace exch def        % file len-7
        } {
          (   **** Warning: Unknown enumerated color space in JPX stream.\n)
          pdfformaterror
        } ifelse
      } {
        dup 2 eq exch 3 eq or {
          1 index exch () /SubFileDecode filter /ReusableStreamDecode filter
          /JPXICC exch def
          0                                % file 0
        } {
          (   **** Warning: Unknown color space method in JPX stream.\n)
          pdfformaterror
        } ifelse
      } ifelse
    } if
  } bdef

  % Palette colors are decoded by the library.
  % For now, ignore 'pclr' table.
  /pclr { } bdef

  /cdef {
    pop
    dup (12) readstring pop
    0 getu16 {
      dup (123456) readstring pop
      2 getu16
      dup 3 lt {
        { /JPXColors /JPXOpacity /JPXPremult } exch get
          currentdict 1 index .knownget { 1 add } { 1 } ifelse def
      } {
        pop
      } ifelse
    } repeat
    0
  } bdef

currentdict end readonly def

% Parse jp2 file format to get color space and image depth info.
% <file> get_jp2_csp -
/get_jp2_csp {
  {
    dup (01234567) readstring pop        % f (LBoxTBox)
    dup length 8 lt {
      pop exit
    } if
    dup 4 4 getinterval exch             % f (TBox) (LBoxTBox)
    0 getu32                             % f (TBox) LBox
    dup 0 eq {
      pop pop exit % cannot happen
    } {
      dup 1 eq {
        pop 1 index (01234567) readstring pop
        4 getu32                         % f (TBox) LBox
        16 sub
      } {
        8 sub
      } ifelse
    } ifelse                             % f (TBox) LBox-8..16

    PDFDEBUG {
      2 copy 2 packedarray //== exec            % f (TBox) LBox-8..16
    } if

    //jp2_tag_dict 3 -1 roll .knownget {
      exec
    } if                                  % f flush

    dup 0 ne {
      1 index exch                        % f f flush
      () /SubFileDecode filter flushfile % skip unwanted blocks
    } {
      pop
    } ifelse
  } loop
  pop
} bind def

currentdict /jp2_tag_dict .undef
currentdict /jp2_csp_dict .undef

% Add a key-value pair to the last /DecodeParms dictionary
% Copy the objects to avoid spoiling shared ones.
% <resdict> <key> <value> -> <resdict>
/add-to-last-param {
  2 index /DecodeParms knownoget {
    dup {} eq {
      pop //false
    } {
      //true
    } ifelse
  } {
    //false
  } ifelse {
    dup type /arraytype eq {
      [ exch { oforce } forall
        dup //null eq { pop 1 dict } if
      ]
      dup dup length 1 sub get           % <resdict> <key> <value> []   <<>>
    } {
      dup length 1 add dict copy dup     % <resdict> <key> <value> <<>> <<>>
    } ifelse
    4 2 roll put                         % <resdict> obj
  } {
                                         % <resdict> <key> <value>
    mark 3 1 roll .dicttomark            % <resdict> obj
    1 index /Filter knownoget {
      dup type /arraytype eq {
        length array                     % <resdict> obj [...]
        dup dup length 1 sub             % <resdict> obj [...] [...] len-1
        4 -1 roll put                    % <resdict> [... obj]
      } {
        pop 
      } ifelse
    } if
  } ifelse
  1 index exch
  /DecodeParms exch put                  % <resdict>
} bdef

/last-ditch-bpc-csp {
  currentdict /BitsPerComponent oknown not {
    (   **** Warning: image has no /BitsPerComponent key; assuming 8 bit.\n)
    pdfformaterror
    /BitsPerComponent 8 def
  } if

  currentdict /ColorSpace knownoget not {
    dup /ColorSpace knownoget not {
      (   **** Warning: image has no /ColorSpace key; assuming /DeviceRGB.\n)
      pdfformaterror
      /DeviceRGB
    } if
  } if
  resolvecolorspace /ColorSpace exch def
} bdef

/get-smask-in-data { % <dict> -> <int>
  /SMaskInData knownoget {
    dup dup 1 ne exch 2 ne and {
      pop 0
    } if
  } {
    0
  } ifelse
} bdef

/makeimagedict {	% <resdict> <newdict> makeimagedict <imagemask?>
                        % On return, newdict' is currentdict
  begin
  /Width 2 copy oget def
  /Height 2 copy oget def
                % Handle missing BitsPerComponent later.
  /BitsPerComponent 2 copy knownoget { def } { pop } ifelse
  /Interpolate 2 copy knownoget { def } { pop } ifelse
  makeimagekeys
} bdef

/makeimagekeys {	% <resdict> makeimagekeys <imagemask>
                % newdict is currentdict
                % Assumes Width, Height, BPC, Interpolate already copied.
  /ImageType 1 def
  /ImageMatrix Width 0 0
                % Handle 0-height images specially.
    Height dup 0 eq { pop 1 } if neg 0 1 index neg
    6 array astore def
  dup /ImageMask knownoget dup { and } if {
                % Image mask
                % Decode is required for the PostScript image operators.
                % AI8 writes bogus decode array [0 1 0 0 0 0 0 0]
    /Decode 2 copy knownoget { 0 2 getinterval } { //01_1 } ifelse def
                % BitsPerComponent is optional for masks.
    /BitsPerComponent 2 copy known { pop } { 1 def } ifelse
                % Even though we're going to read data,
                % pass false to resolvestream so that
                % it doesn't try to use Length (which may not be present).
    //false resolvestream /DataSource exch def
    //true
  } {
                % Opaque image
    dup /Filter knownoget {
      dup type /arraytype eq {
        dup length
        dup 0 gt {
          1 sub get oforce
        } {
          pop
        } ifelse
      } if
      /JPXDecode eq
    } {
      //false
    } ifelse { % /JPXDecode tricks
      dup /ColorSpace oknown
      1 index /BitsPerComponent oknown and not {
        % JPXDecode filters can omit the /ColorSpace and /BitsPerComponent
        % keys, in which case the interpreter must retrieve this information
        % from inside the compressed stream.
        dup /IDFlag known {
          (   **** Warning: PDF spec bans inline JPX images.\n) pdfformaterror
          % Inline stream is not positionable. Cannot get ColorSpace.
        } {
          % Drop the last filter (JPXDecode) from the pipeline
          dup dup length dict copy
          dup /Filter oget
          dup type /arraytype eq {
            dup length 1 gt {
              dup length 1 sub 0 exch getinterval
              1 index exch /Filter exch put

              dup /DecodeParms knownoget {
                dup type /arraytype eq {
                  dup length 1 gt {
                    dup length 1 sub 0 exch getinterval
                    1 index exch /DecodeParms exch put
                  } {
                    pop
                    dup /DecodeParms undef
                  } ifelse
                } {
                  pop
                  dup /DecodeParms undef
                } ifelse
              } if
            } {
              pop
              dup /Filter undef
              dup /DecodeParms undef
            } ifelse
          } {
            pop
            dup /Filter undef
            dup /DecodeParms undef
          } ifelse

          //false resolvestream get_jp2_csp

          currentdict /ColorSpace oknown not {
            currentdict /JPXICC .knownget {
               [ /ICCBased mark
                   /DataSource 5 -1 roll
                   /N currentdict /JPXColors .knownget not {
                     currentdict /JPXComponents get
                   } if
                 .dicttomark
               ] /ColorSpace exch def
            } if
          } if

          { /JPXICC /JPXColors /JPXComponents /JPXOpacity /JPXPremult } {
            currentdict exch undef
          } forall

        } ifelse
      } if % fi missing csp, bpc

      //last-ditch-bpc-csp exec

      dup /ColorSpace oknown {
        % Propagate known color space to the filter
        /ColorSpace currentdict /ColorSpace get //add-to-last-param exec
      } if

      /Decode 2 copy knownoget not {
        ColorSpace //defaultdecodedict
        ColorSpace dup type /arraytype eq { 0 get } if get exec
      } if def

      dup get-smask-in-data dup 0 ne {
        PDFusingtransparency {
          currentdict dup length dict copy begin
          {/Mask/SMask/SMaskInData/Name} { currentdict exch undef } forall
          2 eq {
            /Matte [ Decode length 2 idiv { 0 } repeat ] def
          } if
          /Decode //01_1 def
          /ColorSpace /DeviceGray def
          {/File /FilePosition /Filter /Length /DecodeParms /FFilter /FDecodeParms } {
            2 copy knownoget {
              def
            } {
              pop
            } ifelse
          } forall
          currentdict /Alpha //true //add-to-last-param exec pop
          /SMask currentdict end def
        } {
          pop
        } ifelse
      } {
        pop
      } ifelse
    } { % not JPX image
      //last-ditch-bpc-csp exec
      /Decode 2 copy knownoget not {
        ColorSpace //defaultdecodedict
        ColorSpace dup type /arraytype eq { 0 get } if get exec
      } if def

    } ifelse % fi JPX tricks

                % Even though we're going to read data,
                % pass false to resolvestream so that
                % it doesn't try to use Length (which may not be present).
    //false resolvestream /DataSource exch def
    //false
  } ifelse
} bdef

currentdict /add-to-last-param undef
currentdict /last-ditch-bpc-csp undef

/DoImage {
  checkaltimage dup length 6 add dict  % <<image>> <<>>
  1 index /SMask knownoget {           % <<image>> <<>> <<sm>>  
    dup 3 index ne {                   % <<image>> <<>> <<sm>> <<sm>>
      1 index exch /SMask exch put
    } {
      pop
      (   **** Warning: ignoring recursive /SMask attribute.\n) pdfformaterror
    } ifelse
  } if
  1 index /Mask knownoget { 1 index exch /Mask exch put } if
  makeimagedict doimagesmask
} bdef
/makemaskimage {	% <datasource> <imagemask> <Mask> makemaskimage
                        %   <datasource> <imagemask>, updates currentdict =
                        %   imagedict
  dup type /arraytype eq {
    /ImageType 4 def
                % Check that every element of the Mask is an integer.
    //false 1 index {
      type /integertype ne or
    } forall {
      oforce_array
      //false 1 index {
        type /integertype ne or
      } forall {
        (\n   **** Warning: Some elements of Mask array are not integers.\n)
        pdfformaterror
        [ exch { 0.5 add cvi } forall ]  % following AR4, 5, 6 implementation
      } if
    } if
      % Check elements of array are within 0::(2**BitsPerComponent)-1
      % This is a PostScript error, but AR tries to fix the Mask.
    1 BitsPerComponent bitshift 1 sub //false 2 index {
      % stack: max_value result_bool value
      dup 0 lt exch 3 index gt or or
    } forall exch pop {
      (   **** Warning: Some elements of Mask array are out of range.\n)
      pdfformaterror
      
      ColorSpace dup type /arraytype eq { 0 oget } if /Indexed eq 
      BitsPerComponent 1 eq and {
        % AR9 treats Indexed 1 bpc images specially. Bug 692852.
        dup 0 oget
        dup 0 lt exch 1 BitsPerComponent bitshift ge or {
          % First component is invalid - AR9 ignores the mask
          pop //null
        } {
          % Second component is invalid; AR9 replaces it with 1.
          [ exch 0 oget 1 ]
        } ifelse
      } {
        % AR5, AR9 do this for most cases. Bug 690786.
        [ exch { 1 BitsPerComponent bitshift 1 sub and } forall ]
      } ifelse
    } if
    dup //null ne {
      /MaskColor exch def
    } {
      pop
      /ImageType 1 def
    } ifelse
  } {
                % Mask is a stream, another Image XObject.
                % Stack: datasource imagemask(false) maskstreamdict
    PDFfile fileposition exch
    dup length dict makeimagedict pop
                % In order to prevent the two data sources from being
                % aliased, we need to make at least one a reusable stream.
                % We pick the mask, since it's smaller (in case we need to
                % read all its data now).
                % Stack: datasource imagemask(false) savedpos
                % maskdict is currentdict
    /DataSource DataSource mark
      /Intent 1
      /AsyncRead //true
    .dicttomark .reusablestreamdecode def
    PDFfile exch setfileposition
    currentdict end currentdict end
    5 dict begin
    /ImageType 3 def
    /InterleaveType 3 def
    /DataDict exch def
    /MaskDict exch def
    /ColorSpace DataDict /ColorSpace get def
  } ifelse
} bdef

/doimagesmask { % <imagemask> doimagesmask -
  PDFusingtransparency {
    currentdict /SMask knownoget
  } {
    //false
  } ifelse
  {	% We are doing transparency and SMask is present in the image
        % stack: <imagemask> <SMask>
    currentdevice 1 dict dup /PreserveSMask dup put .getdeviceparams
    dup type /booleantype eq not {cleartomark false}{3 1 roll cleartomark}ifelse
%    currentdevice .devicename /pdfwrite eq
    {
      pop	% pdfwrite will process SMask directly during 'doimage'
    } {
      .begintransparencymaskimage
      PDFfile fileposition exch
      gsave //nodict begin
      //null /SoftMask gput
      1 .setopacityalpha 1 .setshapealpha
      1 CA 1 ca
      /Compatible .setblendmode
      DoImage
      end grestore
      PDFfile exch setfileposition
      0 .endtransparencymask
    } ifelse
    << /Subtype /Group /Isolated //true
      /.image_with_SMask //true % pdfwrite needs : see gs/src/ztrans.c, gs/src/gdevpdft.c
    >> 0 0 1 1 .begintransparencygroup
    doimage
    .endtransparencygroup
  } {
    SoftMask //null ne {
      % the image doesn't have an SMask, but the ExtGState does, force a group.
      << /Subtype /Group /Isolated //true >> 0 0 1 1 .begintransparencygroup
      doimage
      .endtransparencygroup
    }
    { doimage }
    ifelse
  } ifelse
} bdef

% For development needs we define a special option for running with a new handler
% for images with a soft mask.
//systemdict /NEW_IMAGE3X .knownget not { //false } if {
  /doimagesmask { % <imagemask> doimagesmask -
    doimage
  } bdef
} if

/is_big_mask {  % - is_big_mask <bool>
  1 0 dtransform dup mul exch dup mul sqrt add
  0 1 dtransform dup mul exch dup mul sqrt add mul
  currentdevice getdeviceprops .dicttomark /BufferSpace .knownget not {
    4000000 % hack: Can't get the real default value from C source.
  } if
  2 % arbitrary
  div gt
} bind def

% For development needs we define a special option for running with a new handler
% for images with a soft mask.
//systemdict /NEW_IMAGE3X .knownget not { //false } if {
  /is_big_mask {  % - is_big_mask <bool>
    //false
  } bdef
} if

/doimage {	% <imagemask> doimage -
                % imagedict is currentdict, gets popped from dstack
  DataSource exch
  PDFusingtransparency
  currentdevice 1 dict dup /PreserveSMask dup put .getdeviceparams
  dup type /booleantype eq not {cleartomark false}{3 1 roll cleartomark}ifelse not
%  currentdevice .devicename /pdfwrite ne
  {
    % This is a temporary workaround for the bug 689080,
    % which is done under a rush of 8.63 release.
    % The purpose is to disable a conversion of an image with soft mask
    % into a Type 103 image, which currently allocates a full mask buffer
    % before writing clist.
    % With this workaround the Matte color is not working (ignored).
    is_big_mask not
  } {
    //true % pdfwrite doesn't need the workaround explained above,
           % and cannot work with it.
  } ifelse
 and {
    currentdict /SMask knownoget
  } {
    //false
  } ifelse {
    makesoftmaskimage
  } {
    currentdict /Mask knownoget {
      makemaskimage
    } if
  } ifelse
                % Stack: datasource imagemask
   { currentdict end setfillstate { imagemask } }
   { ColorSpace setgcolorspace currentdict end setfillblend { image } }
  ifelse
  PDFSTOPONERROR { exec //false } { stopped } ifelse {
    dup type /dicttype eq { pop } if % Sometimes image fails to restore the stack
    $error /errorname get dup /ioerror eq {
      pop (\n   **** Warning: File has insufficient data for an image.\n)
      pdfformaterror
    } {
      (\n   **** Warning: File encountered ')
      exch 40 string cvs concatstrings
      (' error while processing an image.\n) concatstrings
      pdfformaterror
    } ifelse
  } if
                % Close the input stream, unless it is PDFfile or
                % PDFsource.
  dup dup PDFfile eq exch PDFsource eq or { pop } { closefile } ifelse
} bdef

/.paintform {	% <formdict> <resdict> <stream> .paintform -
  3 -1 roll dup /Group known PDFusingtransparency and {
    .paintgroupform
  } {
    pop pdfopdict .pdfruncontext
  } ifelse
} bdef

/DoForm {
    % Adobe 2nd edition of the PDF 1.3 spec makes /FormType
    % and /Matrix keys optional. Cope with the missing keys.
  begin <<
  currentdict /FormType known not { /FormType 1 } if
  currentdict /Matrix   known not { /Matrix { 1 0 0 1 0 0 } cvlit } if
  currentdict end { oforce } forall
  >>
  dup [ 2 index /Resources knownoget { oforce } { 0 dict } ifelse
  3 index //false /resolvestream cvx
  /.paintform cvx
  ] cvx /PaintProc exch put
    % Adjust pdfemptycount since we have an extra dictionary on the stack
  pdfemptycount countdictstack  3 -1 roll
  /pdfemptycount count 3 sub store
  /q cvx /execform cvx 5 -2 roll 4 .execn
  % Restore pdfemptycount
  0
  { countdictstack 
    2 index le { exit } if
    currentdict /n known not { 1 add } if
    Q
  } loop 
  1 gt {
    (   **** Warning: Form stream has unbalanced q/Q operators \(too many q's\)\n)
    pdfformaterror
  } if
  pop
  /pdfemptycount exch store
} bdef

/_dops_save 1 array def

/DoPS {
  DOPS
   {
     //_dops_save 0 save put
     //true resolvestream cvx exec
     //_dops_save 0 get restore
   }
   { pop }
  ifelse
} bdef

currentdict /_dops_save undef

/ocg_pocs 4 dict begin
  /AllOn {
    //true exch {
      oforce dup type /dicttype eq {
        /OFF known not and
      } {
        pop
      } ifelse
    } forall
  } bdef
  /AnyOn {
    //false exch {
      oforce dup type /dicttype eq {
        /OFF known not or
      } {
        pop
      } ifelse
    } forall
  } bdef
  /AnyOff {
    //AllOn exec not
  } bdef
  /AllOff {
    //AnyOn exec not
  } bdef
currentdict end readonly def

% Check whether OCG or OCMD is visible
% <dict> oc-is-visible <bool>
/ocg-is-visible {
  dup /Type knownoget {
    /OCMD eq {
      dup /OCGs knownoget not { {} } if      % OC OCGs
      dup type /dicttype eq { 1 array astore } if
      //true 1 index { //null eq and } forall {
         pop pop //true  % all nulls => show
      } {
        exch /P knownoget not { /AnyOn } if  % OCGs P
        //ocg_pocs exch get exec             % bool
      } ifelse
    } {
      /OFF known not % OFF is inserted by process_trailer_attrs
    } ifelse
  } {
    /OFF known not % OFF is inserted by process_trailer_attrs
  } ifelse
} bdef

drawopdict begin
  /Do {                                              % /Name
    setfillblend
    PDFfile fileposition exch                      % pos /Name
    dup Page /XObject rget {
      exch pop                                     % pos obj
      OFFlevels length 0 eq {
        dup /OC knownoget { ocg-is-visible } { //true } ifelse
      } {
        //false
      } ifelse {
        dup /Subtype get //xobjectprocs exch get   % pos obj {proc}
        % Don't leave extra objects on the stack while executing
        % the definition of the form.
        3 -1 roll                                  % obj {proc} pos
        2 .execn                                   % pos
      } {
        pop                                        % pos
      } ifelse
    } {
        % This should cause an error, but Acrobat Reader can
        % continue, so we do too.
      (   **** Undefined XObject resource: )
      exch =string cvs concatstrings (\n) concatstrings
      pdfformaterror
    } ifelse
    PDFfile exch setfileposition
  } bdef
end

currentdict /xobjectprocs .undef
currentdict /ocg_pocs .undef

% ---------------- In-line images ---------------- %

% Undo the abbreviations in an in-line image dictionary.
% Note that we must look inside array values.
% /I is context-dependent.
/unabbrevkeydict mark
  /BPC /BitsPerComponent  /CS /ColorSpace  /D /Decode  /DP /DecodeParms
  /F /Filter  /H /Height  /I /Interpolate  /IM /ImageMask  /W /Width
.dicttomark readonly def
/unabbrevvaluedict mark
  /AHx /ASCIIHexDecode  /A85 /ASCII85Decode  /CC /CalCMYK
  /CCF /CCITTFaxDecode  /CG /CalGray  /CR /CalRGB
  /DCT /DCTDecode  /CMYK /DeviceCMYK  /Fl /FlateDecode
  /G /DeviceGray  /RGB /DeviceRGB
  /I /Indexed  /LZW /LZWDecode  /RL /RunLengthDecode
.dicttomark readonly def
/unabbrevtypedict mark
  /nametype {
    //unabbrevvaluedict 1 index .knownget { exch pop } if
  }
  /arraytype {
    dup 0 1 2 index length 1 sub {
      2 copy get unabbrevvalue put dup
    } for pop
  }
.dicttomark readonly def
/unabbrevvalue {	% <obj> unabbrevvalue <obj'>
  oforce //unabbrevtypedict 1 index type .knownget { exec } if
} bdef

/is_space_dict << 0 0 9 9 10 10 12 12 13 13 32 32 >> readonly def

drawopdict begin
  /BI { mark } bdef
  /ID {
    counttomark 2 idiv dup 7 add dict begin {
      exch //unabbrevkeydict 1 index .knownget { exch pop } if
      exch unabbrevvalue def
    } repeat pop
    /IDFlag //true def  % flag for stream processing.
    /File PDFsource def
    currentdict makeimagekeys
    OFFlevels length 0 eq {
      doimage
    } {
      Width
      1 index /ImageMask knownoget dup { and } if not {
        1 index /ColorSpace oget csncomp mul
        BitsPerComponent mul
      } if
      7 add 8 idiv Height mul
      DataSource exch () /SubFileDecode filter flushfile
      end
    } ifelse
        % The Adobe documentation says that the data following ID
        % consists of "lines", and some PDF files (specifically, some files
        % produced by PCL2PDF from Visual Software) contain garbage bytes
        % between the last byte of valid data and an EOL.
        % Some files (PDFOUT v3.8d by GenText) have EI immediately following
        % the stream. Some have no EOL and garbage bytes.
        % Sometimes (bug 690300) CCITTDecode filter consumes 'E' in 'EI'.
        % Therefore, we search for <start>I<sp|end> or <start|sp>EI<sp|end>
    PDFsource read not {
      /ID cvx /syntaxerror signalerror
    } if
    dup 73 eq {
      pop 10 69 73     % Seed to: <sp>EI
    } {
      10 10 3 -1 roll  % Seed to: <sp><sp><any>
    } ifelse
    { PDFsource read not dup { 10 exch } if
      //is_space_dict 2 index known
      3 index 73 eq and 4 index 69 eq and
      //is_space_dict 6 index known and {
        pop pop pop pop pop exit
      } {
          {
            pop pop pop /ID cvx /syntaxerror signalerror
          } {
            4 -1 roll pop
          } ifelse
      } ifelse
    } loop
  } bdef
end

currentdict /is_space_dict undef

% ================================ Text ================================ %

drawopdict begin
                        % Text control
  /BT { BT } def
  /ET { ET } def
  /Tc { Tc } def
  /TL { TL } def
  /Tr { Tr } def
  /Ts { Ts } def
  /Tw { Tw } def
  /Tz { Tz } def
                        % Text positioning
  /Td { Td } def
  /TD { TD } def
  /Tm { Tm } def
  /T* { T* } def
                        % Text painting
  /Tj { Tj } def
  /' { ' } def
  /" { " } def
  /TJ { TJ } def

  /Tform { Tform } def  % Text formatting and painting for AcroForm
                        % without appearance streams.
end

% ======================= Invalid operators ============================ %

drawopdict begin
  /QBT {
    Q BT
    (   **** Warning: invalid operator QBT processed as Q BT .\n)
    pdfformaterror  % Bug 690089
  } def

  /. {
    0.
    (   **** Warning: invalid operator . processed as number 0. .\n)
    pdfformaterror  % Bug 690730
  } def
end

% ============================== Annotations ============================== %

% Create links from separate widget annotations to the parent field nodes.
% Surprisingly, separate widget annotations don't have a link to the parent
% from which they inherit some data.
/link_widget_annots { % <<parent>> <<kid>> -> <<parent>> <<kid>>
  dup /Kids knownoget {
    { oforce
      dup type /dicttype eq {
        link_widget_annots
      } if
      pop
    } forall
  } if
  dup /Parent oknown not {
    2 copy exch /ParentField exch put
  } if
} bdef

% Get and normalize an annotation's rectangle.
/annotrect {		% <annot> annotrect <x> <y> <w> <h>
  /Rect oget aload pop
  exch 3 index sub dup 0 lt { dup 5 -1 roll add 4 1 roll neg } if
  exch 2 index sub dup 0 lt { dup 4 -1 roll add 3 1 roll neg } if
} bdef

% Set an annotation color.
/annotsetcolor {	% <annot> annotsetcolor -
  /C knownoget { aload pop setrgbcolor } { 0 setgray } ifelse
} bdef

% Draw the border.  Currently, we ignore requests for beveling, and we
% don't round the corners of rectangles.
/strokeborder {		% <annot> <width> <dash> strokeborder -
  1 index 0 ne {	% do not draw if border width is 0
    gsave
    2 index annotsetcolor
    0 setdash dup setlinewidth
    exch annotrect
    2 { 4 index sub 4 1 roll } repeat
    2 { 4 index 0.5 mul add 4 1 roll } repeat
    rectstroke pop
    grestore
  } {
    pop pop pop
  } ifelse
} bdef

% Draw an annotation border.
/drawborder {		% <annot> drawborder -
  gsave
  dup /BS known 1 index /Border known or {
    dup /BS knownoget {
      dup type /dicttype ne   % <annot> <border> <bad?>
    } {
      dup /Border oget
      dup type /arraytype eq {
        dup length 3 lt
      } {
        //true
      } ifelse                % <annot> [border] <bad?>
    } ifelse {
      (   **** Warning: Wrong annotation border object, no border is drawn.\n)
      pdfformaterror
      pop { 0 0 0 }
    } if
    dup type /dicttype eq {
      dup /W knownoget not { 1 } if
      % Per PDF1.6 Reference table 8.13, /W in the border style dictionary is
      % expressed in points (an absolute unit), so compensate here for any
      % scaling of the PostScript user space done due to /UserUnit.
      % Scaling due to -dPDFFitPage is not undone, to keep the correct border width
      % compared to the size of the surrounding marks.
      //systemdict /NoUserUnit .knownget not { //false } if not
      //systemdict /PDFFitPage known not and {	% UserUnit is ignored if -dPDFFitPage
        Page /UserUnit knownoget { div } if
      } if
      {} 2 index /S knownoget {
        /D eq { 2 index /D knownoget not { {3} } if exch pop } if
      } if 3 -1 roll pop strokeborder
    } {
      dup 2 get
      exch dup length 3 gt { 3 get } { pop {} } ifelse
      strokeborder
    } ifelse
  } {
    1 {} strokeborder
  } ifelse
  grestore
} bdef

%
%   The PDF annotation F (flags) integer is bit encoded.
%   Bit 1 (LSB) Invisible:  1 --> Do not display if no handler.
%         Note:  We have no handlers but we ignore this bit.
%   Bit 2 Hidden:  1 --> Do not display.  We will not display if this bit is set.
%   Bit 3 Print:  1 --> Display if printing.  We will display if this bit set
%         (and not hidden) and Printed is true
%   Bit 4 NoZoom:  1 --> Do not zoom annotation even if image is zoomed.
%   Bit 5 NoRotate:  1 --> Do not rotate annotation even if image is rotated.
%   Bit 6 NoView:  0 --> Display if this is a 'viewer'.  We will display
%         if this bit is not set (and not hidden) and Printed is false
%   Bit 7 Read Only - 1 --> No interaction.  We ignore this bit
%
%   AR8 and AR9 print 3D annotations even if Print flag is off. Bug 691486.
%
/annotvisible {			% <annot> annotvisible <visible>
  dup /Subtype knownoget { /3D eq } { //false } ifelse % 3D annot
  exch /F knownoget not { 0 } if  % Get flag value
  dup 2 and 0 eq {
    /Printed load {
      4 and 4 eq or               % Printed or 3D
    } {
      32 and 0 eq exch pop        % not NoView
    } ifelse
  } {
    pop pop //false                            % Hidden
  } ifelse
} bdef

/set_bc_color <<
 1 { 0 get oforce setgray } bind
 3 { { oforce } forall setrgbcolor } bind
 4 { { oforce } forall setcmykcolor } bind
>> readonly def

% Get an inherited attribute from a node through /Parent and /ParentField
% links. The latter is set at start-up to access parents of annotations and
% defaults at AcroForm.
/fget	% <field> <key> fget <value> -true-
 {	% <field> <key> fget -false-
   {
     2 copy knownoget {
       exch pop exch pop //true exit
     } {
       exch
       dup /Parent knownoget {
         exch pop exch
       } {
         /ParentField knownoget {
           exch
         } {
           pop //false exit
         } ifelse
       } ifelse
     } ifelse
   } loop
 } bind def

% <annot> foo <annot>
/make_tx_da {
  dup /AP << /N 10 dict dup cvx begin >> put
  /Subtype /Form def
  /BBox [ 0 0 4 index /Rect oget { oforce } forall  3 -1 roll sub abs 3 1 roll sub abs exch ] def
  /Resources 1 index /DR fget not { 0 dict } if def
  /File 1 index /V fget not { () } if length
     2 index /DA fget not { () } if length add
     500 add 65535 .min  string dup 3 1 roll def
  /NullEncode filter    % <annot> file

  dup (BT ) writestring
  1 index /DA fget not { () } if
  [ exch
    { token {
        dup /Tf eq {
          2 index 0 eq {
            /BBox load 3 get
            0.75 mul   % empirical constant
            4 -1 roll pop 3 1 roll
          } if
        } if
        exch
      } {
        exit
      } ifelse
    } loop
  ]
  { 1 index exch write== } forall
  dup 2 index /MaxLen fget not { 0 } if write=
  dup 2 index /V fget not { () } if write==
  dup 2 index /Ff fget not { 0 } if write=
  dup 2 index /Q fget not { 0 } if write=
  dup (Tform ET) write=
  dup .fileposition /Length exch def
  /File File 0 Length getinterval def
  closefile             % <annot>
  end
} bdef

/can-regenerate-ap { % <annot> -> <bool>
  //false exch
  NeedAppearances {
    dup /FT fget {
      /Tx eq {
        dup /V oknown {
          dup /DA fget {
            pop pop not 1
          } if
        } if
      } if
    } if
  } if
  pop 
} bdef

/drawwidget {			% <scalefactor_x> <scalefactor_y> <annot> drawwidget -
  dup /UpdatedAP known not {
    dup can-regenerate-ap {
      dup /AP undef
    } if
  } if
  dup /AP knownoget {
    dup /N known not {
      (   **** Appearance dictionary (AP) lacks the mandatory normal (N) appearance.\n)
      pdfformaterror
    } if
    //false
    [/N /R /D] {
        % stack: scalex scaley annot appearance false key
      2 index exch knownogetdict {
        exch not exit
      } if
    } forall
        % stack: scalex scaley annot appearance value true
        % stack: scalex scaley annot appearance false
    dup {
      pop exch pop
                % Acrobat Distiller produces files in which this Form
                % XObject lacks Type and Subtype keys.  This is illegal,
                % but Acrobat Reader accepts it.  The only way we can
                % tell whether this is a Form or a set of sub-appearances
                % is by testing for the stream Length or File key.
                % If the stream lacks Length key, try File key.
      dup /Length knownoget { type /integertype eq } { //false } ifelse 
      1 index /File knownoget { type /filetype eq or } if {
                % If this is a form then simply use it
        //true
      } {
        1 index /AS knownoget not {
                % If we do not have AS then use any appearance
          { exch pop oforce exit } forall //true
        } {
                % Stack: annot Ndict AS
                % Get the specified appearance.  If no appearance, then
                % display nothing - set stack = false.
          knownoget
        } ifelse
      } ifelse
    } {
      exch pop	% discard useless AP dictionary
    } ifelse

                % Stack: scalex scaley annot appearance true
                % Stack: scalex scaley annot false
    {
                % Draw appearance
                % Initialize graphic following "7.4.4 Appearance Streams"
      q graphicsbeginpage textbeginpage
      1 index annotrect pop pop translate
      3 index 3 index scale	% Apply scale factors
      dup /BBox knownoget {
        1 index /Matrix knownoget not { {1 0 0 1 0 0} } if
        .bbox_transform pop pop
        % Compensate for non-zero origin of BBox
        neg exch neg exch translate
      } if
      DoForm Q
    } if
  } {
    dup /MK knownoget {    % mk
      dup /BG knownoget {  % mk bg
        dup length         % mk bg len
        //set_bc_color exch .knownget {
           gsave
           exec
           3 index 3 index scale
           1 index annotrect rectfill
           grestore
        } {
          pop
        } ifelse
      } if
      dup /BC knownoget {
        dup length
        //set_bc_color exch .knownget {
           gsave
           exec
           1 setlinewidth
           3 index 3 index scale
           1 index annotrect rectstroke
           grestore
        } {
          pop
        } ifelse
      } if
      pop
    } if

    dup can-regenerate-ap {
      make_tx_da
      dup /UpdatedAP //true put
      3 copy drawwidget
    } if
  } ifelse
  pop pop pop
} bdef

currentdict /set_bc_color undef

%  For annotation object we have to determine the size of the output rectangle
%  and the size of the BBox for the form XObject. From these we calculate
%  a scale factors for drawing it.
/calc_annot_scale {		% <annot> calc_annot_scale <x_scale> <y_scale>
  dup /Rect knownoget {
    pop dup annotrect 4 2 roll pop pop	 % get width height size in user space
    3 -1 roll /AP knownoget {
      /N knownogetdict {
        dup /Matrix knownoget not { {1 0 0 1 0 0} } if
        exch /BBox knownoget {  % x y  {matrix} [box]
          exch .bbox_transform  % x y  x0 y0 x1 y1
          3 -1 roll sub         % x y  x0 x1 y1-y0
          3 1 roll exch sub     % x y  y1-y0 x1-x0
          2 copy mul 0 eq {
            (   **** Warning: /BBox has zero width or height, which is not allowed.\n)
            pdfformaterror
            pop pop pop pop 1 1	% zero size -- revert to unity scaling
          } {
            3 1 roll div        % x x1-x0 y/(y1-y0)
            3 1 roll div        % y/(y1-y0) x/(x1-x0)
            exch                % x/(x1-x0) y/(y1-y0)
          } ifelse
        } {
          pop pop pop 1 1	% default to unity scaling
        } ifelse		% if we have /BBox
      } {
        pop pop 1 1
      } ifelse			% if we have /N
    } {
      pop pop 1 1
    } ifelse			% if we have /AP
  } {
    (   **** Warning: /Annot dict is missing required /Rect entry.\n)
    pdfformaterror
    pop 1 1
  } ifelse
} bdef

% Draw an annotation.
/drawannottypes 20 dict begin

  % x0 y0 x1 y1 x2 y2 x3 y3 -> x0 y0 x1-x0 y1-y0 x2-x0 y2-y0
  /quadpoints2basis {
    8 { oforce 8 1 roll } repeat

    % The text is oriented with respect to the vertex with the smallest
    % y value (or the leftmost of those, if there are two such vertices)
    % (x0, y0) and the next vertex in a counterclockwise direction
    % (x1, y1), regardless of whether these are the first two points in
    % the QuadPoints array.

    2 {
      2 index 1 index eq {
        3 index 2 index gt {
          4 2 roll
        } if
      } {
        2 index 1 index gt {
          4 2 roll
        } if
      } ifelse
      8 4 roll
    } repeat
    6 index 3 index gt {
      8 4 roll
    } if

    %  ^
    %  |
    %  * (x2,y2)    * (x3,y3)
    %  |
    %  |
    %  *------------*->
    %  (x0,y0)      (x1,y1)

    pop pop           % x0 y0 x1 y1 x2 y2
    4 index sub exch  % x0 y0 x1 y1 y2-y0 x2
    5 index sub exch  % x0 y0 x1 y1 x2-x0 y2-y0
    4 2 roll
    4 index sub exch  % x0 y0 x2-x0 y2-y0 y1-y0 x1
    5 index sub exch  % x0 y0 x2-x0 y2-y0 x1-x0 y1-y0
    4 2 roll          % x0 y0 x1-x0 y1-y0 x2-x0 y2-y0
  } bdef

  /Link { % <annot> -> <false>
    dup drawborder dup calc_annot_scale 3 -1 roll drawwidget //false
  } bdef

  /Ink { % <annot> -> <annot> <true>
         % <annot> -> <false>
    dup /AP oknown {
      //true
    } {
      1 setlinewidth
      1 setlinecap
      1 setlinejoin
      dup annotsetcolor
      dup calc_annot_scale
      3 index annotrect pop pop translate
      scale
      /InkList knownoget {
        { oforce
          mark exch { oforce } forall
          .pdfinkpath
          stroke
        } forall
      } if
      //false
    } ifelse
  } bdef

  /Underline {
    dup /AP oknown {
      //true
    } {
      0 setlinecap
      dup annotsetcolor
      dup calc_annot_scale scale

      /QuadPoints knownoget {
        aload length 8 idiv {
          //quadpoints2basis exec

          % Acrobat draws the line at 1/7 of the box width from the bottom
          % of the box and 1/16 thick of the box width. /Rect is ignored.

          2 copy dup mul exch dup mul add sqrt 16 div setlinewidth
          7 div 4 index add exch % x0 y0 x1-x0 y1-y0 (y2-y0)/7+y0 x2-x0
          7 div 5 index add exch % x0 y0 x1-x0 y1-y0 (x2-x0)/7+x0 (y2-y0)/7+y0
          2 copy moveto
          2 index add exch
          3 index add exch lineto % x0 y0 x1-x0 y1-y0
          pop pop pop pop
          stroke
        } repeat
      } if
      //false
    } ifelse
  } bdef

  /StrikeOut {
    dup /AP oknown {
      //true
    } {
      0 setlinecap
      dup annotsetcolor
      dup calc_annot_scale scale

      /QuadPoints knownoget {
        aload length 8 idiv {
          //quadpoints2basis exec

          % Acrobat draws the line at 3/7 of the box width from the bottom
          % of the box and 1/16 thick of the box width. /Rect is ignored.

          2 copy dup mul exch dup mul add sqrt 16 div setlinewidth
          0.4285714 mul 4 index add exch % x0 y0 x1-x0 y1-y0 (y2-y0)*3/7+y0 x2-x0
          0.4285714 mul 5 index add exch % x0 y0 x1-x0 y1-y0 (x2-x0)*3/7+x0 (y2-y0)*3/7+y0
          2 copy moveto
          2 index add exch
          3 index add exch lineto % x0 y0 x1-x0 y1-y0
          pop pop pop pop
          stroke
        } repeat
      } if
      //false
    } ifelse
  } bdef

  % Connect 2 points with an arc that has max distance from the line
  % segment to the ark equal 1/4 of the radius.
  /highlight-arc {                      % x1 y1 x0 y0 -> -
    4 2 roll                            % x0 y0 x1 y1
    dup 3 index add 2 div               % x0 y0 x1 y1 (y1+y0)/2
    2 index 5 index sub .9375 mul sub   % x0 y0 x1 y1 (y1+y0)/2-15/16*dx=yc
    4 index 3 index add 2 div           % x0 y0 x1 y1 yc (x0+x1)/2
    2 index 5 index sub .9375 mul add   % x0 y0 x1 y1 yc xc
    exch                                % x0 y0 x1 y1 xc yc
    dup 3 index exch sub                % x0 y0 x1 y1 xc yc y1-yc
    4 index 3 index sub                 % x0 y0 x1 y1 xc yc y1-yc x1-xc
    dup dup mul 2 index dup mul add sqrt %x0 y0 x1 y1 xc yc y1-yc x1-xc r
    3 1 roll atan                       % x0 y0 x1 y1 xc yc r a1
    6 index 3 index sub                 % x0 y0 x1 y1 xc yc r a1 y0-yc
    8 index 5 index sub                 % x0 y0 x1 y1 xc yc r a1 y0-yc x0-xc
    atan                                % x0 y0 x1 y1 xc yc r a1 a2
    exch arcn                           % x0 y0 x1 y1
    pop pop pop pop
  } bind def

  /emptydict 0 dict readonly def

  /Highlight {
    % Acrobat ignores /AP and uses transparent highlighting
    0 setlinecap
    dup annotsetcolor
    /QuadPoints knownoget {
      aload length 8 idiv {
        6 -2 roll
        2 copy moveto
        //highlight-arc exec
        2 copy lineto
        //highlight-arc exec
        closepath
      } repeat
      PDFusingtransparency {
        //emptydict
        pathbbox 2 index add exch 3 index add exch .begintransparencygroup
        /Multiply .setblendmode
        fill
        .endtransparencygroup
      } { % for -dNOTRANSPARENCY
        stroke newpath
      } ifelse
    } if
    //false
  } bdef
  currentdict /emptydict undef
  currentdict /highlight-arc undef

  /Squiggly {
    dup /AP oknown {
      //true
    } {
      dup annotsetcolor
      dup calc_annot_scale scale

      /QuadPoints knownoget {
        aload length 8 idiv {
          gsave
          8 copy moveto lineto
          4 2 roll lineto lineto closepath clip newpath
          //quadpoints2basis exec
          6 -2 roll translate    % adjust for x0 y0      % x1-x0 y1-y0 x2-x0 y2-y0
          1 index 56 div 1 index 56 div translate        % zigzag box is 1/56 up
          1 index 72 div 1 index 72 div translate        % the line in the box is 1/72 up
          2 copy dup mul exch dup mul add sqrt           % x1-x0 y1-y0 x2-x0 y2-y0 |p2|
          4 index dup mul 4 index dup mul add sqrt       % x1-x0 y1-y0 x2-x0 y2-y0 |p2| |p1|
          dup 0 gt 2 index 0 gt and {
            div                                          % x1-x0 y1-y0 x2-x0 y2-y0 |p2|/|p1|=p12
            dup 1 exch div 4 mul 1 add cvi exch 6 2 roll % cnt p12 x1-x0 y1-y0 x2-x0 y2-y0
            4 2 roll                                     % cnt p12 x2-x0 y2-y0 x1-x0 y1-y0
            4 index mul exch 4 index mul exch            % cnt p12 x2-x0 y2-y0 (x1-x0)*p12 (y1-y0)*p12
            4 2 roll 0 0 6 array astore concat           % cnt p12
            1 40 div 1 72 div scale
            pop                                          % cnt
            0 0 moveto
            1 setlinecap
            1 setlinejoin
            1 setlinewidth
            {
              5 10 lineto
              10 0 lineto
              10 0 translate
            } repeat
            stroke
          } {
            6 { pop } repeat
          } ifelse
          grestore
        } repeat
      } if
      //false
    } ifelse
  } bdef

  /Text {
    dup /AP oknown {
      //true
    } {
      dup calc_annot_scale scale
      annotrect 4 2 roll translate
      exch pop

      % Draw a page icon
      0.5 exch 18.5 sub translate
      1 setlinewidth
      0.75 setgray
      0.5 -1 moveto 10 -1 lineto 15 4 lineto 15 17.5 lineto stroke

      0 0 moveto
      9 0 lineto
      14 5 lineto
      14 18 lineto
      0 18 lineto closepath
      gsave .5 setgray fill grestore 0 setgray stroke

      3 8 moveto 7.5 8 lineto
      3 11 moveto 10 11 lineto
      3 14 moveto 10 14 lineto
      9 0 moveto 9 5 lineto 14 5 lineto
      stroke
      //false
    } ifelse
  } bdef

  /frame {
    { 255 div } forall setrgbcolor
    -95 -25 translate
    2 190 atan rotate
    {
      6 0 moveto
      190 0 190 6 6 arct
      190 47 184 47 6 arct
      0 47 0 41 6 arct
      0 0 6 0 6 arct
      closepath

      10 4 moveto
      185 4 185 9 5 arct
      185 43 180 43 5 arct
      5 43 5 38 5 arct
      5 4 9 4 5 arct
      closepath
      eofill
   }
   gsave 1 -1 translate 0.75 setgray dup exec grestore
   exec
  } bdef

  % (text) y h -> -
  /text {
    /Times-Bold findfont exch scalefont setfont  % (text) y
    gsave
    0 0 moveto
    1 index //false charpath flattenpath pathbbox
    pop exch pop sub 2 div
    grestore
    95 add exch moveto
    gsave 1 -1 rmoveto  0.75 setgray dup show grestore
    show
  } bdef

  /red   <ef4023> readonly def
  /green <3fae49> readonly def
  /blue  <0072bc> readonly def

  /stamp_dict 14 dict begin
    /Approved {
      //green //frame exec
      (APPROVED) 13 30 //text exec
    } bdef
    /AsIs {
      //red //frame exec
      (AS IS) 13 30 //text exec
    } bdef
    /Confidential {
      //red //frame exec
      (CONFIDENTIAL) 17 20 //text exec
    } bdef
    /Departmental {
      //blue //frame exec
      (DEPARTMENTAL) 17 20 //text exec
    } bdef
    /Draft {
      //red //frame exec
      (DRAFT) 13 30 //text exec
    } bdef
    /Experimental {
      //blue //frame exec
      (EXPERIMENTAL) 17 20 //text exec
    } bdef
    /Expired {
      //red //frame exec
      (EXPIRED) 13 30 //text exec
    } bdef
    /Final {
      //red //frame exec
      (FINAL) 13 30 //text exec
    } bdef
    /ForComment {
      //green //frame exec
      (FOR COMMENT) 17 20 //text exec
    } bdef
    /ForPublicRelease {
      //green //frame exec
      (FOR PUBLIC) 26 18 //text exec
      (RELEASE)  8.5 18 //text exec
    } bdef
    /NotApproved {
      //red //frame exec
      (NOT APPROVED) 17 20 //text exec
    } bdef
    /NotForPublicRelease {
      //red //frame exec
      (NOT FOR) 26 18 //text exec
      (PUBLIC RELEASE) 8.5 18 //text exec
    } bdef
    /Sold {
      //blue //frame exec
      (SOLD) 13 30 //text exec
    } bdef
    /TopSecret {
      //red //frame exec
      (TOP SECRET) 14 26 //text exec
    } bdef
  currentdict end readonly def

  {/text/frame/red/green/blue} {currentdict exch undef} forall

  /Stamp  {
    dup /AP oknown {
      //true
    } {
      dup calc_annot_scale scale

      % translate to the center of Rect
      dup annotrect
      4 2 roll  % dx dy x0 y0
      2 index 2 div add exch
      3 index 2 div add exch translate  % dx dy

      50 div exch 190 div .min dup scale

      /Name knownoget not { /Draft } if
      //stamp_dict 1 index known not { exch pop /Draft exch } if
      //stamp_dict exch get exec

      //false
    } ifelse
  } bdef

  currentdict /quadpoints2basis undef
currentdict end readonly def

/drawannot {		% <annot> drawannot -
  dup annotvisible {
    gsave
    dup dup /Subtype knownoget {
      //drawannottypes exch .knownget { exec } { //true } ifelse
      {
        dup calc_annot_scale 3 -1 roll drawwidget % Draw rejected annots as widgets
      } if			% type known
    } {
      pop
      (   **** Warning: /Annot dict without required /Subtype entry is ignored.\n)
      pdfformaterror
    } ifelse
    grestore
  } if pop			% annotvisible
} bdef
currentdict /drawannottypes undef

% ============================ AcroForm fields ============================ %

% Get an attribure of the 0th annotation of a node
/annot_oget {  % <annot> /Name annot_oget <value>
  1 index /Kids knownoget {
    0 oget exch oget exch pop
  } {
    oget
  } ifelse
} bdef

% All procedures have the signature:
% <acroform> <field> <annot|field> foo <acroform> <field> <annot|field>
/draw_terminal_field_dict 4 dict begin

/Btn {
  1 index /Tf pget not { 0 } if
  dup 16#20000 and 0 ne {
    pop % Push button
    dup /AP known {
      1 1 2 index drawwidget
    } {
      (Push button without appearance stream is not yet implemented) =
    } ifelse
  } {
    16#10000 and 0 ne {
        % Radio button
        dup /AP known {
          1 index /Kids oget {
            1 1 3 -1 roll drawwidget
          } forall
        } {
          (Radio button without appearance stream is not yet implemented) =
        } ifelse
    } {
        % Checkbox
        dup /AP known {
          dup 1 1 3 -1 roll drawwidget
        } {
          (CkeckBox without appearance stream is not yet implemented) =
        } ifelse
    } ifelse
  } ifelse
} bdef

/Tx {
  dup /AP known {
    dup 1 1 3 -1 roll drawwidget
  } {
    2 index /NeedAppearances knownoget not { //false } if {
      dup /AP << /N 10 dict dup cvx begin >> put
      /Subtype /Form def
      /BBox [ 0 0 4 index /Rect oget { oforce } forall  3 -1 roll sub abs 3 1 roll sub abs exch ] def
      /Resources 3 index /DR pget not { 0 dict } if def
      /File 1000 string dup 3 1 roll def
      /Length 0 def
                            % <acroform> <field> <annot> (string)
      /NullEncode filter    % <acroform> <field> <annot> file

      dup (BT ) writestring
      2 index /DA pget not { () } if
      [ exch
        { token {
            dup /Tf eq {
              2 index 0 eq {
                /BBox load 3 get
                0.75 mul   % empirical constant
                4 -1 roll pop 3 1 roll
              } if
            } if
            exch
          } {
            exit
          } ifelse
        } loop
      ]
      { 1 index exch write== } forall
      dup 3 index /MaxLen pget not { 0 } if write=
      dup 3 index /V pget not { () } if write==
      dup 3 index /Ff pget not { 0 } if write=
      dup 3 index /Q pget not { 0 } if write=
      dup (Tform ET) write=
      end
      closefile             %  <acroform> <field> <annot>
      dup 1 1 3 -1 roll drawwidget
    } if
  } ifelse
} bdef

/Ch {
  (Ch is not yet implemened) //== exec
} bdef

/Sig {
  (Sig is not yet implemened ) //== exec
} bdef

currentdict end def

/draw_terminal_field {   % <field> draw_terminal_field -
 dup /Kids knownoget { 0 oget } { dup } ifelse
 dup /P knownoget {
    /Page load eq {
      //draw_terminal_field_dict 2 index /FT pget not { 0 } if .knownget {
        exec
      } if
   } if
 } if
 pop pop
} bdef

% We distinguish 4 types of nodes on the form field tree:
%  - non-terminal field - has a kid that refers to the parent (or anywhere else)
%  - terminal field with separate widget annotations - has a kid that doesn't have a parent
%  - terminal field with a merged widget annotation - has no kids
%  - widget annotation - has /Subtype and /Rect
%
% The recursive enumeration of the form fields doesn't descend into widget annotations.

/draw_form_field { % <field> draw_form_field -
  dup /Kids knownoget {                       % field []
    dup 0 oget /Parent knownoget {            % field [] kid
      pop % mon-terminal field                % field []
      exch pop                                % []
      { oforce draw_form_field } forall
    } {
      pop draw_terminal_field % separate annots % -
    } ifelse
  } {
    draw_terminal_field % merged annotation   % -
  } ifelse
} bdef

/draw_acro_form {		% <form> draw_acro_form -
  dup /Fields knownoget {
    { oforce draw_form_field } forall
  } if
  pop
} bdef

currentdict /draw_terminal_field_dict undef

end			% pdfdict
end			% GS_PDF_ProcSet
.setglobal