Xref: feenix.metronet.com comp.infosystems.www:2556
Path: feenix.metronet.com!news.ecn.bgu.edu!usenet.ins.cwru.edu!howland.reston.ans.net!pipex!sunic!trane.uninett.no!nntp.uio.no!nntp.uio.no!aas
From: [email protected] (Gisle Aas)
Newsgroups: comp.infosystems.www
Subject: Use gs to render gif images on the fly
Date: 25 Oct 1993 15:30:38 GMT
Organization: Norwegian Computing Center, Oslo, Norway
Lines: 177
Message-ID: <[email protected]>
Reply-To: [email protected]
NNTP-Posting-Host: nora.nr.no

Below is a package for the Plexus http server that shows you how you
can make Ghostscript render some graphics for you on the fly.  This
might be useful for those of you who want to include Greek letters and
other symbols in their html documents. Before you install it you might
want to try some of the following URLs:

  http://nora.nr.no/fancy/clock.gif
  http://nora.nr.no/fancy/clock.gif?400
  http://nora.nr.no/fancy/glyph/g
  http://nora.nr.no/fancy/glyph/yen?Times-Roman,300
  http://nora.nr.no/fancy/glyph/beta?Symbol
  http://nora.nr.no/fancy/glyph/beta?Symbol,300
  http://nora.nr.no/fancy/glyph/beta?Symbol,300,60

Please return enhancements that you make to this code back to me. Enjoy!



---------------------------------------------------------------------------
#!/local/bin/perl

# $Id: fancy.pl,v 1.1 1993/10/25 14:37:51 aas Exp $

# URI: /fancy/clock.gif[?<size>]
# URI: /fancy/glyph/<char>[?<font>][,<size>][,<background>]

# This package shows how one might use ghostscript to render GIF
# images on the fly.  The package is currently able to return an
# analog clock showing the local time and to return an one character
# glyph from any postscript font.
#
# Author: Gisle Aas, Norsk Regnesentral, Oslo


package fancy;

$afmdir = "/usr/openwin/lib/fonts/afm";
$space  = 3; # space around the graphics

sub do
{
   local($rest, $query) = @_;

   if ($rest eq "clock.gif") {
       if ($query =~ /^\d+/) { $dim = int($query) } else { $dim = 100; }
       &clock($dim);
   } elsif ($rest =~ s,^glyph/,,) {
       &glyph($rest,$query);
   } else {
       &main'error('bad_request', "Don't know about $rest");
   }
}


sub glyph
{
   local($char, $param) = @_;
   local($font,$size,$bg) = split(",", $param);
   $font = "Times-Roman" unless length $font;
   $size = 100 if $size <= 0;
   if (defined $bg) { $bg /= 100 } else { $bg = 1 }
   $bg = 1 if $bg < 0 || $bg > 1;

   open(AFM, "$afmdir/$font.afm") ||
       &main'error('internal_error', "No font metrics file for font $font");
   while (<AFM>) {
      next unless /^C\s/;
      last if /\bN\s+$char\b/o;
   }
   close(AFM);
   unless (length $_) {
      &main'error('internal_error', "No char called $char in font $font");
   }
   ($code) = /^C\s+(-?\d+)/;
   ($llx,$lly,$urx,$ury) = /\bB\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)\s+(-?\d+)/;
   if ($code <= 0) {
      &main'error('internal_error', "Char $char is not encoded");
   }
   $char = sprintf("\\%03o", $code);
   grep ($_ *= $size/1000, $llx,$lly,$urx,$ury);
   $wx = int(($urx - $llx) + 2*$space);
   $wy = int(($ury - $lly) + 2*$space);

   open(GS,"|/local/gnu/bin/gs -sDEVICE=gif8 -sOutputFile=- -q -g${wx}x${wy} -") ||
        &main'error('internal_error', "Can't run ghostscript");
   &main'MIME_header('ok', 'image/gif');
   print GS <<"EOF" if $bg != 1;
%!
gsave $bg setgray clippath fill grestore
EOF
   print GS <<"EOF";
%!
$llx neg $lly neg translate
$space $space moveto
/$font findfont $size scalefont setfont
($char)show
showpage
EOF
   close GS;
}


sub clock
{
   local($dim) = shift;
   open(GS,"|/local/gnu/bin/gs -sDEVICE=gif8 -sOutputFile=- -q -g${dim}x${dim} -") ||
        &main'error('internal_error', "Can't run ghostscript");
   &main'MIME_header('ok', 'image/gif');
   select GS;
   if ($dim != 100) {
      local($scale) = $dim/100;
      print "%!\n\n $scale dup scale\n";
   }
   &pstime;
   close(GS);
}


# This procedure reads the local time and outputs a postscript program which
# shows an analog clock.  The dimentions on the picture is 100 x 100 points.

sub pstime
{
   ($sec,$min,$hour) = localtime;
   $clock = sprintf("%d:%02d", $hour, $min);
   $minG  = $min*6;
   $hourG = ($min/60 + $hour)*30;
   print <<"EOF";
%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: 0 0 100 100

50 50 translate
0.5 dup scale

0.85 setgray clippath fill

0.7 setgray
0 0 97 0 360 arc stroke
3 setlinewidth

%/Times-Roman findfont 8 scalefont setfont
gsave
60 rotate
1 1 12 {%for
 pop % 90 4 moveto (  ) cvs show
 90 0 moveto 100 0 lineto stroke
 -30 rotate
} for
grestore

%0 setgray
%/Times-Roman findfont 20 scalefont setfont
%0 -30 moveto ($clock)dup stringwidth pop 2 div neg 0 rmoveto show

9 setlinewidth
0.6 setgray
0 0 moveto
$hourG sin 60 mul
$hourG cos 60 mul
lineto stroke
0 0 9 0 360 arc fill

6 setlinewidth
0.4 setgray
0 0 moveto
$minG sin 90 mul
$minG cos 90 mul
lineto stroke
0 0 6 0 360 arc fill

showpage
EOF
}

1;
--
� Gisle Aas - Norsk Regnesentral                     <[email protected]>