#!/bin/sh

# $Id: pstopdf,v 1.3 2003/02/15 15:21:00 gurubert Exp $
#
# This is a Postscript to PDF filter for CUPS
#
# (C) 2003 Robert Sander <robert.sander@epigenomics.com>
#
# Released under GPL
#
# NO WARRANTY AT ALL
#

set -e

# These options are *not* passed through to pstops, since pdftopdf or
# equivalent has already processed them.
MASK='
  brightness
  Collate
  cupsEvenDuplex
  fitplot
  gamma
  hue
  landscape
  mirror
  multiple-document-handling
  natural-scaling
  number-up
  number-up-layout
  orientation-requested
  OutputOrder
  page-border
  page-bottom
  page-label
  page-left
  page-ranges
  page-right
  page-set
  page-top
  position
  saturation
  scaling
  sides
'

# Convert MASK to a regexp.
MASK_RE=$(
  set -- $MASK
  IFS='|'
  printf "%s" "$*"
)

# Annihilate all forms of the masked options from $5:
# - <option>=parameter
# - <option>   (boolean)
# - no<option> (boolean)
MASKED_OPTS=$(
  printf "%s" "$5" | \
    sed -r -e 's/(^|\s+)(no)?('"$MASK_RE"')(=\S*)?//g' -e 's/^\s+//'
)

PS2PS=/usr/bin/ps2ps
PSTOPS=/usr/lib/cups/filter/pstops
PS2PDF=/usr/bin/ps2pdf13
PS2PS_OPTIONS="-dAutoRotatePages=/None -dAutoFilterColorImages=false
                -dNOPLATFONTS -dPARANOIDSAFER -sstdout=%stderr"
PS2PDF_OPTIONS="$PS2PS_OPTIONS -dColorImageFilter=/FlateEncode"

echo "DEBUG: pstopdf argv[$#] = $@" >&2

if [ $# -lt 5 -o $# -gt 6 ]; then

  echo "ERROR: $0 job-id user title copies options [file]" >&2
  exit 1

fi

# Read from given file.
if [ -n "$6" ]; then
  exec <"$6"
fi

tempfiles=
trap 'rm -f $tempfiles' 0 1 2 13 15

infile=$(mktemp -t pstopdf.XXXXXX)
tempfiles="$tempfiles $infile"

cat >"$infile"

# Apply PPD settings.

resolution=
eval "$(printf "%s" "$5" | sed -nre 's/.*(^|\s)Resolution=([0-9.]+(x[0-9.]+)?).*/resolution="${resolution:-\2}"/p')"
if test -e "$PPD"; then
  eval "$(sed -nre 's/^\*DefaultResolution:\s+([0-9.]+(x[0-9.]+)?).*/resolution="${resolution:-\1}"/p' "$PPD")"
fi

pagesize=
eval "$(printf "%s" "$5" | sed -nre 's/.*(^|\s)(media|PageSize)=(\S+).*/pagesize="${pagesize:-\3}"/p')"
if test -e "$PPD"; then
  eval "$(sed -nre 's/^\*DefaultPageSize:\s+(.+)$/pagesize="${pagesize:-\1}"/p' "$PPD")"
fi

width=
height=
tl_x=
tl_y=
br_x=
br_y=
if test -n "$pagesize" && test -e "$PPD"; then
  eval "$(sed -nre 's|^\*PaperDimension\s+'"$pagesize"'/[^"]+:\s+"(\S+)\s+(\S+)"$|width="\1"; height="\2"|p' "$PPD")"

  eval "$(sed -nre 's|^\*ImageableArea\s+'"$pagesize"'/[^"]+:\s+"(\S+)\s+(\S+)\s+(\S+)\s+(\S+)"$|tl_x="\1"; tl_y="\2"; br_x="\3"; br_y="\4"|p' "$PPD")"
fi

margin_l=
margin_b=
margin_r=
margin_t=
if test -n "$width" && test -n "$height" && \
   test -n "$tl_x" && test -n "$tl_y" && \
   test -n "$br_x" && test -n "$br_y"; then
  margin_l="$tl_x"
  margin_b="$(printf "scale=8; (%s)-(%s)\n" "$height" "$br_y" | bc)"
  margin_r="$(printf "scale=8; (%s)-(%s)\n" "$width" "$br_x" | bc)"
  margin_t="$tl_y"
fi

inject_ps=
if test -n "$margin_l" && test -n "$margin_b" && \
   test -n "$margin_r" && test -n "$margin_t"; then
  inject_ps="<</.HWMargins[$margin_l $margin_b $margin_r $margin_t] /Margins[0 0]>>setpagedevice"
fi

ppd_opts=
if test -n "$resolution"; then
  ppd_opts="${ppd_opts:+$ppd_opts }-r$resolution"
fi
if test -n "$width"; then
  ppd_opts="${ppd_opts:+$ppd_opts }-dDEVICEWIDTHPOINTS=$width"
fi
if test -n "$height"; then
  ppd_opts="${ppd_opts:+$ppd_opts }-dDEVICEHEIGHTPOINTS=$height"
fi

# Injection
if test -n "$inject_ps"; then
  echo "DEBUG: Injecting PostScript: $inject_ps" >&2

  orig_infile="$infile"

  infile=$(mktemp -t pstopdf.XXXXXX)
  tempfiles="$tempfiles $infile"

  perl -p -e 'if (! $did) { s:(^%!.*)$:\1\n'"$inject_ps"': && $did++; }' "$orig_infile" > "$infile"
fi

# DRM

DRM_MATCH='^%.*Removing the following.*lines is illegal.*Digital Copyright Act'
if egrep -q "$DRM_MATCH" "$infile"; then
  # This PS is DRM-infested. Normalize it with ps2ps first.
  echo "DEBUG: Normalizing Adobe Reader PostScript with ps2ps" >&2

  DRMFILTER="$PS2PS $PS2PS_OPTIONS $ppd_opts - -"
else
  DRMFILTER=cat
fi

$PSTOPS "$1" "$2" "$3" 1 "$MASKED_OPTS" "$infile" | $DRMFILTER | $PS2PDF $PS2PDF_OPTIONS $ppd_opts - -
