#!/bin/sh
#
# hpgl2gif - convert HPGL plot file to GIF image
#
# Usage: hpgl2gif [-p color,color,color,...] [-b color] [-h height] [-w width] \
#		  [-G] [-A|-B|-A3|-A4] [-t] [-f[vfont]] [-r] [-m] [hpglfile] \
#		  > giffile
#
# where: -p sets colors for various pens, up to 8
#           colors can be names without spaces as in /usr/X11R6/lib/X11/rgb.txt
#           or hexadecimal values as #FFAA99
#           (default is -p $SCRPENS, i.e. contents of SCRPENS env. variable)
#        -p bw or -p wb will cause a faster rendering of a simple black
#           on white or white on black bitmap image
#        -b sets the image background color (default is white)
#        -h sets the image height in pixels (default is 400)
#        -w sets the image width in pixels (default is 520)
#           if only one of -h or -w is given, the other is set proportionally
#        -G causes a cleaner, but slower rendering, using GhostScript,
#	    also causes lines to be somewhat thicker
#	 -A, -B, -A3, -A4 are page size options that adjust the aspect ratio
#	    and coordinate system to that page size (default is A, but can
#	    be set by the HPGLPAGE environment variable). These options, and...
#	 -t, -f[vfont], -r & -m options are passed directly to hpgl2ras,
#	    hpgl2xpm or hpgl2psc programs which do initial conversion of HPGL
#        hpglfile is the HPGL plot file to be converted (default is std input)
#        output is on standard output which should be redirected to a file
#
# Also called as: hpgl2ppm, hpgl2bmp, hpgl2png and hpgl2tiff to output
# those respective image formats, or hpgl2pdf to make a PDF document.
# For PDFs, GhostScript is always used, and the default size is 7920x6120
# decipoints (US Letter landscape).  Use -w 8420 -h 5950 for A4 landscape.
# When called as hpgl2cps, it will output colour PostScript, with the width
# and height in decipoints as for hpgl2pdf.  See "man emuhpgl" for details
# on other HPGL conversion options and programs.
#
# Copyright (c) 2002-2017, Gilles Detillieux, Spinal Cord Research Centre,
# University of Manitoba.  All Rights Reserved.
#

rgbfile=/dev/null
NEURODIR=${NEURODIR:-/usr/neuro}
for dir in $NEURODIR/lib /usr/X11R6/lib/X11 /usr/lib/X11 /usr/share/X11 \
	/usr/share/emacs/*/etc
do
    if [ -r "$dir/rgb.txt" ]
    then
	rgbfile="$dir/rgb.txt"
	break
    fi
done
ifilteropts=
ofilter=ppmtogif
defwidth=520 defheight=400
defxres=72 defyres=72
width=$defwidth height=$defheight
xres=$defxres yres=$defyres
opts=

pens='/black [0 0 0] def
/red [.8 0 0] def
/green [0 .6 0] def
/blue [0 0 .8] def
/white [1 1 1] def
/yellow [.9 .9 0] def
/cyan [0 .9 .9] def
/magenta [.8 0 .8] def
/gold [.8 .6 0] def
/orange [1 .7 0] def
/purple [.5 0 .8] def
/turquoise [0 .7 .8] def
/brown [.6 .4 .4] def
/gray [.7 .7 .7] def
/pen {7 add 8 mod pens exch get dup 0 get exch dup 1 get exch 2 get setrgbcolor} def
/pens [ black blue green red purple gold brown gray ] def'
mypendefs=
mypens=
mybgcolor=white

setcolor()
{
	color="$1"
	case "$color" in
#	black|red|green|blue|white|yellow|cyan|magenta|gold|orange|purple|turquoise|brown|gray)
#		;;
	0x[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F] | \
	\#[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F] | \
	[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])
		color=`expr "$color" : '.*\(......\)'`
		mypendefs="$mypendefs
/x$color [ <$color> dup 0 get exch dup 1 get exch 2 get ] def"
		color="x$color"
		;;
	*)
		def=`grep -i "	$color" $rgbfile | head -1`
		if [ -z "$def" ]
		then
		    color=gray
		else
		    color=`echo "$color" | sed 's/ /_/g'`
		    def=`echo "$def" | sed 's/	.*/ /; s/  */ /g; s/^ //; s/ / 255.0 div /g'`
		    mypendefs="$mypendefs
/$color [ $def ] def"
		fi
		;;
	esac
}

case "$0" in
*ppm)	ofilter=cat ;;
*bmp)	ofilter=ppmtobmp ;;
*png)	ofilter=pnmtopng ;;
*tif|*tiff)	ofilter=pnmtotiff ;;
*cps)	ofilter=COLOURPS
	defwidth=7920 defheight=6120
	defxres=720 defyres=720
	width=$defwidth height=$defheight
	xres=$defxres yres=$defyres
	;;
*pdf)	ofilter=PS2PDF
	defwidth=7920 defheight=6120
	defxres=720 defyres=720
	width=$defwidth height=$defheight
	xres=$defxres yres=$defyres
	;;
esac

while :
do
 case "$1" in
 -\?|-help|--help)	sed -n '3,/^# Univ/s/^#/ /p' "$0"; exit ;;
 -h) shift
    case "$1" in
    *[^0-9]*)	echo "$0: invalid image height '$1' ignored" >&2 ;;
    *)
	case "$opts" in
	*-w*)	;;	# already set width
	*)	width=`expr "$defwidth" \* "$1" / "$defheight"`
    		xres=`expr "$defxres" \* "$1" / "$defheight"`
		;;
	esac
	opts="${opts}-h"
	height="$1"
	yres=`expr "$defyres" \* "$1" / "$defheight"`
	;;
    esac
    shift
    ;;
 -w) shift
    case "$1" in
    *[^0-9]*)	echo "$0: invalid image width '$1' ignored" >&2 ;;
    *)
	case "$opts" in
	*-h*)	;;	# already set height
	*)	height=`expr "$defheight" \* "$1" / "$defwidth"`
    		yres=`expr "$defyres" \* "$1" / "$defwidth"`
		;;
	esac
	opts="${opts}-w"
	width="$1"
	xres=`expr "$defxres" \* "$1" / "$defwidth"`
	;;
    esac
    shift
    ;;
 -b) shift
    case "$1" in
    "")	echo "$0: no background color given after -b" >&2 ;;
    *)	mybgcolor="$1" ;;
    esac
    shift
    ;;
 -p) shift
    SCRPENS="$1"
    export SCRPENS
    shift
    ;;
 -G) shift
    opts="${opts}-G"
    pens="$pens
.7 40 mul setlinewidth  % use .7 mm pens"
    ;;
 -t|-f*|-r|-m|-[Aa]*|-B) ifilteropts="$ifilteropts $1"
    shift
    ;;
 -?*) echo "Usage:  $0 [-p color,color,color,...] [-b color] \\
		[-h height] [-w width] [-G] [-t] [-f[vfont]] \\
		[-r] [-m] [hpglfile] > giffile
	or $0 --help	for detailed usage information" >&2; exit 1 ;;
 *)
    break
    ;;
 esac
done

case "$ofilter" in
PS2PDF|COLOURPS)
	ropt=
	test `expr "$width" \* 10 / "$height"` -ge 14 && ropt=-A4
	case " $ifilteropts " in
	*\ -r\ *)
		t=$width
		width=$height
		height=$t
		;;
	esac
	;;
*)
	case "$SCRPENS" in
	bw|wb)
		case "$SCRPENS" in
		bw)	inv=1 ;;
		wb)	inv=0 ;;
		esac
		HPGLPENS=11111111 hpgl2ras -xl1 -xh${width} -yl1 -yh${height} \
				$ifilteropts ${@+"$@"} |
			ras2xbm -inv $inv | xbmtopbm | $ofilter
		exit
		;;
	esac

	case "$opts" in
	*-G*)	;;
	*)
		hpgl2xpm -xl1 -xh${width} -yl1 -yh${height} \
				-bg"$mybgcolor" $ifilteropts ${@+"$@"} |
			xpmtoppm | $ofilter
		exit
		;;
	esac
	;;
esac

(
    case "$ofilter" in
    PS2PDF|COLOURPS)
	case "$SCRPENS" in
	bw)	mybgcolor=white
		SCRPENS=black,black,black,black,black,black,black,black ;;
	wb)	mybgcolor=black
		SCRPENS=white,white,white,white,white,white,white,white ;;
	esac
	case "$ofilter" in
	PS2PDF)
	    case " $ifilteropts " in
	    *\ -r\ *)
		;;
	    *)
		echo "%!"
		echo "-90 rotate -612 0 translate"
		;;
	    esac
	    ;;
	esac
	;;
    *)
	ropt=-r
	echo "%!"
	echo "-50 -279 translate"
	;;
    esac
    case "$mybgcolor" in
    white)	;;
    *)	# for background color setting before clipping done
	setcolor "$mybgcolor"
	mypendefs="$mypendefs
$color dup 0 get exch dup 1 get exch 2 get setrgbcolor clippath fill"
	echo "$mypendefs"
	;;
    esac
    hpgl2psc $ropt $ifilteropts /dev/null | sed '/^\/pen/q'
    echo "$pens"

    mypendefs=
    ncolors=0
    saveIFS="$IFS"
    IFS=","
    for color in $SCRPENS
    do
	setcolor "$color"
	mypens="$mypens $color"
	ncolors=`expr $ncolors + 1`
    done
#    while [ $ncolors -lt 8 ]
#    do
#	mypens="$mypens gray"
#	ncolors=`expr $ncolors + 1`
#    done
    case "$ncolors" in
    0)	mypens="$mypens black blue green red purple gold brown gray" ;;
    1)	mypens="$mypens blue green red purple gold brown gray" ;;
    2)	mypens="$mypens green red purple gold brown gray" ;;
    3)	mypens="$mypens red purple gold brown gray" ;;
    4)	mypens="$mypens purple gold brown gray" ;;
    5)	mypens="$mypens gold brown gray" ;;
    6)	mypens="$mypens brown gray" ;;
    7)	mypens="$mypens gray" ;;
    esac
    IFS="$saveIFS"
    mypendefs="$mypendefs
/pens [ $mypens ] def"

    echo "$mypendefs"
    hpgl2psc $ropt $ifilteropts ${@+"$@"} | sed '1,/^\/pen/d'

) | case "$ofilter" in

    COLOURPS)
	cat
	;;

    PS2PDF)
	gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=- \
		-g"${width}x${height}" -c save pop -
	;;

    *)
	gs -q -dNOPAUSE -dBATCH -sDEVICE=ppm -sOutputFile=- \
		-g"${width}x${height}" -r"${xres}x${yres}" - |
	$ofilter
	;;

    esac
