home *** CD-ROM | disk | FTP | other *** search
/ CD Actual Thematic 7: Programming / CDAT7.iso / Share / Editores / Perl5 / perl / lib / site / Tk / Ghostscript.pm < prev    next >
Encoding:
Perl POD Document  |  1997-08-10  |  4.9 KB  |  227 lines

  1. =head1 NAME
  2.  
  3. Ghostscript - Beginings of a lowlevel PostScript viewing widget
  4.  
  5. =head1 SYNOPSIS
  6.  
  7.     my $gs= $parent->Ghostscript(
  8.                     'x_pixels_per_inch' => $scale,
  9.                     'y_pixels_per_inch' => $scale,
  10.                     'BoundingBox' => [ 0,0, $width, $height]
  11.                     );
  12.     $gs->Postscript("....");
  13.  
  14.  
  15. =head1 DESCRIPTION
  16.  
  17. Tested with gs3 via F<pgs> and F<Ghostview.pm>.
  18.  
  19. Aim is to have both GS and "Display Postscript" widgets
  20. which present same interface to higher level document viewers.
  21.  
  22. =cut
  23. package Tk::Ghostscript;
  24. use AutoLoader;
  25.  
  26. use strict qw(subs);
  27. use POSIX qw(F_GETFL F_SETFL O_NONBLOCK fcntl);
  28.  
  29. # use Tk::Xlib;
  30.  
  31. use Carp;
  32. use Tk::Pretty;
  33.  
  34. @ISA = qw(Tk::Frame);
  35. Construct Tk::Widget 'Ghostscript';
  36.  
  37. sub Portrait   {  0}   # Normal portrait orientation 
  38. sub Landscape  { 90}   # Normal landscape orientation 
  39. sub Upsidedown {180}   # Don't think this will be used much 
  40. sub Seascape   {270}   # Landscape rotated the wrong way 
  41.  
  42. sub Populate
  43. {
  44.  my ($w,$args) = @_;
  45.  my %hash = ( 
  46.               'bpixmap'           => 0,
  47.               'page_orientation'  => &Portrait(),
  48.               'BoundingBox'       => [0,0,int(210*72/25.4),int(297*72/25.4)], 
  49.               'x_pixels_per_inch' => 72.0,
  50.               'y_pixels_per_inch' => 72.0,
  51.               'Margins'           => [0,0,0,0]
  52.             );
  53.  %hash = (%hash,@_);
  54.  while (($key,$value) = each %hash)
  55.   {
  56.    $w->{$key} = $value;
  57.   }
  58.  
  59.  $w->{'FH'} = \*{"GS" . $w->PathName};
  60.  
  61.  $w->BindClientMessage('DONE','StopInterp');
  62.  $w->BindClientMessage('PAGE','PAGE');
  63.  $w->ConfigSpecs('-orientation' => ['METHOD','orientation','Orientation','Portrait']
  64.                 );
  65.  
  66.  
  67. 1;
  68.  
  69. __END__
  70.  
  71. sub StartInterp
  72. {
  73.  my $w = shift;
  74.  $w->StopInterp;
  75.  $w->idletasks;
  76.  $w->MakeWindowExist;
  77.  my $win  = ${$w->WindowId};  # Window for properties/events
  78.  my $dest = ${$w->WindowId};  # Xid of drawable to draw on (gs3 and later)
  79.  $ENV{'GHOSTVIEW'} = sprintf("%d %d",$win,$dest);
  80.  $w->property('set','GHOSTVIEW','STRING',8,
  81.               sprintf("%d %d %d %d %d %d %g %g %d %d %d %d",
  82.                $w->{'bpixmap'},
  83.                $w->{'page_orientation'},
  84.                @{$w->{'BoundingBox'}},
  85.                $w->{'x_pixels_per_inch'}, $w->{'y_pixels_per_inch'},
  86.                @{$w->{'Margins'}}));
  87.  my $screen = $w->Screen;
  88. # my $bg = $screen->WhitePixelOfScreen;
  89. # my $fg = $screen->BlackPixelOfScreen;
  90. # $w->property('set','GHOSTVIEW_COLORS','STRING',8,sprintf("Monochrome %d %d",$fg,$bg));
  91.  $w->{'Pending'} = [];
  92.  $w->XSync(0);
  93.  my $fh = $w->{'FH'};
  94.  $w->{'pid'} = open($fh,"| gs -sDEVICE=x11 -dQUIET -dNOPAUSE -");
  95.  my $fl = fcntl($fh,F_GETFL,0);
  96.  die "Cannot F_GETFL:$!" unless (defined $fl);
  97.  fcntl($fh,F_SETFL,$fl | O_NONBLOCK) || die "Cannot F_SETFL:$!";
  98. }
  99.  
  100. sub PAGE
  101. {
  102.  my $w = shift;
  103.  my $e = $w->XEvent;
  104.  my ($m,$d) = unpack('LL',$e->A);
  105.  $w->{'mwin'} = $m;
  106. }
  107.  
  108. sub Postscript
  109. {
  110.  my $w  = shift;
  111.  $w->StartInterp unless(exists $w->{'pid'});
  112.  if (exists $w->{'mwin'})
  113.   {
  114.    $w->SendClientMessage('NEXT',$w->{'mwin'},8,"");
  115.    delete $w->{'mwin'};
  116.   }
  117.  my $fh = $w->{'FH'};
  118.  my $pend = $w->{'Pending'};
  119.  unless (@$pend)
  120.   {
  121.    $w->fileevent($fh,'writable',['SendIt',$w]);
  122.   }
  123.  push(@$pend,@_);
  124. }
  125.  
  126. sub printf
  127. {my $w = shift;
  128.  my $fmt = shift;
  129.  $w->Postscript(sprintf($fmt,@_));
  130. }
  131.  
  132. sub SendIt
  133. {
  134.  my $w  = shift;
  135.  my $fh = $w->{'FH'};
  136.  my $pend = $w->{'Pending'};
  137.  while (@$pend)
  138.   {
  139.    my $line = shift(@$pend);           
  140.    my $len  = length($line);           
  141.    my $done = syswrite($fh,$line,$len);
  142.    $done = 0 unless (defined $done);
  143.    if ($done < $len)
  144.     {
  145.      unshift(@{$pend},substr($line,$done));
  146.      last;
  147.     }
  148.   }
  149.  if (exists $w->{'mwin'})
  150.   {
  151.    $w->SendClientMessage('NEXT',$w->{'mwin'},8,"");
  152.    delete $w->{'mwin'};
  153.   }
  154.  $w->fileevent($fh,'writable',"") unless (@$pend);
  155. }
  156.  
  157. sub StopInterp
  158. {
  159.  my $w = shift;
  160.  if (exists $w->{'pid'})
  161.   {
  162.    my $fh = $w->{'FH'};
  163.    kill('TERM',$w->{'pid'});
  164.    delete $w->{'pid'};
  165.    $w->fileevent($fh,'writable',"");
  166.    close($fh);
  167.    delete $w->{'Pending'};
  168.   }
  169.  delete $w->{'mwin'};
  170. }
  171.  
  172. sub NoteSize
  173. {
  174. }
  175.  
  176. sub ChangeView
  177. {
  178.  my $w = shift;
  179.  my ($llx,$lly,$urx,$ury) = @{$w->{'BoundingBox'}};
  180.  my $x = int(($urx - $llx)*$w->{'x_pixels_per_inch'}/72.0);
  181.  my $y = int(($ury - $lly)*$w->{'y_pixels_per_inch'}/72.0);
  182.  $w->StopInterp;
  183.  if ($w->{'page_orientation'} % 180 == 0)
  184.   {
  185.    $w->configure('-width' => $x,'-height' => $y);
  186.   }
  187.  else
  188.   {
  189.    $w->configure('-width' => $y,'-height' => $x);
  190.   }
  191. }
  192.  
  193. sub BoundingBox
  194. {
  195.  my $w = shift;
  196.  return @{$w->{'BoundingBox'}} unless (@_);
  197.  croak "Invalid bounding box" . Pretty(\@_) unless (@_ == 4); 
  198.  my @bb = @_;
  199.  $w->{'BoundingBox'} = \@bb;
  200.  $w->ChangeView;
  201. }
  202.  
  203. sub orientation
  204. {
  205.  my $w = shift;
  206.  if (@_)
  207.   {
  208.    my $view = shift;
  209.    $w->{'page_orientation'} = $w->$view();
  210.    $w->ChangeView;
  211.   }
  212.  my @names = ('Portrait','Landscape','Upsidedown','Seascape');
  213.  return $names[$w->{'page_orientation'}/90];
  214. }
  215.  
  216. sub ClassInit
  217. {
  218.  my ($class,$mw) = @_;
  219.  $mw->bind($class,'<Configure>','NoteSize');
  220.  $mw->bind($class,'<Destroy>','StopInterp');
  221.  return $class;
  222. }
  223.  
  224. 1;
  225.  
  226.