11.7. How do I get a Canvas to output PostScript(c)?
Many thanks to Tom Oelke <tpo9617@rit.edu> for providing this questio
+n,
answer & snippet of code:
The following section of code gets the postscript code for the secti
+on of
canvas that's top-left corner is at $min_x, $min_y, and has a width
+and
height equivalent to the displayed region. This ps code is then pipe
+d out
to lpr to be printed.
my $ps = $canvas->postscript( '-x' => $min_x,
'-y' => $min_y,
-width => $canv->Width,
-height => $canv->Height);
open (PS, "| lpr"); # customize with -Pname e.g.
print PS $ps;
close (PS);
Whereas you would use something like:
open (PS, ">file.ps"); # to output to a file
print PS $ps;
close (PS);
Update: A better explanation: the first bit of code sends the canvas data in postscript form to a (unix) printer lpr. The second bit of code creates a postscript file that you can send to the printer directly via
% lpr file.ps
or you can open it with ghostscript to print it on a non-postscript printer.
| [reply] [d/l] [select] |
but! that doesnt do anything does it ? just prints it to the screen, or to a file. It doesnt print it (hard copy) whatsoever!
Maybe i have misunderstood?
| [reply] |
You can look at the widget demo under "Canvas", and select "Simple 2D Plot", it has a button to print to printer. Copy the code. It goes something like this:
sub area_save {
my($w, $pinfo) = @_;
my($x1, $x2, $y1, $y2, $a);
if($pinfo->{'areaX2'} != -1) {
($x1, $x2, $y1, $y2) =
@$pinfo{'areaX1', 'areaX2', 'areaY1', 'areaY2'}; # slice !
($x1, $x2) = @$pinfo{'areaX2', 'areaX1'} if $x2 <= $x1;
($y1, $y2) = @$pinfo{'areaY2', 'areaY1'} if $y2 <= $y1;
$a = $w->postscript('-x' => $x1, '-y' => $y1,
-width => $x2 - $x1, -height => $y2 - $y1);
} else {
$a = $w->postscript;
}
$SIG{'PIPE'} = sub {};
open(LPR, "| $pinfo->{'prcmd'}");
print LPR $a;
close(LPR);
} # end area_save
I'm not really a human, but I play one on earth.
flash japh
| [reply] [d/l] |
i hate to keep asking questions, but :P
1) what are the 2 arguments passed to it ?
my($w, $pinfo) = @_;
i.e. which is the canvas, and what is the other thing ?
2) This appears to use PIPE's ? im using windowsXP, I though pelr couyldnt use pipes outside of linux. Or is that just for the Printer module ?
Thanks again :)
| [reply] |
You probably mean that you found hints for outputting Postscript, not PDF.
If you're on Windows, you could check out Tk::WinPrint. Though I'm in the search for a maintainer for this module :-)
| [reply] |
Well that information is earlier in the script, where the sub is called. If you look at the widget demo, for plot, you should be able to see where it's called. However, I have to agree that the demos are written by people who are good, and take alot of "code shortcuts" which are hard for beginners to see. So rather than try to explain to you, what you can find yourself, I will give a "more straight-forward" example. Like in kvale's first reply, you need to specify
the "boundaries" of what you want to capture as postscript. That is what the $pinfo is for. So look at this simple example.
#!/usr/bin/perl
use Tk;
#to change the background color, edit the ps file
# 0.000 0.000 0.000 setrgbcolor AdjustColor
# fill
$width = 800;
$height = 500;
my $main = MainWindow->new();
my $canvas = $main->Canvas( -width=>$width, -height=>$height, -backgro
+und=>"black");
$canvas->pack( -expand=>1,-fill=>'both');
&create;
$canvas->update;
$main->update;
$main->Button(
-text => "Save",
-command => [sub {
$canvas->update;
my @capture=();
my ($x0,$y0,$x1,$y1)=$canvas->bbox('all');
@capture=('-x'=>$x0,'-y'=>$y0,-height=>$y1-$y0,-width=>$x1-$x
+0);
$canvas -> postscript(-colormode=>'color',
-file=>$0.'.ps',
-rotate=>0,
-width=>800,
-height=>500,
@capture);
}
] )->pack;
MainLoop;
sub create{
$canvas->createOval(100, 100, 600, 600,-fill=>'green')
}
I'm not really a human, but I play one on earth.
flash japh
| [reply] [d/l] |
wow, thanks for that :) i didnt know about that widget demo thing, its very useful :)
It all appears to work now, my canvas prints to postscript form, almost perfectly! the biggest thing which would go on it, is luckily in perfect proportions for an A4 sheet! The only problem i am still having is with the lpr command...
lpr -S localhost or 127.0.0.1 -P LPT1 FILENAME
which its having problems with (Error: print server unreachable or specified printer does not exist.). Howevetr im sure its only a matter of time before i work this out! And the fact it is getting this far anyway means that it is likely to work once it finds te correct place! :)
Thanks alot!
| [reply] |
lpr -S localhost or 127.0.0.1 -P LPT1 FILENAME
Is that under WinXP (which you mention running), you need to enable lpr support under "services". Please note that lpr support is only available under XP-Pro, NOT under XP-Home.
And even then it's kludgy and hard to administer. It's easier to just dump into a file and spawn (Win32::CreateProcess()) something to do the dirty work of sending it to the printer, like maybe, ghostscript.
| [reply] [d/l] [select] |