#!/bin/sh
# 
# Photo Image Print System
# Copyright (C) 2001-2004 EPSON KOWA Corporation.
# Copyright (C) SEIKO EPSON CORPORATION 2001-2004.
# 
#  This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
# 

# !!Warning!!
# Not do a check of input format.
# Please implement it to input only Psotscript beforehand.

# Debug
#set -x


DEFAULT_RESOL=360
FRESET=/usr/local/libexec/pips/printer/freset

### Optional initialization
# Perhaps default setting will be defined.
gsopts_default="-q -dNOPROMPT -dNOPAUSE -dSAFER -sOutputFile=- - -c quit"
printer=
rcpath=/usr/local/etc/pipsrc
gsdev=png16m
gsopts=
height=
height=
media=
papath=/usr/local/libexec/pips/printer/paper.csv
resol=
width=
fitp=
npage=

# Others
pstops_opt=
source=
bc_scale=3

usage()
{
    cat 1>&2 <<EOF
Usage   : $0 [ options ] [ [ input ] output ]
Options :
    -h                Display this information
    -H <value>        Height of output image
    -P <name>         Printer name at searching pips configuration
    -R <value>        Resolution of output image
    -W <value>        Width of output image
    -c <file>         Path to pipsrc
    -d <gs device>    Driver name of gs
    -f                Fit to page
    -g <gs options>   Add optional to gs
    -l <value>        Multi page number
    -m <name>         Paper name at searching paper list
    -p <file>         Path to paper list
    -r <file>         Path to freset
    -s <name>         PaperSource name
EOF
}


#
# Checking Ghostscript
#
GS=`which gs`
if [ ! -x "$GS" ] ; then # error check
    echo "$0 : gs (Ghostscript) was not found." >&2
    exit 1
fi


#
# Get options
#
opt=
while getopts H:P:R:W:c:d:fg:hl:m:p:r:s: opt ; do
    case $opt in
	H) height="$OPTARG" ;;
	P) printer="$OPTARG" ;;
	R) resol="$OPTARG" ;;
	W) width="$OPTARG" ;;
	c) rcpath="$OPTARG" ;;
	d) gsdev="$OPTARG" ;;
	f) fitp="ON" ;;
	g) gsopts="$gsopts $OPTARG" ;;
	l) npage="$OPTARG" ;;
	m) media="$OPTARG" ;;
	p) papath="$OPTARG" ;;
	r) FRESET="$OPTARG" ;;
	s) source="$OPTARG" ;;
	h) usage ; exit 1 ;;
	\?) usage ; exit 1
	    ;;
    esac
done

shift `expr $OPTIND - 1`


#
# set input & output
#
if [ -n "$1" ] ; then
    if [ -r "$1" ] ; then
	exec <$1
    else
	usage ; exit 1
    fi
fi

if [ -n "$2" ] ; then
    if [ -r "$2" ] ; then
	exec >$2
    else
	usage ; exit 1
    fi
fi


#
# Examine input PostScript.
#
GS_PSREF="$GS -g32767x32767 -sDEVICE=pswrite -q -dNOPROMPT -dNOPAUSE -dSAFER -sOutputFile=- - -c quit"

line=`$GS_PSREF 2>/dev/null | grep -e '^%%BoundingBox:' | sed -e "s@^.*\%\%BoundingBox:[[:space:]]*@@"`
$FRESET

line=`echo "$line" | tr -d "\012\015" | sed -e "s@(atend)@@g" -e "s@^[[:space:]]*@@"`

if [ x"$line" = x ] ; then # error check
    echo "$0 : There is an error in the Postscript file." >&2
    exit 1

else
    for variable in bbox_sx bbox_sy bbox_ex bbox_ey ; do
	eval $variable=`echo "$line" | sed -e "s@[[:space:]].*@@"`
	line=`echo "$line" | sed -e "s@^[[:digit:]]*[[:space:]]*@@"`
    done
    if [ -z bbox_sx -o -z bbox_sy -o -z bbox_ex -o -z bbox_ey ] ; then # error check
	echo "$0 : There is an error in the Postscript file." >&2
	exit 1
    fi
fi


#
# Resource Load
#
if [ -z "$media" -o -z "$resol" -o -z "$fitp" -o -z "$npage" -o -z "$source" -a -r "$rcpath" -a -n "$printer" ] ; then
    key=
    number=`grep -n "$printer" $rcpath | sed -e "s@:.*@@"`

    if [ x$number = x ] ; then # error check
	echo "$0 : $rcpath : does not include entry of \"$printer\"." >&2

    else
	i=0
	exec 3< $rcpath
	while read line <&3 ; do
	    if [ "$i" -le "$number" ] ; then
		i=`expr $i + 1`
		continue;
	    fi
	    if [ x"`echo \"$line\" | grep \"^.*\[.*\].*$\"`" != x ] ; then
		break
	    fi
	    
	    resource=`echo "$line" | sed -e 's@=.*$@@' -e 's@[[:space:]]@@g' | tr A-Z a-z`
	    value=`echo "$line" | sed -e 's@[[:space:]]@@g' -e 's@^.*=@@' -e 's@#.*$@@'`
	    
	    case "$resource" in
		"mediasize") media=${media:="$value"} ;;
		"resolution") resol=${resol:="$value"} ;;
		"fit2page") fitp=${fitp:="$value"} ;;
		"multipage") npage=${npage:="$value"} ;;
		"papersource") source=${source:="$value"} ;;
		*) ;;
	    esac    
	done
	exec 3<&-
    fi
fi

# default set
fitp=${fitp:=OFF}
npage=${npage:=1}
media=${media:=A4}
resol=${resol:=360}
source=${source:=AUTO}


#
# Paper List Load
#
csvshift()
{
    key_csvshift=
    key_csvshift=`echo "$1" | sed -e 's@,.*$@@'`
    NEWLINE=`echo "$1" | sed -e ''s@^"$key_csvshift",@@''`
}


if [ -z "$width" -o  -z "$height" ] ; then

    if [ -r "$papath" -a -n "$media" ] ; then

	line=`grep "^[:space:]*$media," < $papath`
	
	csvshift "$line"
	csvshift "$NEWLINE"
	line="$NEWLINE"

	for variable in p_width p_height mg_r mg_l mg_t mg_b ; do
	    eval $variable=`echo "$line" | sed -e 's@,.*$@@'`
	    
	    csvshift "$line"
	    line="$NEWLINE"
	done

	width=${width:=$p_width}
	height=${height:=$p_height}
    fi

fi


#
# Last check
#
if [ -z "$gsdev" -o -z "$resol" -o -z "$width" -o -z "$height" ] ; then # error check

    echo "$0 : Cannot start process." >&2
    exit 1

fi


#
# Utility
#

if [ $npage -ne 1 -o "$fitp" = "ON" ] ; then
    # Convert paper size into 72dpi. (72dpi=Postscript default)
    h_72dpi=`expr $height \* 72 / 360`
    w_72dpi=`expr $width \* 72 / 360`

    plus_margin=6 # 5.6 pixel -2mm margin
    r_72dpi=0
    l_72dpi=0
    t_72dpi=0
    b_72dpi=0
    if [ "$source" = "AUTO" -o "$source" = "ROLL" ] ; then
	if [ -z "$mg_r" -o -z "$mg_l" ] ; then # error check
	    echo "$0 : PaperSize does not suit for the PaperSource." >&2
	    exit 1
	fi
	r_72dpi=`expr $mg_r \* 72 / 360 + $plus_margin`
	l_72dpi=`expr $mg_l \* 72 / 360 + $plus_margin`

	if [ "$source" = "AUTO" ] ; then
	    if [ -z "$mg_t" -o -z "$mg_b" ] ; then # error check
		echo "$0 : PaperSize does not suit for the PaperSource." >&2
		exit 1
	    fi
	    t_72dpi=`expr $mg_t \* 72 / 360 + $plus_margin`
	    b_72dpi=`expr $mg_b \* 72 / 360 + $plus_margin`
	fi
    fi
fi


#
# Setting coordinate
#
if [ $fitp = "ON" ] ; then

    w_input=`expr $bbox_ex - $bbox_sx`
    h_input=`expr $bbox_ey - $bbox_sy`

    if [ $w_input -le 0 -o $h_input -le 0 ] ; then
    	echo "$0 : There is an error in the Postscript file." >&2
	exit 1
    fi

    if [ $t_72dpi -gt $b_72dpi ] ; then
	mg_h_72dpi=$t_72dpi
    else
	mg_h_72dpi=$b_72dpi
    fi

    if [ $r_72dpi -gt $l_72dpi ] ; then
	mg_w_72dpi=$r_72dpi
    else
	mg_w_72dpi=$l_72dpi
    fi

    case "$npage" in
	1)
	    bcopt_wsize="( $w_72dpi - $mg_w_72dpi * 2 )"
	    bcopt_hsize="( $h_72dpi - $mg_h_72dpi * 2 )"
	    ;;

	2)
	    bcopt_wsize="( $h_72dpi / 2 - $mg_h_72dpi * 2 )"
	    bcopt_hsize="( $w_72dpi - $mg_w_72dpi * 2 )"
	    ;;

	4) 
	    bcopt_wsize="( $w_72dpi / 2 - $mg_w_72dpi * 2 )"
	    bcopt_hsize="( $h_72dpi / 2 - $mg_h_72dpi * 2 )"
	    ;;

	*) ;;
    esac

    wmag=`echo "scale = $bc_scale; $bcopt_wsize / $w_input" | bc`
    hmag=`echo "scale = $bc_scale; $bcopt_hsize / $h_input" | bc`

    if [ `echo "$wmag < $hmag" | bc` -ne 0 ] ; then
	magnify=$wmag
	w_margin=`echo "scale = $bc_scale; -$bbox_sx * $magnify" | bc`
	eval h_margin=`echo "scale = $bc_scale; ( $bcopt_hsize - $magnify * $h_input ) / 2 - $bbox_sy * $magnify" | bc`
    else
	magnify=$hmag
	eval w_margin=`echo "scale = $bc_scale; ( $bcopt_wsize - $magnify * $w_input ) / 2 - $bbox_sx * $magnify" | bc`
	h_margin=`echo "scale = $bc_scale; -$bbox_sy * $magnify" | bc`
    fi

elif [ $npage -ne 1 ] ; then # $fitp = "OFF"

    w_input=$w_72dpi
    h_input=$h_72dpi

    mg_w_72dpi=0
    mg_h_72dpi=0


    case "$npage" in
	1)
	    bcopt_wsize="( $w_72dpi )"
	    bcopt_hsize="( $h_72dpi )"
	    ;;

	2)
	    bcopt_wsize="( $h_72dpi / 2 )"
	    bcopt_hsize="( $w_72dpi )"
	    ;;

	4) 
	    bcopt_wsize="( $w_72dpi / 2 )"
	    bcopt_hsize="( $h_72dpi / 2 )"
	    ;;

	*) ;;
    esac

    wmag=`echo "scale = $bc_scale; $bcopt_wsize / $w_input" | bc`
    hmag=`echo "scale = $bc_scale; $bcopt_hsize / $h_input" | bc`

    if [ `echo "$wmag < $hmag" | bc` -ne 0 ] ; then
	magnify=$wmag
	w_margin=0
	eval h_margin=`echo "scale = $bc_scale; ( $bcopt_hsize - $magnify * $h_input ) / 2" | bc`
    else
	magnify=$hmag
	eval w_margin=`echo "scale = $bc_scale; ( $bcopt_wsize - $magnify * $w_input ) / 2" | bc`
	h_margin=0
    fi

fi

#
# Setting Multi Page
#
PSTOPS=

if [ $fitp = "ON" -o  $npage -ne 1 ] ; then
    PSTOPS=`which pstops`

    if [ ! -x "$PSTOPS" ] ; then # error check
	echo "$0 : pstops (PSUtils) was not found."
	exit 1
    fi

    pstops_opt="-w$bbox_ex -h$bbox_ey"

    if [ $npage -eq 1 ] ; then
	w_margin=`echo "scale = $bc_scale; $w_margin + $mg_w_72dpi" | bc | sed -e "s@^\.@0.@" -e "s@\..*@@"`
	h_margin=`echo "scale = $bc_scale; $h_margin + $mg_h_72dpi" | bc | sed -e "s@^\.@0.@" -e "s@\..*@@"`
	Page1="$magnify($w_margin,$h_margin)"

	pstops_opt="$pstops_opt 1:0@$Page1"

    elif [ $npage -eq 2 ] ; then
	w_margin=`echo "scale = $bc_scale; $w_margin + $mg_h_72dpi" | bc | sed -e "s@^\.@0.@" -e "s@\..*@@"`
	h_margin=`echo "scale = $bc_scale; $h_margin + $mg_w_72dpi" | bc | sed -e "s@^\.@0.@" -e "s@\..*@@"`	
	Page1="$magnify(`expr $w_72dpi - $h_margin`,$w_margin)"
	Page2="$magnify(`expr $w_72dpi - $h_margin`,`expr $h_72dpi / 2 + $w_margin`)"

	pstops_opt="$pstops_opt 2:0L@$Page1+1L@$Page2"

    elif [ $npage -eq 4 ] ; then
	w_margin=`echo "scale = $bc_scale; $w_margin + $mg_w_72dpi" | bc | sed -e "s@^\.@0.@" -e "s@\..*@@"`
	h_margin=`echo "scale = $bc_scale; $h_margin + $mg_h_72dpi" | bc | sed -e "s@^\.@0.@" -e "s@\..*@@"`
	Page1="$magnify($w_margin,`expr $h_72dpi / 2 + $h_margin`)"
	Page2="$magnify(`expr $w_72dpi / 2 + $w_margin`,`expr $h_72dpi / 2 + $h_margin`)"
	Page3="$magnify($w_margin,$h_margin)"
	Page4="$magnify(`expr $w_72dpi / 2 + $w_margin`,$h_margin)"
    
	pstops_opt="$pstops_opt 4:0@$Page1+1@$Page2+2@$Page3+3@$Page4"
    fi
fi

#
# Printing
#
width=`expr \`expr $resol \* $width\` / $DEFAULT_RESOL`
height=`expr \`expr $resol \* $height\` / $DEFAULT_RESOL`

# running ghostscript
gsopts="-r$resol -g${width}x${height} -sDEVICE=$gsdev $gsopts $gsopts_default"

if [ -n "$PSTOPS" ] ; then
    exec $GS_PSREF -r360 2>/dev/null | $PSTOPS $pstops_opt 2>/dev/null | $GS $gsopts
    exit $?
fi

exec $GS $gsopts
