1package Starlink::AST::PLplot;
2
3use strict;
4use vars qw/ $VERSION /;
5use constant R2D     => 57.29578;        # Radians to degrees factor
6use constant FLT_MAX => 3.40282347e+38;  # Maximum float on ix86 platform
7
8# Need plstrl
9use Graphics::PLplot 0.03 qw/:all/;
10use Starlink::AST;
11use Carp;
12
13$VERSION = '2.00';
14
15=head1 NAME
16
17Starlink::AST::PLplot - AST wrapper to the PLplot library
18
19=head1 SYNOPSIS
20
21   use Starlink::AST::PLplot
22
23The main methods which need to be registered with the AST package
24are shown below,
25
26   $status = _GFlush();
27   $status = _GLine( \@x, \@y );
28   $status = _GMark( \@x, \@y, $type );
29   $status = _GText( $text, $x, $y, $just, $upx, $upy );
30   ( $status, $xb, $yb ) = _GTxExt( $text, $x, $y, $just, $upx, $upy );
31   ( $status, $chv, $chh ) = _GQch();
32   ( $status, $old_value ) = _GAttr( $attr, $value, $prim );
33   ( $status, $alpha, $beta) = _GScales();
34
35=head1 DESCRIPTION
36
37This file implements the low level graphics functions required by the rest
38of AST, by calling suitable PLplot functions.
39
40=head1 NOTES
41
42All the functions in this module are private, and are intended to be called
43from the AST module. None of these functions should be considered to be part
44of the packages public interface.
45
46=head1 REVISION
47
48$Id$
49
50=head1 METHODS
51
52=over 4
53
54=item B<_GFlush>
55
56This function ensures that the display device is up-to-date, by flushing
57any pending graphics to the output device.
58
59   my $status = _GFlush();
60
61=cut
62
63sub _GFlush {
64  plflush();
65  return 1;
66}
67
68=item B<_GLine>
69
70This function displays lines joining the given positions.
71
72   my $status = _GLine( \@x, \@y );
73
74=cut
75
76sub _GLine {
77  my $x = shift;
78  my $y = shift;
79
80  if( scalar(@$x) > 1 && scalar(@$x) == scalar(@$y) ) {
81    plcol0(1);
82    plline( $x, $y );
83  }
84  _GFlush();
85  return 1;
86}
87
88=item B<_GMark>
89
90This function displays markers at the given positions.
91
92   my $status = _GMark( \@x, \@y, $type );
93
94where $type is an integer used to indicate the type of marker required.
95
96=cut
97
98sub _GMark {
99   my $x = shift;
100   my $y = shift;
101   my $type = shift;
102
103   # Check for supported plot symbols: PLplot does not support ftriangle or fdiamond
104   # Also we will arbitrarily not support anything above 18 for now
105   if ($type < 0 || $type == 13 || $type > 18) {
106     $type = 2;
107   }
108
109   if( scalar(@$x) >= 1 && scalar(@$x) == scalar(@$y) ) {
110      plcol0(2);
111      plpoin( $x, $y, $type );
112   }
113   _GFlush();
114   return 1;
115}
116
117=item B<_GText>
118
119This function displays a character string $text at a given position using
120a specified justification and up-vector.
121
122   my $status = _GText( $text, $x, $y, $just, $upx, $upy );
123
124where $x is the reference x coordinate, $y is the reference y coordinate,
125and where $just is a character string which specifies the location within
126the text string which is to be placed at the reference position given by x
127and y. The first character may be 'T' for "top", 'C' for "centre", or 'B'
128for "bottom", and specifies the vertical location of the reference position.
129Note, "bottom" corresponds to the base-line of normal text. Some characters
130(eg "y", "g", "p", etc) descend below the base-line. The second  character
131may be 'L' for "left", 'C' for "centre", or 'R'  for "right", and specifies
132the horizontal location of the  reference position. If the string has less
133than 2 characters then 'C' is used for the missing characters.
134
135And $upx is the x component of the up-vector for the text, in graphics
136world coordinates. If necessary the supplied value should be negated to
137ensure that positive values always refer to displacements from  left to
138right on the screen.
139
140While $upy is the y component of the up-vector for the text, in graphics
141world coordinates. If necessary the supplied value should be negated to
142ensure that positive values always refer to displacements from  bottom to
143top on the screen.
144
145=cut
146
147# PLplot only allows justification relative to the horizontal position
148# within the string going from 0 to 1.0, where 0.5 is halfway along.
149# B and T justification requires offsetting by 0.5 character height.
150
151# PLplot assumes C justification (centre of text) as opposed to PGPLOT
152# which assumes B justification by default for vertical positioning.
153
154# upx and upy for PLplot define the angle where
155# the actual angle is atan2(upy,upx) relative to horizontal (mathematical
156# definition of angle rather than astronomical).
157
158# AST seems to define the angle as atan2(-$upx, $upy )
159
160
161sub _GText {
162   my ( $text, $x, $y, $just, $upx, $upy ) = @_;
163
164   # check we have a string to print
165   if( defined $text && length($text) != 0 ) {
166
167      # validate the justifcation
168      my $just1 = substr $just, 0, 1;
169      my $just2 = substr $just, 1, 1;
170      if ( defined $just && length($just) == 2 ) {
171
172        # if we have a bogus justification string default it
173        unless( $just1 =~ /^[TBC]/ ) {
174           warn "_GText: bad vertical justification defaulting to 'C'\n";
175           $just1 = "C";
176        }
177        unless( $just2 =~ /^[LCR]/ ) {
178           warn "_GText: bad horizontal justification defaulting to 'C'\n";
179           $just2 = "C";
180        }
181      } else {
182         warn "_GText: No justification string defaulting to 'CC'\n";
183         $just1 = "C";
184         $just2 = "C";
185      }
186      $just = $just1 . $just2;
187
188      # get the axis scaling
189      my ( $ret, $alpha, $beta ) = _GScales();
190      return 0 if $ret == 0;
191
192      # If either axis is reversed, reverse the supplied up-vector
193      # components so that they refer to the world-coordinates axes.
194      $upx = -$upx if $alpha < 0.0;
195      $upy = -$upy if $beta < 0.0;
196
197      # Get the angle between the text base-line and horizontal.
198      my $angle = atan2( -$upx*$alpha, $upy*$beta);
199
200      # Get the fractional horizontal justification as needed by PGPLOT.
201      my $fjust;
202      if( $just2 eq "L" ) {
203        $fjust = 0.0;
204      } elsif ( $just2 eq "R" ) {
205        $fjust = 1.0;
206      } else {
207        $fjust = 0.5;
208      }
209
210      # Unless the requested justification is "Centre", we need to adjust
211      # the supplied reference position before we use it with PLplot because
212      # PLplot assumes "Centre" justification.
213      if( $just1 ne "C" ) {
214
215         # Get the bounding box of the string. Note, only the size of the box
216         # is significant here, not its position. Also note, leading and
217         # trailing spaces are not included in the bounding box.
218         my ( @xbox, @ybox );
219
220	 # Get the character height in mm. AAdd a fudge factor since
221	 # the height does not seem to be quite correct
222	 my ($def, $ht ) = plgchr();
223	 $ht *= 1.5;
224
225         #pgqtxt( $x, $y, $angle, $fjust, $text, \@xbox, \@ybox );
226         #plptex ( $x, $y, $upy, $upx , $fjust, $text);
227         # Normalise the up-vector in world coordinates.
228         my $uplen = sqrt( $upx*$upx + $upy*$upy );
229         if( $uplen > 0.0 ){
230            $upx /= $uplen;
231            $upy /= $uplen;
232         } else {
233            ReportGrfError("_GText: Zero length up-vector supplied.");
234            return 0;
235         }
236
237	 # Adjust the vertical position of the text since PLplot assumes C
238	 if ($just1 eq 'T' ) {
239	   $x -= 0.5 * $upx * mm2world(1, $ht);
240	   $y -= 0.5 * $upy * mm2world(2, $ht);
241	 } elsif ($just1 eq 'B') {
242	   $x += 0.5 * $upx * mm2world(1, $ht);
243	   $y += 0.5 * $upy * mm2world(2, $ht);
244	 }
245      }
246
247      # Display the text, erasing any graphics.
248      #my $tbg;
249      #pgqtbg( $tbg );
250      #pgstbg( 0 );
251      #pgptxt( $x, $y, $angle, $fjust, $text );
252      #pgstbg( $tbg );
253      plcol0(15);
254
255      # Need to convert upx and upy to PLplot dx and dy
256      my $dx = cos($angle);
257      my $dy = sin($angle);
258
259      plptex ( $x, $y, $dx, $dy, $fjust, $text);
260
261   }
262
263   # Return, all is well strangely
264   _GFlush();
265   return 1;
266}
267
268=item B<_GScales>
269
270This function returns two values (one for each axis) which scale
271increments on the corresponding axis into a "normal" coordinate system in
272which: The axes have equal scale in terms of (for instance) millimetres
273per unit distance, X values increase from left to right and the Y values
274increase from bottom to top.
275
276   my ( $status, $alpha, $beta ) = _GScales()
277
278=cut
279
280sub _GScales {
281  # Query device for world and page (mm) coordinates
282  my ( $nx1, $nx2, $ny1, $ny2) = plgspa();
283  my ( $wx1, $wx2, $wy1, $wy2 ) = plgvpw();
284
285  my ($alpha, $beta);
286  if( $wx2 != $wx1 && $wy2 != $wy1 && $nx2 != $nx1 && $ny2 != $ny1 ) {
287    $alpha = ( $nx2 - $nx1 ) / ( $wx2 - $wx1 );
288    $beta = ( $ny2 - $ny1 ) / ( $wy2 - $wy1 );
289  } else {
290    ReportGrfError("_GScales: The graphics window has zero size\n");
291    return(0);
292  }
293  return ( 1, $alpha, $beta );
294}
295
296
297=item B<_GTxExt>
298
299This function returns the corners of a box which would enclose the
300supplied character string if it were displayed using astGText. The
301returned box INCLUDES any leading or trailing spaces.
302
303   my ( $status, $xb, $yb ) = _GTxtExt( $text, $x, $y, $just, $upx, $upy);
304
305where $x is the reference x coordinate, $y is the reference y coordinate,
306and where $justification is a character string which specifies the
307location within the text string which is to be placed at the reference
308position given by x and y. The first character may be 'T' for "top", 'C'
309for "centre", or 'B' for "bottom", and specifies the vertical location of
310the reference position. Note, "bottom" corresponds to the base-line of
311normal text. Some characters  (eg "y", "g", "p", etc) descend below the
312base-line. The second  character may be 'L' for "left", 'C' for "centre",
313or 'R'  for "right", and specifies the horizontal location of the
314reference position. If the string has less than 2 characters then 'C' is
315used for the missing characters.
316
317And $upx is the x component of the up-vector for the text, in graphics
318world coordinates. If necessary the supplied value should be negated to
319ensure that positive values always refer to displacements from  left to
320right on the screen.
321
322While $upy is the y component of the up-vector for the text, in graphics
323world coordinates. If necessary the supplied value should be negated to
324ensure that positive values always refer to displacements from  bottom to
325top on the screen.
326
327Finally $xb is a refernce to an array of 4 elements in which to return the
328x coordinate of each corner of the bounding box, and $yb is a reference to
329an array of 4 elements in which to return the y coordinate of each corner
330of the bounding box.
331
332Notes:
333     -  The order of the corners is anti-clockwise (in world coordinates)
334        starting at the bottom left.
335     -  A NULL value for "just" causes a value of "CC" to be used.
336     -  Both "upx" and "upy" being zero causes an error.
337     -  Any unrecognised character in "just" causes an error.
338     -  Zero is returned for all bounds of the box if an error occurs.
339
340=cut
341
342# PLplot only allows justification relative to the horizontal position
343# within the string going from 0 to 1.0, where 0.5 is halfway along.
344# B and T justification requires offsetting by 0.5 character height.
345
346# PLplot assumes C justification (centre of text) as opposed to PGPLOT
347# which assumes B justification by default for vertical positioning.
348
349# upx and upy for PLplot define the angle where
350# the actual angle is atan2(upy,upx) relative to horizontal (mathematical
351# definition of angle rather than astronomical).
352
353# AST seems to define the angle as atan2(-$upx, $upy )
354
355
356sub _GTxExt {
357  my ( $text, $x, $y, $just, $upx, $upy ) = @_;
358
359  #print "Request for Text '$text' Just $just at x=$x y=$y  [$upx/$upy]\n";
360
361  # Make sure we have something
362  my @xb = map { 0.0 } 0..3;
363  my @yb = map { 0.0 } 0..3;
364
365  # check we have a string to print
366  if( defined $text && length($text) != 0 ) {
367
368    # validate the justifcation
369    my $just1 = substr $just, 0, 1;
370    my $just2 = substr $just, 1, 1;
371    if ( defined $just && length($just) == 2 ) {
372
373      # if we have a bogus justification string default it
374      unless( $just1 =~ /[TBC]/ ) {
375	warn "_GText: bad vertical justification defaulting to 'C'\n";
376	$just1 = "C";
377      }
378      unless( $just2 =~ /[LCR]/ ) {
379	warn "_GText: bad horizontal justification defaulting to 'C'\n";
380	$just2 = "C";
381      }
382    } else {
383      warn "_GText: No justification string defaulting to 'CC'\n";
384      $just1 = "C";
385      $just2 = "C";
386    }
387    $just = $just1 . $just2;
388
389    # get the axis scaling
390    my ( $ret, $alpha, $beta ) = _GScales();
391    return ( 0 ) if $ret == 0;
392
393
394    # If either axis is reversed, reverse the supplied up-vector
395    # components so that they refer to the world-coordinates axes.
396    $upx = -$upx if $alpha < 0.0;
397    $upy = -$upy if $beta < 0.0;
398
399    # convert the up-vector into millimetres
400    # [need to think about this - the bounding boxes work perfectly
401    # if I skip this step. They get skewed if I scale by alpha/beta]
402    my $ux = $alpha*$upx;
403    my $uy = $beta*$upy;
404    $ux = $upx;
405    $uy = $upy;
406
407    # normalise the up-vector to a length of 1 millimetre
408    my $uplen = sqrt( $ux*$ux + $uy*$uy );
409    if ( $uplen > 0.0 ) {
410      $ux /= $uplen;
411      $uy /= $uplen;
412    } else {
413      ReportGrfError("_GTxtExt: Zero length up-vector supplied.");
414      return ( 0 );
415    }
416
417    # Form the base-line vector by rotating the up-vector by 90 degrees
418    # clockwise.
419    my $vx = $uy;
420    my $vy = -$ux;
421
422    # Get the height of the string in mm (with fudge factor)
423    my ($def, $ht ) = plgchr();
424    my $fudge = 2;
425    $ht *= $fudge;
426
427    # This is all above the baseline if hd==0 and does not take into account y
428    my $hu =$ht;
429    # but we fudge 10% just in case of string that drops below the baseline
430    my $hd = -0.1* $ht;
431
432    # Get an up and a down vector scaled to the height/depth of the
433    # bounding box above/below the text base-line .
434    my $uxu = $ux*$hu;
435    my $uyu = $uy*$hu;
436    my $uxd = $ux*$hd;
437    my $uyd = $uy*$hd;
438
439    # and the length of the string [in mm]
440    # plstr1 does not work in plplot 5.3.0 so guess
441    #my $width = Graphics::PLplot::plstrl( $text );
442
443    # Assume square characters for now. With a 90% correction
444    # from squareness + 1 character
445    my $width = length($text) * $ht / $fudge * 0.9 + $ht;
446
447    # Scale the base-line vector so that its length is equal to the width
448    # of the bounding box (including spaces).
449    $vx *= $width;
450    $vy *= $width;
451
452    # Convert the base-line vector back into world coordinates.
453    $vx /= $alpha;
454    $vy /= $beta;
455
456    # Convert the up and down vectors into world coordinates.
457    $uxu /= $alpha;
458    $uyu /= $beta;
459    $uxd /= $alpha;
460    $uyd /= $beta;
461
462
463    # Find the coordinates at the centre of the bounding box in world
464    # coordinates.
465    my $xc = $x;
466    my $yc = $y;
467
468    if( $just1 eq 'B' ) {
469      $xc += 0.5*$uxu;
470      $yc += 0.5*$uyu;
471    } elsif( $just1 eq 'T' ) {
472      $xc -= 0.5*$uxu;
473      $yc -= 0.5*$uyu;
474    }
475
476    if( $just2 eq 'L' ) {
477      $xc += 0.5*$vx;
478      $yc += 0.5*$vy;
479    } elsif( $just2 eq 'R' ) {
480      $xc -= 0.5*$vx;
481      $yc -= 0.5*$vy;
482    }
483
484    # Get the corners of the bounding box.
485    my $vdx = 0.5*$vx;
486    my $vdy = 0.5*$vy;
487    my $udx = 0.5*$uxu;
488    my $udy = 0.5*$uyu;
489
490    # Bottom left corner...
491    $xb[ 0 ] = $xc - $vdx - $udx + $uxd;
492    $yb[ 0 ] = $yc - $vdy - $udy + $uyd;
493
494    # Bottom right corner...
495    $xb[ 1 ] = $xc + $vdx - $udx + $uxd;
496    $yb[ 1 ] = $yc + $vdy - $udy + $uyd;
497
498    # Top right corner...
499    $xb[ 2 ] = $xc + $vdx + $udx;
500    $yb[ 2 ] = $yc + $vdy + $udy;
501
502    # Top left corner...
503    $xb[ 3 ] = $xc - $vdx + $udx;
504    $yb[ 3 ] = $yc - $vdy + $udy;
505
506    # Uncomment this if you want to display the bounding box on the plot
507    # my @c = @xb;
508    # my @d = @yb;
509    # $c[4] = $c[0]; $d[4] = $d[0];
510    # _GLine(\@c, \@d);
511    # _GMark([$x],[$y],5);
512
513  }
514
515
516  # Return
517  _GFlush();
518  return (1, \@xb, \@yb );
519}
520
521=item B<_GQch>
522
523This function returns the heights of characters drawn vertically and
524horizontally in world coordinates.
525
526   my ( $status, $chv, $chh ) = _GQch( );
527
528Where $chv is the height of characters drawn with a vertical
529baseline. This will be an increment in the X axis.  Where $chh is the
530height of characters drawn with a horizontal baseline. This will be an
531increment in the Y axis.
532
533=cut
534
535sub _GQch {
536  # Get the height in millimetres
537  my ($def, $ht) = plgchr();
538
539  # This is really just GScales
540  my $chv = mm2world( 1, $ht );
541  my $chh = mm2world( 2, $ht );
542
543  my $status = ( Starlink::AST::_OK() ? 1 : 0 );
544
545  # Return the result in world coordinates
546  return ($status,$chv, $chh);
547}
548
549=item B<_GAttr>
550
551This function returns the current value of a specified graphics
552attribute, and optionally establishes a new value. The supplied
553value is converted to an integer value if necessary before use.
554
555
556   my ( $status, $old_value ) = _GAttr( $attr, $value, $prim );
557
558Where $attr is an integer value identifying the required attribute.
559The following symbolic values are defined in the AST grf.h:
560
561           GRF__STYLE  - Line style.
562           GRF__WIDTH  - Line width.
563           GRF__SIZE   - Character and marker size scale factor.
564           GRF__FONT   - Character font.
565           GRF__COLOUR - Colour index.
566
567$value is a new value to store for the attribute. If this is
568AST__BAD no value is stored, and $old_value is a scalar containing
569the old attribute value, if this is NULL no value is returned.
570
571Finally $prim is the sort of graphics primitive to be drawn with
572the new attribute. Identified by the following values defined in
573AST's grf.h:
574
575           GRF__LINE
576           GRF__MARK
577           GRF__TEXT
578
579=cut
580
581my @gattrs; # Global
582sub _GAttr {
583  my $att = shift;
584  my $val = shift;
585  my $prim = shift;
586  #print "# _GAttr: Placeholder routine called\n";
587
588  my $MAX_ATTR = 5;
589  my $i;
590  if ($att == &Starlink::AST::Grf::GRF__STYLE() ) {
591    $i = 1;
592  } elsif ( $att == &Starlink::AST::Grf::GRF__WIDTH() ) {
593    $i = 2;
594  } elsif ( $att == &Starlink::AST::Grf::GRF__SIZE() ) {
595    $i = 3;
596  } elsif ( $att == &Starlink::AST::Grf::GRF__FONT() ) {
597    $i = 4;
598  } elsif ( $att == &Starlink::AST::Grf::GRF__COLOUR() ) {
599    $i = 5;
600  } else {
601    print "# Bad ATT value: ", $att ."\n";
602  }
603
604  my $j;
605  if ($prim == &Starlink::AST::Grf::GRF__LINE() ) {
606    $j = 1;
607  } elsif ($prim == &Starlink::AST::Grf::GRF__MARK() ) {
608    $j = 2;
609  } elsif ($prim == &Starlink::AST::Grf::GRF__TEXT() ) {
610    $j = 3;
611  } else {
612    print "# Bad PRIM value: $prim\n";
613  }
614
615  # Store the new value if required
616  # Convert prim and att to index of 2d array
617  my $index = ( $MAX_ATTR * ($att - 1) + $prim );
618  my $old = $gattrs[$index];
619  $old = &Starlink::AST::AST__BAD() if !defined $old;
620  $gattrs[$index] = $val if $val != &Starlink::AST::AST__BAD();
621
622  return (1, $old);
623}
624
625=item B<_GCap>
626
627This function is called by the AST Plot class to determine if the
628grf module has a given capability, as indicated by the "cap"
629argument.
630
631  $has_cap = _GCap( $cap, $value );
632
633The capability string should be one of the following constants
634provided in the Starlink::AST::Grf namespace:
635
636GRF__SCALES: This function should return a non-zero value if
637it implements the astGScales function, and zero otherwise. The
638supplied "value" argument should be ignored.
639
640GRF__MJUST: This function should return a non-zero value if
641the astGText and astGTxExt functions recognise "M" as a
642character in the justification string. If the first character of
643a justification string is "M", then the text should be justified
644with the given reference point at the bottom of the bounding box.
645This is different to "B" justification, which requests that the
646reference point be put on the baseline of the text, since some
647characters hang down below the baseline. If the astGText or
648astGTxExt function cannot differentiate between "M" and "B",
649then this function should return zero, in which case "M"
650justification will never be requested by Plot. The supplied
651"value" argument should be ignored.
652
653GRF__ESC: This function should return a non-zero value if the
654astGText and astGTxExt functions can recognise and interpret
655graphics escape sequences within the supplied string. These
656escape sequences are described below. Zero should be returned
657if escape sequences cannot be interpreted (in which case the
658Plot class will interpret them itself if needed). The supplied
659"value" argument should be ignored only if escape sequences cannot
660be interpreted by astGText and astGTxExt. Otherwise, "value"
661indicates whether astGText and astGTxExt should interpret escape
662sequences in subsequent calls. If "value" is non-zero then
663escape sequences should be interpreted by astGText and
664astGTxExt. Otherwise, they should be drawn as literal text.
665
666Zero should be returned if the supplied capability is not recognised.
667
668=cut
669
670sub _GCap {
671  my $cap = shift;
672  my $value = shift;
673
674  # We have got a SCALES routine
675  if ($cap == &Starlink::AST::Grf::GRF__SCALES) {
676    return 1;
677  }
678  return 0;
679}
680
681
682# Internal error setting routine
683sub ReportGrfError {
684  my $text = shift;
685  warn "Generated AST error in perl PLplot callback: $text\n";
686  Starlink::AST::_Error( &Starlink::AST::Status::AST__GRFER(), $text);
687}
688
689# Routine to convert distance in millimetres to world coordinates
690#   $dw = mm2world( $axis, $mm )
691# Where argument one is "1" for X-axis and "2" for Y-axis.
692# Second argument is distance in mm.
693# Returns 0 and sets AST status on error
694
695sub mm2world {
696  my ($ax, $mm ) = @_;
697  return 0 unless Starlink::AST::_OK;
698
699  # page size in millimetres
700  my ($mx1,$mx2,$my1,$my2) = plgspa();
701
702  # Size of viewport in world coordinates
703  my ($wx1, $wx2, $wy1, $wy2) = plgvpw();
704
705  # now convert distance in mm to world coordinates
706
707  # X direction
708  if ($ax == 1) {
709    if ($mx1 != $mx2) {
710      $mm *= ($wx2 - $wx1 ) / ( $mx2 - $mx1 );
711    } else {
712      ReportGrfError("astGQch: The graphics viewport has zero size in the X direction.");
713      return 0;
714    }
715  } else {
716    # Y direction
717    if ($my1 != $my2) {
718      $mm *= ($wy2 - $wy1 ) / ( $my2 - $my1 );
719    } else {
720      ReportGrfError("astGQch: The graphics viewport has zero size in the Y direction.");
721      return 0;
722    }
723
724  }
725  return $mm;
726
727}
728
729
730=back
731
732=head1 COPYRIGHT
733
734Copyright (C) 2004-2005 Particle Physics and Astronomy Research Council.
735All Rights Reserved.
736
737This program is free software; you can redistribute it and/or modify it under
738the terms of the GNU General Public License as published by the Free Software
739Foundation; either version 2 of the License, or (at your option) any later
740version.
741
742This program is distributed in the hope that it will be useful,but WITHOUT ANY
743WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
744PARTICULAR PURPOSE. See the GNU General Public License for more details.
745
746You should have received a copy of the GNU General Public License along with
747this program; if not, write to the Free Software Foundation, Inc., 59 Temple
748Place,Suite 330, Boston, MA  02111-1307, USA
749
750=head1 AUTHORS
751
752
753Tim Jenness E<lt>tjenness@cpan.orgE<gt>,
754Alasdair Allan E<lt>aa@astro.ex.ac.ukE<gt>,
755Brad Cavanagh E<lt>b.cavanagh@jach.hawaii.eduE<gt>,
756Andy Gibb E<lt>agibb@phas.ubc.caE<gt>.
757
758
759=cut
760
761
762package Starlink::AST::Plot;
763
764use strict;
765use vars qw/ $VERSION /;
766
767use Starlink::AST::PLplot;
768
769sub plplot {
770  my $self = shift;
771
772  $self->GFlush(\&Starlink::AST::PLplot::_GFlush);
773  $self->GLine(\&Starlink::AST::PLplot::_GLine);
774  $self->GMark(\&Starlink::AST::PLplot::_GMark);
775  $self->GText(\&Starlink::AST::PLplot::_GText);
776  $self->GTxExt(\&Starlink::AST::PLplot::_GTxExt);
777  $self->GQch(\&Starlink::AST::PLplot::_GQch);
778  $self->GAttr(\&Starlink::AST::PLplot::_GAttr);
779  $self->GScales(\&Starlink::AST::PLplot::_GScales);
780  $self->GCap(\&Starlink::AST::PLplot::_GCap);
781
782  return 1;
783}
784
7851;
786