1% 2% psi.prolog 3% 4% Copyright (C) 1996-2000 by vhf computer GmbH + vhf interservice GmbH 5% Author: Georg Fleischmann 6% 7% created: 2000-09-09 8% modified: 9% 10 11%%% this file also contains a section taken from GPL Ghostscript 8.50 "traceimg.ps", see below 12 13% this PostScript code writes a file with the structure below. 14% # # # # l (x0 y0 x1 y1) line 15% # # # # # # # #c (x0 y0 x1 y1 x2 y2 x3 y3) curve 16% # w (width) width 17% # # # # # co (c m y k a) color 18% n new list 19% f list is a filled polygon 20% s list is a group 21% cl list is a clip list (clip with old clip list and use it) 22% gs save current clip list and width to top of stack 23% gr use last clip list (on top of stack) and width 24% # # # # # # # # # # (x y a b c d e f text font) text 25% 26% Adapted for Scribus by Franz Schmid 15.05.2004 27% Also removed the hardcoded Output Filename 28% and changed it in a way the -sOutputFile Option of Ghostscript can be used 29% Speeded up the flattening of Text by removing unneeded calculations. 30% Changed the Output slightly to ease parsing 31% m moveto 32% l # # # # (x0 y0 x1 y1) line 33% c # # # # # # # # (x0 y0 x1 y1 x2 y2 x3 y3) curve 34% w # (width) Linewidth 35% co # # # # # (c m y k a) color 36% n new list 37% f list is a filled polygon 38% s list is a stroke path 39% cp close current subpath 40% ci list is a clip list (clip with old clip list and use it) 41% sp end of page 42% lj # linejoin 43% lc # linecap 44% ld # # #n linedash count offset d1, d2, dx 45% im # image <name> 46% pat # # makepattern params tmpfilename 47% mask imagemask, followed by b/w image 48% fill-evenodd set fill rule 49% fill-winding - " - 50% 15.05.2004 Added the Glyphshow Operator. 51% 17.05.2004 Made clipping working. 52% 20.05.2004 kshow is working now. 53% 22.02.2006 added image and colorimage ops -- av 54% 02.03.2006 added code to divide reported coordinates by (device resolution/72) -- av 55% 23.03.2006 added code to trace PDF commands 56 57% some hacks to get access to PDF operators, needs -sDELAYBIND 58 59currentglobal true setglobal 60GS_PDF_ProcSet begin 61currentdict /setshowstate 62{ 63 dup WordSpacing 0 32 TextSpacing 0 6 -1 roll awidthshow 64 //setshowstate exec 65} .forceput 66currentdict /endpage { 67 (sp\n) print 68 //endpage exec 69} .forceput 70currentdict /doimage known not { 71 currentdict /doimage { } .forceput 72} if 73currentdict /doimage { 74 currentdict i_image 75 //doimage exec 76} .forceput 77end 78setglobal 79.bindnow 80 81/cfile TraceFile (w) file def 82/print { cfile exch writestring } bind def 83 84 85/==write % any ==write - 86{ 87 dup type dup /arraytype eq exch /packedarraytype eq or 88 { 89 i_file ([) writestring 90 { ==write i_file ( ) writestring } forall 91 i_file (]) writestring 92 } { 93 dup type /nametype eq 94 { 95 i_file (/) writestring i_file exch i_str cvs writestring 96 } { 97 dup type /stringtype eq 98 { 99 true 1 index { 32 ge and } forall 100 { 101 i_file (\() writestring i_file exch writestring i_file (\)) writestring 102 } 103 { 104 i_file (<) writestring 105 i_file /ASCIIHexEncode filter dup 106 3 -1 roll 107 writestring closefile % close filter 108 i_file (\n) writestring 109 } ifelse 110 } { 111 dup type /dicttype eq 112 { 113 i_file (<<) writestring 114 { ==write ( ) =write ==write (\n) =write } forall 115 i_file (>>) writestring 116 } { 117 i_file exch i_str cvs 118 dup dup length 1 sub get (-) 0 get eq { pop (null) } if 119 writestring 120 } ifelse } ifelse } ifelse } ifelse 121} def 122 123/=write % any =write - 124{ 125 dup type dup /arraytype eq exch /packedarraytype eq or 126 { 127 { =write i_file ( ) writestring } forall 128 } { 129 dup type /nametype eq 130 { 131 i_file exch i_str cvs writestring 132 } { 133 dup type /stringtype eq 134 { 135 i_file exch writestring 136 } { 137 dup type /dicttype eq 138 { 139 i_file (<<) writestring 140 { =write ( ) =write =write (\n) =write } forall 141 i_file (>>) writestring 142 } { 143 i_file exch i_str cvs writestring 144 } ifelse } ifelse } ifelse } ifelse 145} def 146 147 148% flag to deactivate our substitutions 149/i_shortcut false def 150 151% defines an overloaded function name proc i_shortcutOverload - 152% equvalent to /name { i_shortcut { //name } { proc } ifelse } bind def 153/i_shortcutOverload 154{ 155 [ /i_shortcut /load load [ 5 index load ] cvx 4 index /ifelse load ] cvx 156 exch pop 157 bind def 158} def 159 160% whether we have to flatten the text 161/flattenText 1 def 162 163% is a Clipping there 164/clipCnt 0 def 165 166% remember the current point 167/currentX 0 def 168/currentY 0 def 169 170% 1st point of path to close the path 171/beginX 0 def 172/beginY 0 def 173 174% dummy for converting strings 175/i_str 50 string def 176 177% 0 = mirror at 178/mirror 0 def 179 180% mirror a at 0 181/mir 182{ 183 mirror 0 ne 184 { 0 exch sub 185 }if 186} bind def 187 188% scale 189 190currentpagedevice /HWResolution get aload pop 19172 div /i_vscale exch def 19272 div /i_hscale exch def 193 194/m_a 1 def 195/m_b 0 def 196/m_c 0 def 197/m_d 1 def 198/m_x 0 def 199/m_y 0 def 200/matrix_x % x y 201{ 202 % ax + cy + tx 203 m_c mul exch m_a mul add m_x add i_hscale div 204} bind def 205/matrix_y % x y 206{ 207 % bx + dy + ty 208 m_d mul exch m_b mul add m_y add i_vscale div 209} bind def 210 211 212/concatenate % str1 str2 concatenate str12 213{ 214 dup length 2 index length add string 215 dup 3 index length 3 index putinterval 216 dup 0 4 index putinterval 217 exch pop exch pop 218} bind def 219 220% this is like search but returns the last match in string 221/rsearch % string seek rsearch post match pre true // string false 222{ 223 2 copy search % string seek post1 match1 pre1 true 224 { 225 2 index 4 index rsearch % string seek post1 match1 pre1 post2 match2 pre2 true 226 { 227 6 -1 roll pop % string seek match1 pre1 post2 match2 pre2 228 % combine (pre1 match1 pre2) into one string 229 5 -1 roll exch concatenate % string seek pre1 post2 match2 (match1+pre2) 230 4 -1 roll exch concatenate % string seek post2 match2 (pre1+match1+pre2) 231 } { % string seek post1 match1 pre1 post1 232 pop 233 } ifelse 234 % string seek post match pre 235 5 -2 roll pop pop 236 true 237 } { % string seek string 238 pop pop false 239 } ifelse 240} bind def 241 242 243% returns a unique filename for the given extension 244/i_exportfilename % string i_exportfilename string 245{ 246 /ExportFiles where { /ExportFiles get (.) rsearch { exch pop exch pop } if } { (imagefile) } ifelse 247 (-) concatenate dup /i_basename exch def i_filecount 9 string cvs concatenate 248 { 249 i_filecount 1 add /i_filecount exch store 250 dup 2 index concatenate status not { exit } if 251 pop pop pop pop pop 252 i_basename i_filecount 9 string cvs concatenate 253 } loop 254 exch pop 255} bind def 256 257% Code for reading patters is currently commented out, as it 258% doesn't seem to work correctly. 259% /makepattern { % dict matrix makepattern patterndict 260% %/makepattern = 261% % we will do some real painting here: 262% /i_shortcut true store 263% % params: 264% /i_m exch def 265% /i_dict exch def 266% % define export filename 267% /i_basename (.png) i_exportfilename (.png) concatenate def 268% i_dict /BBox get 269% dup 0 get /i_x exch def 270% dup 1 get /i_y exch def 271% dup 2 get i_x sub /i_w exch def 272% 3 get i_y sub /i_h exch def 273% % we want those in devspace: 274% i_x i_y i_m itransform matrix currentmatrix transform 275% i_vscale div /i_y exch def i_hscale div /i_x exch def 276% i_w i_h i_m idtransform matrix currentmatrix dtransform 277% i_vscale div /i_h exch def i_hscale div /i_w exch def 278% % i_h < 0 ? 279% i_h 0 le 280% { 281% /i_y i_h i_y add def 282% /i_h i_h neg def 283% } if 284% % i_w < 0 ? 285% i_w 0 le 286% { 287% /i_x i_w i_x add def 288% /i_w i_w neg def 289% } if 290% % now we can use the current matrix as pattern matrix, but with (0,0) origin 291% i_m == 292% i_x i_y matrix currentmatrix translate /i_m exch def 293% i_m == 294% i_dict /BBox [ 0 0 i_w i_h ] put 295% (w x h =) = i_w = i_h = 296% % paint pattern to png file 297% gsave 298% currentcolor currentcolorspace 299% << 300% /OutputFile i_basename 301% /OutputDevice (pngalpha) 302% /TextAlphaBits 4 303% /GraphicsAlphaBits 4 304% % /BackgroundColor 16777215 305% % /BackgroundColor 0 306% /PageUsesTransparency true 307% /HWResolution [ 72 72 ] 308% /ProcessColorModel /DeviceRGB 309% /PageSize [i_w i_h] 310% /pngalpha finddevice putdeviceprops setdevice 311% setcolorspace setcolor 312% % matrix currentmatrix == 313% % 0 0 transform exch = = 314% % 1 1 transform exch = = 315% i_dict i_w i_h matrix identmatrix scale 316% %matrix identmatrix 317% //makepattern setpattern 318% 0 0 i_w i_h rectfill 319% showpage 320% grestore 321% % create pattern with our extensions: 322% i_dict dup /ExportFile i_basename put 323% dup /Origin [ 0 0 transform ] put 324% i_m //makepattern 325% /i_shortcut false store 326% %/makepatternE = 327% } i_shortcutOverload 328 329/writecurrentpattern 330{ 331 currentcolor 332 (pat ) print 333 dup /Origin get 334 dup 0 get i_hscale div i_str cvs print ( ) print 335 1 get i_vscale div i_str cvs print ( ) print 336 /ExportFile get print 337 (\n) print 338} bind def 339 340/writecurrentcmykcolor 341{ 342 currentcmykcolor % -> c m y k 343 (co )print 344 3 index i_str cvs print 345 ( ) print 346 2 index i_str cvs print 347 ( ) print 348 1 index i_str cvs print 349 ( ) print 350 i_str cvs print 351 ( ) print 352 pop pop pop 353 .currentopacityalpha % a 354 i_str cvs print 355 (\n) print 356} bind def 357 358 359/writecurrentrgbcolor 360{ 361 currentrgbcolor % -> r g b 362 (corgb )print 363 2 index i_str cvs print 364 ( ) print 365 1 index i_str cvs print 366 ( ) print 367 i_str cvs print 368 ( ) print 369 pop pop 370 .currentopacityalpha % a 371 i_str cvs print 372 (\n) print 373} bind def 374 375 376/writecurrentcolor 377{ 378 currentcolorspace 0 get 379 380 % try to find a base colorspace first 381 dup /Indexed eq 382 { 383 pop 384 currentcolorspace 1 get 385 dup type /arraytype eq { 0 get } if 386 } if 387 388 dup dup /DeviceN eq exch /Separation eq or 389 { 390 pop 391 currentcolorspace 2 get 392 dup type /arraytype eq { 0 get } if 393 } if 394 395 % now write values 396 dup /CIEBasedABC eq 397 { % this must be a hack.... 398 gsave 399 currentcolor setrgbcolor 400 writecurrentrgbcolor 401 grestore 402 } { 403 dup /DeviceRGB eq 404 { 405 writecurrentrgbcolor 406 } { 407 dup dup /DeviceCMYK eq exch /DeviceGray eq or 408 { 409 writecurrentcmykcolor 410 } { 411 dup /Pattern eq 412 { 413 writecurrentpattern 414 } { 415 % TODO: other CIE 416 writecurrentrgbcolor % will always be 0 417 } 418 ifelse } ifelse } ifelse } ifelse 419 pop 420} bind def 421 422/writecurrentlinecap 423{ 424 (lc ) print 425 currentlinecap i_str cvs print 426 (\n) print 427} bind def 428 429/writecurrentlinejoin 430{ 431 (lj ) print 432 currentlinejoin i_str cvs print 433 (\n) print 434} bind def 435 436/writecurrentdash 437{ 438 (ld ) print 439 currentdash 1 index length i_str cvs print ( ) print i_str cvs print ( ) print 440 0 1 2 index length 1 sub 441 { 442 1 index exch get 443 storeMatrix 444 dup dup dup m_b abs mul exch m_d abs mul add exch m_a abs mul add exch m_c abs mul add 2 div abs 445 i_hscale div 446 i_str cvs print ( ) print 447 } for 448 pop 449 (\n) print 450} bind def 451 452/writecurrentlinewidth 453{ 454 userdict begin 455 currentlinewidth % w 456 storeMatrix 457 458 % (wb + wd + wa + wc) / 2 459%?? 460 dup dup dup m_b abs mul exch m_d abs mul add exch m_a abs mul add exch m_c abs mul add 2 div abs 461 i_hscale div 462 % transform (w,w) and take length 463%av-test: dup dtransform i_vscale div dup mul exch i_hscale div dup mul add sqrt 464 (w ) print 465 i_str cvs print 466 (\n) print 467 end 468} bind def 469 470/i_move % x y 471{ 472 userdict begin 473 (m\n) print 474 /currentY exch def 475 /currentX exch def 476 /beginX currentX def 477 /beginY currentY def 478 end 479} bind def 480 481/i_line 482{ 483 userdict begin 484 /y1 exch def 485 /x1 exch def 486 487 % x x1 ne y y1 ne or 488 currentX x1 sub abs 0.001 gt currentY y1 sub abs 0.001 gt or 489 { 490 (l ) print 491 currentX currentY matrix_x i_str cvs print 492 ( ) print 493 currentX currentY matrix_y i_str cvs print 494 ( ) print 495 496 x1 y1 matrix_x i_str cvs print 497 ( ) print 498 x1 y1 matrix_y i_str cvs print 499 (\n) print 500 /currentX x1 def 501 /currentY y1 def 502 }if 503 end 504} bind def 505 506/i_curve 507{ 508 userdict begin 509 % x1 y1 x2 y2 x3 y3 510 (c ) print 511 currentX currentY matrix_x i_str cvs print 512 ( ) print 513 currentX currentY matrix_y i_str cvs print 514 ( ) print 515 5 index 5 index matrix_x i_str cvs print 516 ( ) print 517 5 index 5 index matrix_y i_str cvs print 518 ( ) print 519 3 index 3 index matrix_x i_str cvs print 520 ( ) print 521 3 index 3 index matrix_y i_str cvs print 522 ( ) print 523 524 /currentY exch def 525 /currentX exch def 526 527 currentX currentY matrix_x i_str cvs print 528 ( ) print 529 currentX currentY matrix_y i_str cvs print 530 (\n)print 531 pop pop pop pop 532 end 533} bind def 534 535% modified: 18.10.96 536/i_close 537{ 538 beginX beginY i_line 539 (cp\n) print 540} bind def 541 542/storeMatrix 543{ 544 userdict begin 545 matrix currentmatrix 546 dup 0 get /m_a exch def 547 dup 1 get /m_b exch def 548 dup 2 get /m_c exch def 549 dup 3 get /m_d exch def 550 dup 4 get /m_x exch def 551 5 get /m_y exch def 552 end 553} bind def 554 555/pathClipAndClose % this is not nice: closes all open paths & flattens the path :-( 556{ 557 clipsave 558 clip % combine clippath and path 559 newpath clippath % copy (closed) clippath to path 560 cliprestore 561} bind def 562 563 564% find out if the point is within the clipping area 565/i_in_clip % x y i_in_clip bool 566{ 567 gsave 568 newpath clippath 569 infill 570 grestore 571} bind def 572 573 574% find out if two points are within the clipping area 575/i_in_clip2 % x1 y1 x2 y2 i_in_clip bool1 bool2 576{ 577 gsave 578 newpath clippath 579 infill % x1 y1 bool2 580 3 1 roll % bool2 x1 y1 581 infill % bool2 bool1 582 exch 583 grestore 584} bind def 585 586 587/i_clip_move 588{ 589 /beginY exch store 590 /beginX exch store 591 /currentX beginX store 592 /currentY beginY store 593 % test if within cliparea 594 currentX currentY i_in_clip 595 { 596 currentX currentY /moveto load 597 } if 598} bind def 599 600 601% find intersection with line x1,y1 -> x2,y2 with clip path. 602% x1,y2 is outside the clip area, x2, y2, x3, y3 inside 603 604/i_find_clip_intersect % x1 y1 x2 y2 i_find_clip_intersect x3 y3 605{ 606 3 index 2 index sub % x1 y1 x2 y2 dx 607 3 index 2 index sub % x1 y1 x2 y2 dx dy 608 gsave 609 newpath clippath 610 { 611 2 div exch 2 div exch % half interval 612 2 copy abs 0.01 lt exch abs 0.01 lt and 613 { exit } if % done 614 2 copy 4 index add exch % x1 y1 x2 y2 dx dy (y2+dy) dx 615 5 index add exch % x1 y1 x2 y2 dx dy (x2+dx) (y2+dy) 616% /Intersect = 7 index = 6 index = 5 index = 4 index = 3 index = 2 index = 1 index = 0 index = 617 2 copy infill 618 { % replace x2,y2 619 6 -2 roll pop pop 620 4 2 roll 621 } { 622 8 -2 roll pop pop % replace x1,y1 623 6 2 roll 624 } ifelse 625 } loop 626 grestore 627 6 -2 roll % return x2,y2 628 4 { pop } repeat 629} bind def 630 631/i_clip_line 632{ 633 /endY exch store 634 /endX exch store 635 currentX currentY endX endY i_in_clip2 636 { % end in 637 { 638 % both in. just draw it. FIXME check if line leaves cliparea 639 endX endY /lineto load 640 } { 641 % current not in 642 % find new current point 643 currentX currentY endX endY i_find_clip_intersect 644 /moveto load 645 endX endY /lineto load 646 } ifelse 647 } { % end not in 648 { % current in 649 % find new endpoint 650 endX endY currentX currentY i_find_clip_intersect 651 /lineto load 652 } { 653 % both not in 654 % try to find a point within cliparea 655 currentX currentY endX endY i_find_clip_intersect 656 2 copy i_in_clip 657 { 658 % yeah 659 /moveto load 660 % now find point from other end 661 endX endY currentX currentY i_find_clip_intersect 662 /lineto load 663 } { 664 pop pop 665 } ifelse 666 } ifelse 667 } ifelse 668 /currentX endX store 669 /currentY endY store 670} bind def 671 672 673/pathClipForStroke 674{ 675 % only lines 676 flattenpath 677 % create a userpath from currentpath 678 userdict begin 679 /beginX 0 def /beginY 0 def 680 /currentX 0 def /currentY 0 def 681 /endX 0 def /endY 0 def 682 systemdict begin % some EPS redefine moveto & Co :-( 683 [ 684 { i_clip_move } % remember last move 685 { i_clip_line } % clip lines individually 686 { 6 {pop} repeat /OOPS = } % won't happen 687 { beginX beginY i_clip_line } % close with line 688 pathforall 689 ] cvx 690% dup == 691 newpath % uappend % userpaths SUCK! 692 end end 693 exec 694} bind def 695 696/rectfill 697{ 698 userdict begin 699 (n\n)print % start polygon 700 writecurrentcolor 701 writecurrentlinewidth 702 writecurrentlinecap 703 writecurrentlinejoin 704 writecurrentdash 705 storeMatrix 706 707 % x y width height 708 dup type /arraytype ne 709 { 710 /hr exch def 711 /wr exch def 712 /yr exch def 713 /xr exch def 714 xr yr i_move 715 xr wr add yr i_line 716 xr wr add yr hr add i_line 717 xr yr hr add i_line 718 xr yr i_line 719 } 720 % numarray 721 % numstring 722 { 723 /ar exch def 724 0 4 ar length 1 sub 725 { 726 /n exch def 727 ar n get /xr exch def 728 ar n 1 add get /yr exch def 729 ar n 2 add get /wr exch def 730 ar n 3 add get /hr exch def 731 xr yr i_move 732 xr wr add yr i_line 733 xr wr add yr hr add i_line 734 xr yr hr add i_line 735 xr yr i_line 736 } for 737 }ifelse 738 (cp\n)print 739 (f\n)print % close polygon 740 end 741} i_shortcutOverload 742 743/rectstroke 744{ 745 userdict begin 746 (n\n)print % start rect 747 writecurrentcolor 748 writecurrentlinewidth 749 writecurrentlinecap 750 writecurrentlinejoin 751 writecurrentdash 752 storeMatrix 753 754 % x y width height 755 dup type dup /arraytype ne exch /stringtype ne and 756 { 757 /hr exch def 758 /wr exch def 759 /yr exch def 760 /xr exch def 761 xr yr i_move 762 xr wr add yr i_line 763 xr wr add yr hr add i_line 764 xr yr hr add i_line 765 xr yr i_line 766 } 767 % numarray 768 % numstring 769 { 770 /ar exch def 771 0 4 ar length 1 sub 772 { 773 /n exch def 774 ar n get /xr exch def 775 ar n 1 add get /yr exch def 776 ar n 2 add get /wr exch def 777 ar n 3 add get /hr exch def 778 xr yr i_move 779 xr wr add yr i_line 780 xr wr add yr hr add i_line 781 xr yr hr add i_line 782 xr yr i_line 783 } for 784 }ifelse 785 (cp\n)print 786 (s\n)print % stroke rect 787 end 788} i_shortcutOverload 789 790/stroke 791{ 792 (n\n) print 793 writecurrentcolor 794 writecurrentlinewidth 795 writecurrentlinecap 796 writecurrentlinejoin 797 writecurrentdash 798% clipCnt 1 eq 799% { pathClipForStroke } if 800 storeMatrix 801 802 {i_move} {i_line} {i_curve} {i_close} pathforall 803 (s\n)print % stroke path 804 newpath 805} i_shortcutOverload 806 807/eofill 808{ 809 (n\n) print % start polygon 810 writecurrentcolor % write color 811 writecurrentlinewidth 812 writecurrentlinecap 813 writecurrentlinejoin 814 writecurrentdash 815% clipCnt 1 eq 816% { pathClipAndClose } if 817 storeMatrix % take transformation, scaling, rotation from PostScript 818 {i_move} {i_line} {i_curve} {i_close} pathforall 819 (f\n)print % close polygon 820 821 newpath % clear stack 822} i_shortcutOverload 823 824/fill 825{ 826 (fill-winding\n) print 827 eofill 828 (fill-evenodd\n) print 829} i_shortcutOverload 830 831/clip 832{ 833 userdict begin 834 (n\n)print % start clip polygon 835 836% FIXME: pathClipAndClose first? 837 838 storeMatrix % take transformation, scaling, rotation from PostScript 839 {i_move} {i_line} {i_curve} {i_close} pathforall 840 841 (ci\n)print % close clip polygon begin path 842 % we have to close the path!! 843% clip 844% /clipCnt 1 def 845 newpath % clear stack 846 end 847} i_shortcutOverload 848 849/eoclip 850{ 851 userdict begin 852 (n\n)print % start clip polygon 853 854% FIXME: pathClipAndClose first? 855 856 storeMatrix % take transformation, scaling, rotation from PostScript 857 {i_move} {i_line} {i_curve} {i_close} pathforall 858 859 (ci\n)print % close clip polygon begin path 860 % we have to close the path!! 861% clip 862% /clipCnt 1 def 863 newpath % clear stack 864 end 865} i_shortcutOverload 866 867% we don't clip 868% because this doesn't work for flattening text (show, charpath) with NeXT PostScript Code 869/rectclip 870{ 871 % let Scribus decide what to do with ci; was: pop pop pop pop 872 userdict begin 873 (n\n)print % start clip polygon 874 875 storeMatrix % take transformation, scaling, rotation from PostScript 876 dup type dup /arraytype ne exch /stringtype ne and 877 { 878 4 copy 879 /i_h exch def 880 /i_w exch def 881 /i_y exch def 882 /i_x exch def 883 i_x i_y i_move 884 i_x i_w add i_y i_line 885 i_x i_w add i_y i_h add i_line 886 i_x i_y i_h add i_line 887 } { 888 % array or string 889 0 4 dup length 1 sub 890 { 891 1 index 1 index get /i_x exch def 892 1 add 893 1 index 1 index get /i_y exch def 894 1 add 895 1 index 1 index get /i_w exch def 896 1 add 897 1 index 1 index get /i_y exch def 898 i_x i_y i_move 899 i_x i_w add i_y i_line 900 i_x i_w add i_y i_h add i_line 901 i_x i_y i_h add i_line 902 } for 903 } ifelse 904 905 (ci\n)print % close clip polygon begin path 906 % we have to close the path!! 907% rectclip 908% /clipCnt 1 def 909 newpath % clear stack 910 end 911} i_shortcutOverload 912 913 914% Code for reading images is currently commented out, as it 915% doesn't seem to work correctly. 916% Copyright (C) 1994 Aladdin Enterprises. All rights reserved. 917% 918% This software is provided AS-IS with no warranty, either express or 919% implied. 920% 921% This software is distributed under license and may not be copied, 922% modified or distributed except as expressly authorized under the terms 923% of the license contained in the file LICENSE in this distribution. 924% 925% For more information about licensing, please refer to 926% http://www.ghostscript.com/licensing/. For information on 927% commercial licensing, go to http://www.artifex.com/licensing/ or 928% contact Artifex Software, Inc., 101 Lucas Valley Road #110, 929% San Rafael, CA 94903, U.S.A., +1(415)492-9861. 930 931% $Id: import.prolog 13454 2009-05-08 19:04:32Z jghali $ 932% traceimg.ps 933% Trace the data supplied to the 'image' operator. 934 935% This code currently handles only the (Level 2) dictionary form of image, 936% with a single data source and 8-bit pixels. 937 938% changed for Scribus image import by Andreas Vox, 2006-2-21 939% added support for colorimage and other image variant 940 941/i_image % <dict> i_image - 942{ 943%dup { == == } forall 944/i_image = 945 begin 946 /i_left Width Height mul Decode length 2 idiv mul BitsPerComponent mul 8 idiv dup /i_size exch store store 947 /i_dict currentdict store 948 /i_nsources 1 store 949 /i_source 0 store 950 /i_datasource currentdict /DataSource get store 951 currentdict /MultipleDataSources known not 952 { /MultipleDataSources false def } if 953 MultipleDataSources 954 { 955 /i_nsources DataSource length store 956 /i_datasource DataSource 0 get store 957 } if 958 end 959 storeMatrix 960 i_dict /ImageMatrix get matrix invertmatrix matrix currentmatrix matrix concatmatrix /i_m exch def 961 i_dict /Width get 0 i_m dtransform dup mul exch dup mul add sqrt /i_w exch def 962 0 i_dict /Height get i_m dtransform dup mul exch dup mul add sqrt /i_h exch def 963 0 0 i_m transform /i_y exch def /i_x exch def 964 i_dict /Width get i_dict /Height get i_m transform 965 /i_hflip -1 def /i_vflip 1 def 966 dup i_y le { /i_y exch def } { pop /i_vflip -1 def } ifelse 967 dup i_x le { /i_x exch def } { pop /i_hflip 1 def } ifelse 968 0 i_dict /Height get i_m dtransform atan 969 /i_angle exch def 970 (.dat) i_exportfilename 971 (im ) print % im x y w h angle ... 972 i_x i_hscale div i_str cvs print ( ) print 973 i_y i_vscale div i_str cvs print ( ) print 974 i_w i_hscale div i_str cvs print ( ) print 975 i_h i_vscale div i_str cvs print ( ) print 976 i_angle i_str cvs print ( ) print 977 i_dict /Width get i_str cvs print ( ) print % ... hpix vpix ... 978 i_dict /Height get i_str cvs print ( ) print 979 currentcolorspace 0 get /DeviceRGB eq 980 { (tiff24nc ) print } 981 { currentcolorspace 0 get /DeviceCMYK eq 982 { (psdcmyk ) print } 983 { currentcolorspace 0 get /DeviceGray eq 984 { (tiffgray ) print } 985 { (tiff32nc ) print } 986 ifelse } ifelse } ifelse 987 dup (.tif) concatenate print (\n) print flush % ... dev filename 988 (.dat) concatenate (w) file /i_file exch store % temp file 989 currentcolorspace ==write ( setcolorspace\n) =write 990 (<<\n) =write 991 i_dict { exch 992 dup /DataSource eq 993 { pop pop (/DataSource currentfile\n) =write } 994 { 995 dup /ImageMatrix eq 996 { pop pop (/ImageMatrix [) =write 997 i_hflip ==write ( 0 0 ) =write i_vflip ==write 998 ( ) =write 999 i_hflip 0 lt { i_dict /Width get } { 0 } ifelse ==write 1000 ( ) =write 1001 i_vflip 0 lt { i_dict /Height get} { 0 } ifelse ==write 1002 (]\n) =write } 1003 { ==write ( ) =write ==write (\n) =write } 1004 ifelse 1005 } ifelse 1006 } forall 1007 (>>\nimage\n) =write i_file flushfile 1008 1009 { %loop 1010 i_left 0 le 1011 { 1012 i_source 1 add /i_source exch def 1013 i_source i_nsources ge { exit } if 1014 i_dict /DataSource get i_source get /i_datasource exch def 1015 /i_left i_size def 1016 } if 1017 /i_datasource load exec 1018 dup type /filetype eq 1019 { i_buf 0 i_left 32 .min getinterval readstring pop 1020 } if 1021 dup length 0 eq {pop i_zero 0 i_left 32 .min getinterval} if 1022 dup i_file exch writestring 1023 i_left exch length sub /i_left exch def 1024 } loop 1025 i_file flushfile 1026/i_imageE = 1027 } bind def 1028 1029/colorimage 1030{ 1031/colorimage = 1032 % width height bits/sample matrix datasource0..n-1 multi ncomp 1033 /tmpN exch def 1034 /tmpMulti exch def 1035 tmpMulti 1036 { 1037 /tmpN load array astore 1038 } if 1039 /tmpN load 6 add dict 1040 dup 7 -1 roll /Width exch put 1041 dup 6 -1 roll /Height exch put 1042 dup 5 -1 roll /BitsPerComponent exch put 1043 dup 4 -1 roll /ImageMatrix exch put 1044 dup 3 -1 roll /DataSource exch put 1045 tmpMulti 1046 { 1047 dup /MultipleDataSources true put 1048 } if 1049 dup /ImageType 1 put 1050 gsave 1051 /tmpN load 1052 dup 1 eq 1053 { 1054 1 index /Decode [0 1] /Decode put 1055 /DeviceGray setcolorspace 1056 } if 1057 dup 3 eq 1058 { 1059 1 index /Decode [0 1 0 1 0 1] put 1060 /DeviceRGB setcolorspace 1061 } if 1062 dup 4 eq 1063 { 1064 1 index /Decode [0 1 0 1 0 1 0 1] put 1065 /DeviceCMYK setcolorspace 1066 } if 1067 pop 1068 i_image 1069 grestore 1070/colorimageE = 1071} i_shortcutOverload 1072 1073/image { 1074/image = 1075 gsave 1076 dup type /dicttype ne 1077 { 1078 % width height bits/sample matrix datasource 1079 7 dict 1080 dup 7 -1 roll /Width exch put 1081 dup 6 -1 roll /Height exch put 1082 dup 5 -1 roll /BitsPerComponent exch put 1083 dup 4 -1 roll /ImageMatrix exch put 1084 dup 3 -1 roll /DataSource exch put 1085 dup 1 /ImageType exch put 1086 dup [0 1] /Decode exch put 1087 /DeviceGray setcolorspace 1088 } if 1089 i_image 1090 grestore 1091/imageE = 1092} i_shortcutOverload 1093 1094/imagemask 1095{ 1096/imagemask = 1097 writecurrentcolor 1098 (mask\n) print 1099 gsave 1100 dup type /dicttype ne 1101 { 1102 % width height pol matrix datasource 1103 7 dict 1104 dup 7 -1 roll /Width exch put 1105 dup 6 -1 roll /Height exch put 1106 dup 5 -1 roll { [0 1] } { [1 0] } ifelse /Decode exch put 1107 dup 4 -1 roll /ImageMatrix exch put 1108 dup 3 -1 roll /DataSource exch put 1109 } if 1110 dup 1 /ImageType exch put 1111 dup 1 /BitsPerComponent exch put 1112 /DeviceGray setcolorspace 1113 i_image 1114 grestore 1115/imagemaskE = 1116} i_shortcutOverload 1117 1118 1119% declare some global vars 1120 1121/i_left 0 def 1122/i_size 0 def 1123/i_dict null def 1124/i_buf 32 string def 1125/i_nsources 1 def 1126/i_source 0 def 1127/i_datasource { (x) } def 1128/i_file null def 1129/i_filecount 1 def 1130/i_zero 32 string def 1131 1132%%%% End of traceimage code 1133 1134 1135/stateArray 500 array def 1136/stateTop 0 def 1137/gsave 1138{ 1139 (gs\n) print 1140 userdict begin 1141% (gs\n) print 1142 stateArray stateTop gstate currentgstate put 1143 /stateTop stateTop 1 add def 1144 end 1145} i_shortcutOverload 1146 1147/grestore 1148{ 1149 (gr\n) print 1150 userdict begin 1151 stateTop 1 lt 1152 { 1153 } 1154 { 1155% (gr\n) print 1156 stateArray stateTop 1 sub get setgstate 1157 /stateTop stateTop 1 sub def 1158 stateArray stateTop 0 put 1159 }ifelse 1160 end 1161} i_shortcutOverload 1162 1163/stringwidth 1164{ 1165 /i_shortcut true store 1166 stringwidth 1167 /i_shortcut false store 1168} i_shortcutOverload 1169 1170% a bind def of the show operator doesn't work, 1171% so this is our way to get a charpath entry for flattening text 1172/root_charpath 1173{ 1174 charpath 1175} bind def 1176 1177/i_kerningI 1178{ 1179 exch 1 getinterval stringwidth 1180} bind def 1181 1182% find kerning value 1183/i_kerningII % index string i_kerning dx dy 1184{ 1185 % stringwidth( [n..n+1] ) - stringwidth( [n+1] ) 1186 /i_pstring exch def 1187 /i_pindex exch def 1188 i_pstring i_pindex 2 getinterval stringwidth exch % y2 x2 1189 i_pstring i_pindex 1 add 1 getinterval stringwidth % y2 x2 x1 y1 1190 4 1 roll sub % y1 y2 (x2-x1) 1191 3 1 roll exch sub % (x2-x1) (y2-y1) 1192} bind def 1193 1194 1195/i_kerningIII % index string i_kerning dx dy 1196{ 1197 % stringwidth( [n..n+1] ) - stringwidth( [n+1] ) 1198 /i_pstring exch def 1199 /i_pindex exch def 1200 i_pstring i_pindex 2 getinterval (l) exch concatenate stringwidth exch % y2 x2 1201 i_pstring i_pindex 1 add 1 getinterval (l) exch concatenate stringwidth % y2 x2 x1 y1 1202 4 1 roll sub % y1 y2 (x2-x1) 1203 3 1 roll exch sub % (x2-x1) (y2-y1) 1204} bind def 1205 1206/i_kerning /i_kerningII load def 1207 1208/show % string show - 1209{ 1210 userdict begin 1211 storeMatrix 1212 currentfont /FontName known 1213 % stack: string 1214 { 1215 currentfont /FontType get dup 3 eq exch 0 eq or 1216 { 1217 currentpoint /ycur exch def /xcur exch def 1218 currentpoint % x y 1219 newpath 1220 /clipCnt 0 def 1221 moveto 1222 (n\n)print % start polygon 1223 writecurrentcolor % write color 1224 storeMatrix 1225 dup 1226 stringwidth 1227 /curwidthy exch def /curwidthx exch def 1228 false root_charpath 1229 {i_move} {i_line} {i_curve} {i_close} pathforall 1230 (f\n)print % close polygon 1231 newpath 1232 curwidthx xcur add curwidthy ycur add moveto 1233 currentpoint /ycur exch def /xcur exch def 1234 newpath % clear graphic stack 1235 xcur ycur moveto 1236 } 1237 { 1238 currentpoint /ycur exch def /xcur exch def 1239 currentpoint % x y 1240 newpath 1241 /clipCnt 0 def 1242 moveto 1243 /completeString exch def 1244 % we process each char separately to get smaller paths 1245 0 1 completeString length 1 sub 1246 { 1247 (n\n)print % start polygon 1248 writecurrentcolor % write color 1249 storeMatrix 1250 dup completeString length 1 sub eq 1251 { dup completeString exch 1 getinterval stringwidth } 1252 { dup completeString i_kerning } ifelse 1253 /curwidthy exch def /curwidthx exch def 1254 completeString exch 1 getinterval dup /curstr exch def 1255 false root_charpath 1256 {i_move} {i_line} {i_curve} {i_close} pathforall 1257 (f\n)print % close polygon 1258 newpath 1259 curwidthx xcur add curwidthy ycur add moveto 1260 currentpoint /ycur exch def /xcur exch def 1261 newpath % clear graphic stack 1262 xcur ycur moveto 1263 } for 1264 currentpoint % x y 1265 newpath % clear graphic stack (and current point) 1266 moveto 1267 } ifelse 1268 } 1269 { 1270 currentfont /FontType known 1271 { 1272 currentfont /FontType get dup 3 eq exch 0 eq or 1273 { 1274 currentpoint /ycur exch def /xcur exch def 1275 currentpoint % x y 1276 newpath 1277 /clipCnt 0 def 1278 moveto 1279 (n\n)print % start polygon 1280 writecurrentcolor % write color 1281 storeMatrix 1282 dup 1283 stringwidth 1284 /curwidthy exch def /curwidthx exch def 1285 false root_charpath 1286 {i_move} {i_line} {i_curve} {i_close} pathforall 1287 (f\n)print % close polygon 1288 newpath 1289 curwidthx xcur add curwidthy ycur add moveto 1290 currentpoint /ycur exch def /xcur exch def 1291 newpath % clear graphic stack 1292 xcur ycur moveto 1293 } 1294 { 1295 pop 1296 } ifelse 1297 } 1298 { 1299 pop 1300 } ifelse 1301 } ifelse 1302 end 1303} i_shortcutOverload 1304 1305/ashow 1306{ 1307 % ax ay string 1308 exch /ydist exch def 1309 exch /xdist exch def 1310 userdict begin 1311 storeMatrix 1312 currentfont /FontName known 1313 % stack: string 1314 { 1315 currentpoint /ycur exch def /xcur exch def 1316 currentpoint % x y 1317 newpath 1318 /clipCnt 0 def 1319 moveto 1320 /completeString exch def 1321 % we process each char separately to get smaller paths 1322 0 1 completeString length 1 sub 1323 { 1324 (n\n)print % start polygon 1325 writecurrentcolor % write color 1326 storeMatrix 1327 dup completeString length 1 sub eq 1328 { dup completeString exch 1 getinterval stringwidth } 1329 { dup completeString i_kerning } ifelse 1330 /curwidthy exch def /curwidthx exch def 1331 completeString exch 1 getinterval dup /curstr exch def 1332 false root_charpath 1333 {i_move} {i_line} {i_curve} {i_close} pathforall 1334 (f\n)print % close polygon 1335 newpath 1336 curwidthx xcur add curwidthy ycur add 1337 exch xdist add exch ydist add moveto 1338 currentpoint /ycur exch def /xcur exch def 1339 newpath % clear graphic stack 1340 xcur ycur moveto 1341 } for 1342 currentpoint % x y 1343 newpath % clear graphic stack (and current point) 1344 moveto 1345 } { 1346 pop 1347 } ifelse 1348 end 1349} i_shortcutOverload 1350 1351/awidthshow % cx cy char ax ay string 1352{ 1353 % ax ay string 1354 exch /ydist exch def 1355 exch /xdist exch def 1356 % cx cy char string 1357 exch /char exch def 1358 exch /cydist exch def 1359 exch /cxdist exch def 1360 userdict begin 1361 storeMatrix 1362 currentfont /FontName known 1363 % stack: string 1364 { 1365 currentpoint /ycur exch def /xcur exch def 1366 currentpoint % x y 1367 newpath 1368 /clipCnt 0 def 1369 moveto 1370 /completeString exch def 1371 % we process each char separately to get smaller paths 1372 0 1 completeString length 1 sub 1373 { 1374 (n\n)print % start polygon 1375 writecurrentcolor % write color 1376 storeMatrix 1377 dup completeString length 1 sub eq 1378 { dup completeString exch 1 getinterval stringwidth } 1379 { dup completeString i_kerning } ifelse 1380 /curwidthy exch def /curwidthx exch def 1381 completeString exch 1 getinterval dup /curstr exch def 1382 false root_charpath 1383 {i_move} {i_line} {i_curve} {i_close} pathforall 1384 (f\n)print % close polygon 1385 newpath 1386 curwidthx xcur add curwidthy ycur add 1387 exch xdist add exch ydist add moveto 1388 curstr 0 get char eq 1389 { 1390 currentpoint exch cxdist add exch cydist add moveto 1391 } if 1392 currentpoint /ycur exch def /xcur exch def 1393 newpath % clear graphic stack 1394 xcur ycur moveto 1395 } for 1396 currentpoint % x y 1397 newpath % clear graphic stack (and current point) 1398 moveto 1399 } { 1400 pop 1401 } ifelse 1402 end 1403} i_shortcutOverload 1404 1405/widthshow % cx cy char string 1406{ 1407 0 exch 1408 0 exch 1409 awidthshow 1410} bind def 1411 1412%/cshow % proc string 1413%{ 1414% exch pop 1415% show 1416%} i_shortcutOverload 1417 1418/kshow % proc string 1419{ 1420 dup length 1 sub 1421 dup 0 ne 1422 { 1423 1 index 0 1 getinterval 1424 show 1425 1 sub 1426 dup 0 ne 1427 { 1428 1 add 1429 1 exch 1 exch 1430 { 1431 dup 1 sub 1432 2 index exch get 1433 2 index 2 index get 1434 4 index exec 1435 1 index exch 1 getinterval 1436 show 1437 } for 1438 } if 1439 } 1440 { 1441 pop dup show 1442 } ifelse 1443 pop pop 1444} i_shortcutOverload 1445 1446/xshow % string array 1447{ 1448 pop %FIXME 1449 show 1450} i_shortcutOverload 1451 1452/xyshow % string array 1453{ 1454 pop %FIXME 1455 show 1456} i_shortcutOverload 1457 1458/yshow % string array 1459{ 1460 pop %FIXME 1461 show 1462} i_shortcutOverload 1463 1464/i_reencode % newfontname reencodevector origfontdict -> i_reencode -> newfontdict 1465{ 1466 userdict begin 1467 dup begin dup maxlength dict begin 1468 { 1 index /FID ne {def} {pop pop} ifelse 1469 } forall 1470 /Encoding exch def 1471 currentdict 1472 end end 1473 definefont 1474 end 1475} bind def 1476 1477/glyphshow { 1478 save % So can reclaim VM from reencoding 1479 currentfont /Encoding get dup length array copy dup 0 5 -1 roll put 1480 /GlyphShowTempFont exch currentfont i_reencode 1481 setfont 1482 (\000) show 1483 currentpoint 3 -1 roll % curx cury -save- 1484 restore 1485 newpath 1486 moveto 1487} i_shortcutOverload 1488 1489/showpage 1490{ 1491 (sp\n) print 1492} i_shortcutOverload 1493 1494 1495