#!/bin/sh

#!/bin/sh

# application/vnd.cups-pdf -> application/vnd.cups-postscript filter

# Contributed by Johan Kiviniemi, Robert Sander <robert.sander@epigenomics.com>,
# and Till Kamppeter. Licensed under the terms of the CUPS Debian
# packaging.
# The typical filter chain using this filter:
# (something that outputs pdf)
# -> pdftopdf
# -> cpdftocps (runs Poppler's pdftops and then CUPS' pstops)
# -> (postscript printer)

# The emit-jcl option can be safely passed through to pstops, since pdftops
# strips any JCL output by pdftopdf before processing the PDF. pstops then
# simply does the right thing regarding JCL for pdftops’ output.
# $Id: $
#

set -e

PDF2PS=/usr/bin/pdftops
PDF2PS_OPTIONS=""

# Check whether pdftops supports the "-origpagesizes" option
HAVE_ORIGPAGESIZES=no
if `$PDF2PS -h 2>&1 | grep -q -- -origpagesizes 2>/dev/null`; then
    HAVE_ORIGPAGESIZES=yes
fi

echo "DEBUG: pdftops argv[$#] = $@" >&2
echo "DEBUG: PPD: $PPD" >&2
echo "DEBUG: $PDF2PS supports '-origpagesizes': $HAVE_ORIGPAGESIZES" >&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

# Apply PPD settings.

pslevel=2
if test -e "$PPD"; then
    # Read LanguageLevel from PPD file
    eval "$(sed -nre 's/^\*LanguageLevel:\s*\"?([0-9]+)\"?.*/pslevel_from_ppd="\1"/pi' "$PPD")"
    # If the PPD file specifies a LanguageLevel: use it
    if test -n "$pslevel_from_ppd"; then
         pslevel=$pslevel_from_ppd
    fi
fi
echo "DEBUG: PostScript Level: $pslevel" >&2

duplex=no
if test -e "$PPD"; then
    eval "$(sed -nre 's/^\*Default(sides|Duplex|EFDuplex|EFDuplexing|KD03Duplex|JCLDuplex):\s*(two-sided|Duplex|On|True|Yes|1)\b.*/duplex="yes"/pi' "$PPD")"
fi
eval "$(printf "%s" "$5" | sed -nre 's/.*(^|\s)(sides|Duplex|EFDuplex|EFDuplexing|KD03Duplex|JCLDuplex)=(two-sided|Duplex|On|True|Yes|1)\b.*/duplex="yes"/pi')"
echo "DEBUG: Duplex: $duplex" >&2

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

if test -n "$resolution"; then
    # If the resolution is not symmetric, use the higher of the two,
    # Ghostscript ps2write device does not work with asymmetric resolutions.
    xres=
    yres=
    eval "$(printf "%s" "$resolution" | sed -nre 's/.*(^|\s)([0-9]+)x([0-9]+).*/xres="\2"; yres="\3"/pi')"
    if test -n "$xres" && test -n "$yres"; then
	if [ "$xres" -gt "$yres" ]; then
	    resolution=$xres
	else
	    resolution=$yres
	fi
    fi
fi

width=
height=
bl_x=
bl_y=
tr_x=
tr_y=
margin_l=
margin_b=
margin_r=
margin_t=
pagesize=
unit=
customw=
customh=
eval "$(printf "%s" "$5" | sed -nre 's/.*(^|\s)(media|PageSize)=(\S+).*/pagesize="${pagesize:-\3}"/pi')"
if test -e "$PPD"; then
    eval "$(sed -nre 's/^\*DefaultPageSize:\s*(\S+).*/pagesize="${pagesize:-\1}"/pi' "$PPD")"
fi
echo "DEBUG: Page size: $pagesize" >&2

eval "$(printf "%s" "$pagesize" | sed -nre 's/^Custom\.([0-9\.]+)x([0-9\.]+)(\S*)$/customw="\1"; customh="\2"; unit="\3"/pi')"

if test -n "$customw" && test -n "$customh"; then
    echo "DEBUG: Custom page size: $customw x $customh $unit" >&2

    if test "$unit" = "in"; then
	width="$(printf "scale=0; (%s)*(72.0)/(1.00)\n" "$customw" | bc)" 
	height="$(printf "scale=0; (%s)*(72.0)/(1.00)\n" "$customh" | bc)"
    elif test "$unit" = "cm"; then
	width="$(printf "scale=0; (%s)*(72.0)/(2.54)\n" "$customw" | bc)" 
	height="$(printf "scale=0; (%s)*(72.0)/(2.54)\n" "$customh" | bc)"
    elif test "$unit" = "mm"; then
	width="$(printf "scale=0; (%s)*(72.0)/(25.4)\n" "$customw" | bc)" 
	height="$(printf "scale=0; (%s)*(72.0)/(25.4)\n" "$customh" | bc)"
    else
	width="$(printf "scale=0; (%s)/(1.00)\n" "$customw" | bc)" 
	height="$(printf "scale=0; (%s)/(1.00)\n" "$customh" | bc)"
    fi

    if test -e "$PPD"; then
	eval "$(sed -nre 's|^\*HWMargins:\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s*|bl_x="\1"; bl_y="\2"; tr_x="\3"; tr_y="\4"|p' "$PPD")"
	
	if test -n "$tr_x"; then
	    tr_x="$(printf "scale=8; (%s)-(%s)\n" "$width" "$tr_x" | bc)"
	fi
	if test -n "$tr_y"; then
	    tr_y="$(printf "scale=8; (%s)-(%s)\n" "$height" "$tr_y" | bc)"
	fi
    fi
elif test -n "$pagesize" && test -e "$PPD"; then
    eval "$(sed -nre 's|^\*PaperDimension\s+'"$pagesize"'(/[^:]+\|):\s*"(\S+)\s+(\S+)".*|width="\2"; height="\3"|p' "$PPD")"
    
    eval "$(sed -nre 's|^\*ImageableArea\s+'"$pagesize"'(/[^:]+\|):\s*"(\S+)\s+(\S+)\s+(\S+)\s+(\S+)".*|bl_x="\2"; bl_y="\3"; tr_x="\4"; tr_y="\5"|p' "$PPD")"
fi

test -n "$bl_x" || bl_x=0
test -n "$bl_y" || bl_y=0
test -n "$tr_x" || tr_x=$width
test -n "$tr_y" || tr_y=$height

echo "DEBUG: Width: $width, height: $height, absolute margins: $bl_x, $bl_y, $tr_x, $tr_y" >&2

if test -n "$width" && test -n "$height" && \
   test -n "$bl_x"  && test -n "$bl_y" && \
   test -n "$tr_x"  && test -n "$tr_y"; then
    margin_l="$bl_x"
    margin_b="$bl_y"
    margin_r="$(printf "scale=8; (%s)-(%s)\n" "$width" "$tr_x" | bc)"
    margin_t="$(printf "scale=8; (%s)-(%s)\n" "$height" "$tr_y" | bc)"
fi
echo "DEBUG: Relative margins: $margin_l, $margin_b, $margin_r, $margin_t" >&2

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

# Poppler's pdftops needs the page dimensions as integer values
width=`echo $width | sed -e 's/[\.a-z].*$//i'`
height=`echo $height | sed -e 's/[\.a-z].*$//i'`

fitplot=
eval "$(printf "%s" "$5" | sed -nre 's/.*(^|\s)(fitplot|fit-to-page)($|\s).*/fitplot=1/pi')"

ppd_opts=
if test -n "$pslevel"; then
    # Poppler's PostScript Level 3 output does not work on some printers
    if [ "$pslevel" -ne "3" ]; then
	pslevel=2
    fi
    ppd_opts="${ppd_opts:+$ppd_opts }-level$pslevel"
#    if [ "$pslevel" -ne "3" ]; then
#	ppd_opts="${ppd_opts:+$ppd_opts }-noembtt"
#    fi
fi
#if test -n "$resolution"; then
#  ppd_opts="${ppd_opts:+$ppd_opts }-r$resolution"
#fi
if test -n "$fitplot" || [ "$HAVE_ORIGPAGESIZES" = "no" ]; then
    if test -n "$width"; then
	ppd_opts="${ppd_opts:+$ppd_opts }-paperw $width"
    fi
    if test -n "$height"; then
	ppd_opts="${ppd_opts:+$ppd_opts }-paperh $height"
    fi
fi
if test -z "$fitplot" && [ "$HAVE_ORIGPAGESIZES" = "yes" ]; then
    ppd_opts="${ppd_opts:+$ppd_opts }-origpagesizes"
fi
if test -n "$fitplot"; then
    ppd_opts="${ppd_opts:+$ppd_opts }-expand"
fi
if [ "$duplex" = "yes" ]; then
    ppd_opts="${ppd_opts:+$ppd_opts }-duplex"
fi
echo "DEBUG: PPD options: $ppd_opts" >&2

# We do not supply the margins to the ps2pdf process, as this breaks
# full-bleed printing and also disturbs the printing if PPDs have too
# conservative margin definitions.
inject_ps=

# We read the data into a temporary files
tempfiles=
trap 'rm -f $tempfiles' 0 1 2 13 15

# Injection
echo "DEBUG: PostScript to be injected: $inject_ps" >&2
infile=
if test -n "$inject_ps"; then
    echo "DEBUG: Injecting PostScript: $inject_ps" >&2

    orig_infile="$infile"

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

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

ifile=$(mktemp -t pdftops.XXXXXX)
tempfiles="$tempfiles $ifile"

# Allow rendering of PDF files which have non-PDF stuff before and after the
# real PDF part, like for example PJL commands. Remove everything before
# "%PDF-X.Y" and after "%%EOF"
cat $infile | perl -e '$f = join("", <>); $f =~ s/^.*(\%PDF-\d+\.\d+)/$1/s; $f =~ s/(\%\%EOF\r?\n?).*$/$1/s; print $f' > "$ifile"

# 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
'

# 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*)?//gi' -e 's/^\s+//'
)

copies=`grep -a '%%PDFTOPDFNumCopies' "$ifile" | perl -p -e 's/^\D*(\d+)\s*$/\1/'`
[ -n "$copies" ] || copies=1
collate=
grep -qi '%%PDFTOPDFCollate\s*:\s*true' "$ifile" && collate="collate"

echo "DEBUG: Device copies: $copies; device collate: $collate" 1>&2

echo "DEBUG: Running $PDF2PS $PDF2PS_OPTIONS $ppd_opts $ifile -" >&2
echo "DEBUG: Running pstops '$1' '$2' '$3' '$copies' '$collate $MASKED_OPTS'" >&2
$PDF2PS $PDF2PS_OPTIONS $ppd_opts "$ifile" - | \
  /usr/lib/cups/filter/pstops "$1" "$2" "$3" "$copies" "$collate $MASKED_OPTS"


# vim:set et sw=2 sts=2:
