% Copyright (C) 1996, 1997, 1998, 1999 Aladdin Enterprises. All rights reserved. % % This file is part of Aladdin Ghostscript. % % Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author % or distributor accepts any responsibility for the consequences of using it, % or for whether it serves any particular purpose or works at all, unless he % or she says so in writing. Refer to the Aladdin Ghostscript Free Public % License (the "License") for full details. % % Every copy of Aladdin Ghostscript must include a copy of the License, % normally in a plain ASCII text file named PUBLIC. The License grants you % the right to copy, modify and redistribute Aladdin Ghostscript, but only % under certain conditions described in the License. Among other things, the % License requires that the copyright notice and this notice be preserved on % all copies. % $Id: gs_pdfwr.ps,v 1.1 2000/03/09 08:40:40 lpd Exp $ % PDF writer additions to systemdict. % This file should be included iff the pdfwrite "device" is included % in the executable. % Redefine pdfmark to pass the data to the driver. % We use a pseudo-parameter named /pdfmark whose value is an array: % key1 value1 ... CTM /type /.pdf===dict mark /arraytype { dup xcheck { ({) (}) } { ([) (]) } ifelse % Stack: file obj left right 4 1 roll 2 index exch writestring () exch { exch 2 index exch writestring 1 index exch pdfmark===only ( ) } forall pop exch writestring } bind /packedarraytype 1 index /dicttype { 1 index (<<\n) writestring { 2 index 3 -1 roll pdfmark===only 1 index ( ) writestring 1 index exch pdfmark===only dup (\n) writestring } forall (>>) writestring } bind .dicttomark readonly def /pdfmark===only { % pdfmark===only - .pdf===dict 1 index type .knownget { exec } { write===only } ifelse } bind def /.pdfcvbuf 10 string def % enough for most arguments userdict /.pdfcvstring () put /.pdfcvs { % .pdfcvs currentglobal exch false .setglobal /.pdfcvstring () store % We can't handle long values yet. { pop dup length 0 eq { pop } { /.pdfcvstring .pdfcvstring 3 -1 roll concatstrings store } ifelse //.pdfcvbuf } /NullEncode filter dup 3 -1 roll pdfmark===only closefile .setglobal .pdfcvstring } bind def /.pdfputparams { % -mark- ... .pdfputparams currentdevice null false counttomark 1 add 3 roll % Don't allow the page device to get cleared.... {.putdeviceparams} .currentpagedevice pop {.setpagedevice} 3 .execn } bind def % Convert relevant operands to strings in an array. /.pdfcvsloop { % -mark- values ... markname start step .pdfcvsloop % [values ... ctm markname] matrix currentmatrix .pdfcvs 4 1 roll counttomark 1 add 2 roll ] 3 1 roll % Stack: values start step 2 index length 3 sub { 2 copy 2 copy get .pdfcvs put pop } for } bind def /.pdfcvsall { % -mark- values ... markname .pdfcvsall <> 0 1 .pdfcvsloop } bind def /.pdfcvseven { % -mark- key value ... markname .pdfcvseven <> 1 2 .pdfcvsloop } bind def /.pdfcvsnone { % -mark- values ... markname .pdfcvsnone <> 100000 1 .pdfcvsloop } bind def /.pdfcvsfirst { % -mark- first values ... markname .pdfcvsfirst<> .pdfcvsnone dup 0 2 copy get .pdfcvs put } bind def % The procedures in the following dictionary are called with the entire % pdfmark operand list (including the pdfmark name) on the stack; % they may modify this ad lib. They must call .pdfcvsxxx. /.pdfmarkparams mark % Unpack a dictionary for PUT, and don't convert stream data. /PUT { counttomark 3 eq { 1 index type /dicttype eq { pop { } forall /.PUTDICT .pdfcvsall } { pop dup type /filetype eq { % Read the file into a sequence of strings. % This isn't great, but it's simple. { dup 1000 string readstring not { exch exit } if exch } loop closefile } if /.PUTSTREAM .pdfcvsfirst } ifelse } { .pdfcvsall } ifelse } bind % Unpack the array for PUTINTERVAL. /PUTINTERVAL { pop aload pop /.PUTINTERVAL .pdfcvsall } bind .dicttomark readonly def /.pdfparamerror { % ? ? ? -mark- ... .pdfparamerror - counttomark 4 add 2 roll cleartomark pop pop pop .systemvar exch signalerror } bind def /pdfmark { % -mark- ... pdfmark - counttomark 1 add copy //.pdfmarkparams 1 index .knownget { exec } { .pdfcvsall } ifelse mark /pdfmark 3 -1 roll .pdfputparams dup type /booleantype ne { /pdfmark .pdfparamerror } if cleartomark } odef userdict /pdfmark .undef currentdict /.pdfmarkparams .undef % Define setdistillerparams / currentdistillerparams. % Distiller parameters are currently treated as device parameters. /.distillerparamkeys mark % General parameters -- all distillers % ****** NOTE: StartPage and EndPage are disabled because % ****** EndPage clashes with a page device parameter. /ASCII85EncodePages { } /AutoRotatePages { } /Binding { } /CompressPages { } /DefaultRenderingIntent { } /DetectBlends { } /DoThumbnails { } % /EndPage { } /ImageMemory { } /LockDistillerParams { } /LZWEncodePages { } /OPM { } /PreserveHalftoneInfo { } /PreserveOPIComments { } /PreserveOverprintSettings { } % /StartPage { } /TransferFunctionInfo { } /UCRandBGInfo { } /UseFlateCompression { } % General parameters -- PDF writer /CoreDistVersion { } /CompatibilityLevel { } /Optimize { } /ParseDSCCommentsForDocInfo { } /ParseDSCComments { } /EmitDSCWarnings { } /CreateJobTicket { } /PreserveEPSInfo { } /AutoPositionEPSFile { } /PreserveCopyPage { } /UsePrologue { } % Color sampled image parameters /ColorACSDict { } /AntiAliasColorImages { } /AutoFilterColorImages { } /ColorImageDepth { } /ColorImageDict { } /DownsampleColorImages { } /ColorImageDownsampleThreshold { } /ColorImageDownsampleType { } /EncodeColorImages { } /ColorImageFilter { } /ColorImageResolution { } % Color processing parameters /CalCMYKProfile { } /CalGrayProfile { } /CalRGBProfile { } /sRGBProfile { } /ColorConversionStrategy { } /ConvertCMYKImagesToRGB { } /ConvertImagesToIndexed { } % Grayscale sampled image parameters /GrayACSDict { } /AntiAliasGrayImages { } /AutoFilterGrayImages { } /GrayImageDepth { } /GrayImageDict { } /DownsampleGrayImages { } /GrayImageDownsampleThreshold { } /GrayImageDownsampleType { } /EncodeGrayImages { } /GrayImageFilter { } /GrayImageResolution { } % Monochrome sampled image parameters /AntiAliasMonoImages { } /MonoImageDepth { } /MonoImageDict { } /DownsampleMonoImages { } /MonoImageDownsampleThreshold { } /MonoImageDownsampleType { } /EncodeMonoImages { } /MonoImageFilter { } /MonoImageResolution { } % Font embedding parameters /AlwaysEmbed { dup length 0 gt { dup 0 get false eq { dup length 1 sub 1 exch getinterval exch pop /~AlwaysEmbed exch } if } if } /NeverEmbed { dup length 0 gt { dup 0 get false eq { dup length 1 sub 1 exch getinterval exch pop /~NeverEmbed exch } if } if } /CannotEmbedFontPolicy { } /EmbedAllFonts { } /MaxSubsetPct { } /SubsetFonts { } .dicttomark readonly def /.distillerdevice { currentdevice .devicename /pdfwrite eq { currentdevice } { /pdfwrite finddevice } ifelse } bind def /setdistillerparams { % setdistillerparams - .distillerdevice null false mark 4 index { //.distillerparamkeys 2 index .knownget { exec } { pop pop } ifelse } forall .putdeviceparams dup type /booleantype ne { /setdistillerparams .pdfparamerror } { pop pop pop } ifelse } odef /currentdistillerparams % - currentdistillerparams { .distillerdevice //.distillerparamkeys .getdeviceparams .dicttomark } odef % Patch 'where' so that the distillerparams operators are only visible % if the pdfwrite device is the current one, for the benefit of badly % designed PostScript files that "know" they have to do something different % if a distiller is processing them. .wheredict /currentdistillerparams { currentdevice .devicename /pdfwrite eq { .where } { .where pop dup //systemdict eq { pop false } { true } ifelse } ifelse } bind put .wheredict /setdistillerparams .wheredict /currentdistillerparams get put