In article <9908271957.06ol@lassie.demon.co.uk>,
David Jordan <dave@lassie.demon.co.uk> wrote:
>It's not that difficult, it took me about an hour to come up with
a simple
>viewer written in perl. It uses the GD module so you need to invoke
it as:
>
> ngview < file | xv -
>
>There's a module somewhere that interfaces perl with GTK, maybe
I'll try
>that so you don't need to intermediate step of using xv.
>
>The program is less than 100 lines and handles the basics of the
format, it
>ignores invalid lines and can cope with split polylines. As it's
so short I
>could post it here if anybody wants it, it will be useable on
a great
>number of machines as all you need is perl and the GD library.
You beat me by a day and about 50 lines. I'm using classic
(I think
it's Version 4) Perl, and producing postscript for Ghostscript
to do
the graphics.
>What I would like to see is a complete description of the format
(what does
>the initial '1' mean in the polyline, what does the 'M' mean for
text...).
The linewidth, 1 (to 10) , and Medium size font. A lot of
it's at
the end of Franz's web page but there remain some picky details.
Stuff
like what the character size (in pixels) is for each font and where
the
location of a character string is relative to the starting coordinates,
and what the dot and dash pattersns are need to be resolved.
(And what
the linewidth of 0 in his version 6.0 example means).
CAUTION:
NEWER VERSION BELOW!
=-----------------------------------------------------------
#!/usr/bin/perl
#
#
File: ng2ps.pl
#
Author: Mark Zenier
#
Description: A filter to convert Ing. Franz Glaser's
NGpaint simple
#
graphics format for newsgroup postings to level 1
#
Postscript.
#
Usage: Perl => Unix
and where else it works
#
#
ng2ps.pl [width] <input >output
#
#
width (optional) is in Postscript points (72 per inch),
#
default is 320 about a half pagewidth
#
#
History: August 28, 1999
Version 1.2
#
#
Bugs: Dot and
Dash sequences are not matched to NGpaint.
#
Offsets for text from postion are not set.
#
font sizes are a random guess.
#
Proposed extensions (arc and relative distances) are
#
not implemented.
#
Just about Zero validity checking is done.
#
shape fill is untested, any color that you like as
#
long as it's black.
#
wrapped lines are not supported.
#
#
Features: Junk at the start of a line
is ignored
#
$scale = ($#ARGV >= 0) ? $ARGV[0]/320 : 1;
shift;
%widthstring = (
1 => " 1 setlinewidth [] 0 setdash\n",
2 => " 2 setlinewidth [] 0 setdash\n",
3 => " 3 setlinewidth [] 0 setdash\n",
4 => " 4 setlinewidth [] 0 setdash\n",
5 => " 5 setlinewidth [] 0 setdash\n",
6 => " 6 setlinewidth [] 0 setdash\n",
7 => " 7 setlinewidth [] 0 setdash\n",
8 => " 8 setlinewidth [] 0 setdash\n",
9 => " 9 setlinewidth [] 0 setdash\n",
10 => " 10 setlinewidth [] 0 setdash\n",
DS => " 1 setlinewidth [3 2] 0 setdash\n",
DT => " 1 setlinewidth [2 2] 0 setdash\n",
DD => " 1 setlinewidth [3 2 1 2] 0 setdash\n"
);
%fontoffset = (
S => " 0 0 rmoveto ",
M => " 0 0 rmoveto ",
B => " 0 0 rmoveto "
);
$shapefill = "fill ";
print <<'HDR-HEREDOC-DELIM';
%!PS-Adobe-1.0
%%Pages: (atend)
%%DocumentFonts: Courier
%%EndComments
/NGPSfont /Courier findfont
[6 0 0 -6 0 0] makefont def
/NGPMfont /Courier findfont
[8 0 0 -8 0 0] makefont def
/NGPLfont /Courier findfont
[16 0 0 -16 0 0] makefont def
HDR-HEREDOC-DELIM
# Move coordinate system up by the height, and flop the x-axis, and magnify
print "0 ", 200*$scale, " translate\n",
$scale, " -", $scale, " scale\n";
print <<'HDR-HEREDOC-DELIM';
NGPMfont setfont
%%EndProlog
HDR-HEREDOC-DELIM
$currentwidth = "?";
$currentfont = "M";
while(<>)
{
if(/L\([^)]*\)/)
{
print "% ", $_ ;
s/^.*L\(//;
($newwidth, $x1, $y1, $endpairs) = split /;/, $_, 4;
if($newwidth != $currentwidth) { print $widthstring{$newwidth} }
$currentwidth = $newwidth;
print $x1, " ", $y1, " moveto ";
@pairs = split /[;\)]/, $endpairs ;
for( $index = 0; $index < $#pairs; $index += 2)
{
print $pairs[$index], " ", $pairs[$index+1], " lineto ";
}
print "stroke\n";
}
elsif( /R\([^\)]*\)/ )
{
print "% ", $_ ;
s/^.*R\(//;
($newwidth, $fill, $x1, $y1, $x2, $y2) = split /[;\)]/;
if($newwidth != $currentwidth) { print $widthstring{$newwidth};
}
$currentwidth = $newwidth;
print $x1, " ", $y1, " moveto ";
print $x1, " ", $y2, " lineto ";
print $x2, " ", $y2, " lineto ";
print $x2, " ", $y1, " lineto ";
print "closepath ";
if($fill =~ /F/)
{
print "gsave ", $shapefill, " grestore ";
}
print "stroke\n";
}
elsif(/E\([^\)]*\)/)
{
print "% ", $_ ;
s/^.*E\(//;
($newwidth, $fill, $x1, $y1, $x2, $y2) = split /[;\)]/;
if($newwidth != $currentwidth) { print $widthstring{$newwidth};
}
$currentwidth = $newwidth;
#
create a new coordinate system where the origin is in the center
#
of the ellipse and the x and y dimensions are scaled so that a
#
unit circle is drawn as an ellipse
print "gsave ";
$xo = ($x1+$x2)/2;
$yo = ($y1+$y2)/2;
print $xo, " ", $yo, " translate ";
$xs = abs($x1-$x2)/2;
$ys = abs($y1-$y2)/2;
print $xs, " ", $ys, " scale ";
print "0 0 1 0 360 arc closepath\n";
#
unscale so the line isn't real fat
print 1/$xs, " ", 1/$ys, " scale\n";
if($fill =~ /F/)
{
print "gsave ", $shapefill, "grestore ";
}
print "stroke grestore\n";
#
toss the new coordinate system so the rest of the drawing is ok
}
elsif(/T\([^\)]*\)/)
{
print "% ", $_ ;
s/^.*T\(//;
($font, $x1, $y1, $text) = split /[;\)]/ ;
if($font != $currentfont) { print "NGP", $font, "font
setfont\n";}
$currentfont = $font;
print $x1, " ", $y1, " moveto ", $fontoffset{$font};
$text =~ s/^[^"]*"/(/;
$text =~ s/"[^"]*$/)/;
print $text, " show\n";
}
}
print <<'TRAILER-DELIM';
showpage
%%Trailer
%%Pages: 1
TRAILER-DELIM
=-----------------------------------------------------------
Mark Zenier mzenier@eskimo.com mzenier@netcom.com Washington State resident
In article <935958098.2619.0.pluto.d4ee0662@news.demon.nl>,
Jan Panteltje <jan@panteltje.demon.nl> wrote:
>I have got the perl script working, but ghostview complains about
fonts it does
not know,
>any suggestions?
Do a "gs --help" to tell you where the font directory "Fontmap"
file is
by following the search path.
In the Fontmap file there are mapping between the either fonts and
file
names, or fonts and aliases for the provided fonts. Looks
like this:
/NimbusMonL-Regu (n022003l.pfb)
;
/Courier
/NimbusMonL-Regu ;
You should be able to either add a alias to an existing font in
the
Fontmap file, or change the reference to Courier in the Perl script.
(There is a compile option that causes Ghostscript to either bomb
off
when it doesn't find a font, or to just substitute a default font.
That could be changed, too. Easiest to change the script
to use a fixed
width(?) font that you have).
Ghostview may use an alternate Fontmap file. It's a command
line
option for Ghostscript, so it can be changed. (It may switch
to
a set of X-Windows fonts, I've never used it).
Here's how I've been invoking it (as a script) by |ing from trn:
~mark/NGpaint/ng2ps.pl 640 | gs -q -g640x400 -sDEVICE=pngmono \
-dNOPAUSE -sOutputFile=${1-ngp}.png -
And then I use zvg under svgalib to look at the resulting graphic
on
an alternate console. (My news machine is a 8 Mb 386, and
X-Windows is
just too painful on that small a machine).
Here's the latest version. It handles the elliptical arcs,
and supports
some of the proposed stuff, but in a way that Franz has since changed.
I think he plans to use the : instead of the # for line segments
with
relative positions. And I don't know if he plans to use those
in the
Rectangle or other shapes in addition to Line specs. And
since I've
never run his program, I still don't know if the font sizes and
offsets
are close enough.
=-------------------------------------------------------
#!/usr/bin/perl
#
# File:
ng2ps.pl
# Author:
Mark Zenier
# Description:
A filter to convert Ing. Franz Glaser's NGpaint simple
#
graphics format for newsgroup postings to level 1
#
Postscript.
# Usage:
Perl => Unix and whereever else it works
#
#
ng2ps.pl [width] <input >output
#
#
width (optional) is in Postscript points (72 per inch),
#
default is 320 about a half pagewidth
#
# History:
August 29, 1999 Version 1.3
#
# Bugs:
Dot and Dash sequences are not matched to NGpaint.
#
Offsets for text from postion are not set.
#
font sizes are a random guess.
#
shape fill is untested, any color that you like as
#
long as it's black.
#
wrapped lines are not supported.
#
expects fixed 320x200 field for input
$scale = ($#ARGV >= 0)
? $ARGV[0]/320 : 1;
shift;
%widthstring = (
1 => " 1 setlinewidth [] 0 setdash\n",
2 => " 2 setlinewidth [] 0 setdash\n",
3 => " 3 setlinewidth [] 0 setdash\n",
4 => " 4 setlinewidth [] 0 setdash\n",
5 => " 5 setlinewidth [] 0 setdash\n",
6 => " 6 setlinewidth [] 0 setdash\n",
7 => " 7 setlinewidth [] 0 setdash\n",
8 => " 8 setlinewidth [] 0 setdash\n",
9 => " 9 setlinewidth [] 0 setdash\n",
10 => " 10 setlinewidth [] 0 setdash\n",
DS => " 1 setlinewidth [3 2] 0 setdash\n",
DT => " 1 setlinewidth [2 2] 0 setdash\n",
DD => " 1 setlinewidth [3 2 1 2] 0 setdash\n"
);
%fontoffset = (
S => " 0 0 rmoveto ",
M => " 0 0 rmoveto ",
B => " 0 0 rmoveto "
);
$shapefill = "fill ";
print <<'HDR-HEREDOC-DELIM';
%!PS-Adobe-1.0
%%Pages: (atend)
%%DocumentFonts: Courier
%%EndComments
/NGPSfont /Courier findfont [6 0 0 -6 0 0] makefont def
/NGPMfont /Courier findfont [8 0 0 -8 0 0] makefont def
/NGPLfont /Courier findfont [16 0 0 -16 0 0] makefont def
HDR-HEREDOC-DELIM
# Move coordinate system up by the height, and flop the x-axis, and magnify
print "0 ", 200*$scale,
" translate\n",
$scale, " -", $scale, " scale\n";
print <<'HDR-HEREDOC-DELIM';
NGPMfont setfont
%%EndProlog
HDR-HEREDOC-DELIM
$currentwidth = "?";
$currentfont = "M";
while(<>)
{
if(/^T\([^\)]*\)/)
{
print "% ", $_ ;
s/^T\(//;
($font, $x1, $y1, $text) = split /[;]/, $_, 4 ;
if($font != $currentfont && $font =~ /[SMB]/)
{
print "NGP", $font, "font setfont\n";
$currentfont = $font;
}
print $x1, " ", $y1, " moveto ", $fontoffset{$font};
$text =~ s/([()])/\\\1/g;
$text =~ s/^[^"]*"/(/;
$text =~ s/"[^"]*$/)/;
print $text, " show\n";
}
elsif(/^L\([^)]*\)/)
{
print "% ", $_ ;
s/^L\(//;
($newwidth, $x1, $y1, $endpairs) = split /[;#]/, $_, 4;
if($newwidth != $currentwidth) { print $widthstring{$newwidth} }
$currentwidth = $newwidth;
print $x1, " ", $y1, " moveto ";
# parse both delimiters and number strings for "polylines"
@pairs = split /([;#\)])/, $endpairs ;
for( $index = 0; $index < $#pairs; $index += 4)
{
print $pairs[$index], " ", $pairs[$index+2],
#only check middle delimiter, if # both coords are relative, no
mixing
($pairs[$index+1] =~ /#/) ? " rlineto ":" lineto " ;
}
print "stroke\n";
}
elsif( /^R\([^\)]*\)/
)
{
print "% ", $_ ;
s/^R\(//;
($newwidth, $fill, $x1, $y1, $x2, $y2) = split /[;\)]/;
if($newwidth != $currentwidth) { print $widthstring{$newwidth};
}
$currentwidth = $newwidth;
print $x1, " ", $y1, " moveto ";
print $x1, " ", $y2, " lineto ";
print $x2, " ", $y2, " lineto ";
print $x2, " ", $y1, " lineto ";
print "closepath ";
if($fill =~ /F/)
{
print "gsave ", $shapefill, " grestore ";
}
print "stroke\n";
}
elsif(/^E\([^\)]*\)/)
{
print "% ", $_ ;
s/^E\(//;
($newwidth, $fill, $x1, $y1, $x2, $y2) = split /[;\)]/;
if($x1 != $x2 && $y1 != $y2)
#skip 0 width/height shapes
{
if($newwidth != $currentwidth) { print $widthstring{$newwidth}; }
$currentwidth = $newwidth;
#
create a new coordinate system where the origin is in the center
#
of the ellipse and the x and y dimensions are scaled so that a
#
unit circle is drawn as an ellipse
print "gsave ";
$xo = ($x1+$x2)/2;
$yo = ($y1+$y2)/2;
print $xo, " ", $yo, " translate ";
$xs = abs($x1-$x2)/2;
$ys = abs($y1-$y2)/2;
print $xs, " ", $ys, " scale ";
print "0 0 1 0 360 arc closepath\n";
#
unscale so the line isn't real fat
print 1/$xs, " ", 1/$ys, " scale\n";
if($fill =~ /F/)
{
print "gsave ", $shapefill, "grestore ";
}
print "stroke grestore\n";
#
toss the new coordinate system so the rest of the drawing is ok
}
}
elsif(/^A\([^\)]*\)/)
{
print "% ", $_ ;
s/^A\(//;
($newwidth, $fill, $xc, $yc, $x2, $y2, $rest) = split /[;\)]/,$_, 7;
if($x2 < $xc && $y2 < $yc) { $arcstart = 90; $arcend = 180;
}
if($x2 >= $xc && $y2 < $yc) { $arcstart = 0; $arcend = 90; }
if($x2 < $xc && $y2 >= $yc) { $arcstart = 180; $arcend = 270;
}
if($x2 >= $xc && $y2 >= $yc) { $arcstart = 270; $arcend = 360;
}
if($rest =~ /[;0-9]/)
{
($arcstart, $arcend) = split /[;\)]/, $rest;
}
if($newwidth != $currentwidth) { print $widthstring{$newwidth};
}
$currentwidth = $newwidth;
# create a new coordinate system
where the origin is in the center
# of the ellipse and the x
and y dimensions are scaled so that a
# unit circle is drawn as an
ellipse
print "gsave ";
print $xc, " ", $yc, " translate ";
$xs = abs($xc-$x2);
$ys = abs($yc-$y2);
#flip y axis so that 0 degrees means to the right, increasing counterclockwise
print $xs, " -", $ys, " scale ";
print "0 0 1 ", $arcstart, " ", $arcend, " arc\n";
# unscale so the line isn't
real fat
print 1/$xs, " ", 1/$ys, " scale\n";
print "stroke grestore\n";
# toss the new coordinate system
so the rest of the drawing is ok
}
}
print <<'TRAILER-DELIM';
showpage
%%Trailer
%%Pages: 1
TRAILER-DELIM
=-------------------------------------------------------
Mark Zenier mzenier@eskimo.com mzenier@netcom.com
Washington State resident