home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Acorn User 10
/
AU_CD10.iso
/
Updates
/
Perl
/
Non-RPC
/
!Perl
/
riscos
/
RISCOS
/
DrawFile
/
Common.pm
next >
Wrap
Text File
|
1999-01-20
|
7KB
|
221 lines
package RISCOS::DrawFile::Common;
use RISCOS::BBox qw(inside inside_or_touching intersect intersect_or_touching
outside);
use RISCOS::Clone (Clone);
use strict;
use vars qw ($VERSION @ISA @EXPORT_OK);
use Carp;
$VERSION = 0.03;
# 0.03 adds Translate
@ISA = 'Exporter';
@EXPORT_OK = 'drawplus_split_type';
### use SelfLoader;
sub RISCOS::DrawFile::Common::drawplus_split_type ($);
sub RISCOS::DrawFile::Common::BBox ;
sub RISCOS::DrawFile::Common::Translate ($$$$);
sub RISCOS::DrawFile::Common::Inside ($$);
sub RISCOS::DrawFile::Common::InsideOrTouching ($$);
sub RISCOS::DrawFile::Common::Intersect ($$);
sub RISCOS::DrawFile::Common::IntersectOrTouching ($$);
sub RISCOS::DrawFile::Common::Outside ($$);
1;
### __DATA__
sub drawplus_split_type ($) {
return $_[0] & 0xFF unless wantarray;
unpack 'C4', pack 'I', $_[0];
}
sub BBox {
my $self = shift;
defined $self->{'__BBOX'} ? $self->{'__BBOX'} : $self->BBox_Calc;
}
sub Translate ($$$$) {
if (ref ($_[3]) eq 'CODE') {
&{$_[3]}($_[0], $_[1], $_[2]);
} elsif (not defined $_[3]) {
warn "Cannot translate $_[0] by ($_[1], $_[2])\n";
} elsif ($_[3] eq '') {
my $self = $_[0];
my $bbox = defined $self->{'__BBOX'} ? $self->{'__BBOX'}
: $self->BBox_Calc;
if (defined $bbox) {
$$bbox[0] += $_[1];
$$bbox[1] += $_[2];
$$bbox[2] += $_[1];
$$bbox[3] += $_[2];
} else {
warn "Cannot translate $_[0] by ($_[1], $_[2])\n";
}
} else {
confess "Illegal third argument to translate ('$_[3]') when attempting to translate $_[0] by ($_[1], $_[2])";
}
();
}
sub Inside ($$) {
my $bbox = $_[0]->BBox();
($bbox and inside $_[1], $bbox) ? $_[0] : ();
# Return ourself if we have a defined bbox, and if it is inside the supplied
# box
# Otherwise, if I've understood things correctly empty list () should be
# converted to undef in scalar context, and used correctly in list context
# Using undef will add (undef) to any list which is being accumulated from
# our return result.
}
sub InsideOrTouching ($$) {
my $bbox = $_[0]->BBox();
($bbox and inside_or_touching $_[1], $bbox) ? $_[0] : ();
}
sub Intersect ($$) {
my $bbox = $_[0]->BBox();
($bbox and intersect $_[1], $bbox) ? $_[0] : ();
}
sub IntersectOrTouching ($$) {
my $bbox = $_[0]->BBox();
($bbox and intersect_or_touching $_[1], $bbox) ? $_[0] : ();
}
sub Outside ($$) {
my $bbox = $_[0]->BBox();
($bbox and outside $_[1], $bbox) ? $_[0] : ();
}
1;
__END__
=head1 NAME
RISCOS::DrawFile::Common
=head1 SYNOPSIS
Methods common to DrawFiles and objects within DrawFiles.
=head1 DESCRIPTION
C<RISCOS::DrawFile::Common> provides methods common to DrawFiles and to objects
within DrawFiles. It provides one function C<drawplus_split_type>.
=head2 drawplus_split_type
$type = drawplus_split_type 0x00010402; # $type = 0x02
($type, $layer, $flags, $spare) = drawplus_split_type $type;
C<drawplus_split_type> takes an integer and interprets it as a DrawPlus
"extended tag". In scalar context it returns the standard draw type, in array
context the list (type, layer, flags, spare), as described in the DrawPlus
documentation.
=head2 Methods
=over 4
=item Clone
returns a copy of this object. Derived class implementors should see
L<RISCOS::Clone> for the cloning teqnique, and the B<assumptions> it makes.
=item BBox
returns a reference to an array giving the bounding box, or C<undef> if there is
is no bounding box for this object (I<i.e.> font tables, empty paths, option
objects). Note that option objects and empty paths store a bounding box of
(0,0,0,0) when saved. C<BBox> will attempt to call C<BBox_Calc> (which the
derived class B<must> provide) if the bounding box is currently unknown.
As the returned array reference B<is> the internal copy of the bounding box it
must not be modified.
=item Translate <x> <y> [<barf_func>]
translates the object by (I<x>, I<y>), or calls
&I<barf_func> (I<object>, I<x>, I<y>) for any object for which translation is
not possible (I<i.e.> unknown objects and tagged objects, as the tag data might
contain co-ordinate information. If I<barf_func> is undefined a warning is
issued, while an empty string silences any warning, and assumes that altering
the bounding box of any unknown object is sufficient to perform the translation.
=item Inside <bbox>
checks whether this object is entirely within the bounding box (passed as an
array reference). Returns a reference to the object if it is, an empty list if
it touches, intersects or lies outside the box. The empty list C<()> is
converted to C<undef> in scalar context, whereas returning C<undef> in list
context would generate a one element list C<(undef>) which can cause surprises.
=item InsideOrTouching <bbox>
checks whether this object is entirely within or touching the bounding box
(passed as an array reference). Returns a reference to the object if it is,
C<()> if it intersects or lies outside the box.
=item Intersect <bbox>
checks whether any of this object's bounding box is within the bounding box
(passed as an array reference). Returns a reference to the object if it is,
C<()> if it lies outside the box (including just touching the edge).
=item IntersectOrTouching <bbox>
checks whether any of this object's bounding box is within the bounding box, or
is touching the box (passed as an array reference). Returns a reference to the
object if it is, C<()> if it lies outside and is not touching the box.
=item Outside <bbox>
checks whether this object's bounding box is entirely outside the bounding box
(passed as an array reference). Returns a reference to the object if it is,
C<()> if any part of the bounding box touches or intersects the box.
=back
=head2 Methods derived classes must supply
In addition to the overriding above methods where appropriate (in particular
C<Type>) derived classes (DrawFile and DrawFile objects) must provide the
following methods. All objects within DrawFiles provide further classes as
specifed in C<RISCOS::DrawFile::Object>.
=over 4
=item BBox_Calc
(re)calculates the bounding box, returning a reference to an array, or undef if
there is no bounding box. As it has no idea about the data it contains
C<OpaqueObject> simply returns the bounding box it was given when it was called.
=item PrePack <hash_reference>
a hook to perform calculations immediately before saving a DrawFile. The hash
reference is used to store the names of fonts needed in the FontTable, keys are
font names, values the number of text objects that use that font (see C<PrePack>
in C<RISCOS::DrawFile::Text> if you really must know).
=item Pack <undef>, fonttable, ...
returns a scalar containing the object packed ready to save into a DrawFile.
=item Write <filehandle>, <fonttable>, ...
writes the object to the given filehandle. C<Write> should return true unless
there was an error.
=back
=head1 BUGS
Not tested enough.
=head1 AUTHOR
Nicholas Clark <F<nick@unfortu.net>>