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