home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Acorn User 10
/
AU_CD10.iso
/
Updates
/
Perl
/
Non-RPC
/
Docs
/
RISCOS-Library-Docs
/
Container.pm
< prev
next >
Wrap
Text File
|
1999-04-17
|
9KB
|
247 lines
NAME
RISCOS::DrawFile::Container
SYNOPSIS
Abstract base class for classes that hold other DrawFile
objects.
DESCRIPTION
`RISCOS::DrawFile::Container' provides an abstract base class
for classes that hold other DrawFile objects (groups, tagged
objects and DrawFiles themselves. `RISCOS::DrawFile::Container'
itself is not a `RISCOS::DrawFile::Object', as not all classes
which derive from it are objects found in DrawFiles.
Methods
new <contents>
creates a new object. If *contents* is an array reference it
is dereferenced. The array of objects (if any) is used as
the container's contents.
Stuff [<new_contents>]
returns a reference to the array of contents. If
*new_contents* are given, then these replace the existing
contents (and the old contents are returned). If
*new_contents* is an array reference it is automatically
dereferenced first.
MoreStuff [<additional_contents>]
adds *new_contents* existing contents, returning a reference
to the array of contents. If *additional_contents* is an
array reference it is automatically dereferenced first.
Do <what>, arguments...
recursively does something to all contained objects.
For each contained item:
* If it has a `Do' method, calls it with the arguments passed
to this method.
* If <what> is a code reference, calls it as
&what (object, arguments...)
else looks for a method *what* in the object, and if
found calls that method with the arguments given
`Do' returns the list of all results returned from all
called subroutines.
This method is extremely powerful. For example, to set all
line widths to thin in the object `$draw'
$draw->Do('Width', 0);
To change all occurrences of the font 'Homerton.Medium' to
'AvantG.Book' in all text objects you could do:
$draw->Do(sub {$_[0]->Font ('AvantG.Book')
if $_[0]->can('Font')
and $_[0]->Font() eq 'Homerton.Medium'});
(note that if you pass code you need to check that the
method exists with `can' before you try to call it) but
you'd be much better off with
$draw->ChangeString('Font','Homerton.Medium','AvantG.Book');
(see below)
DoToAll <what>, arguments...
is like `Do' except that it also calls the named method or
code reference on contained containers, unlike `Do' which
only calls it on objects which do not possess their own `Do'
to recurse to. Unless you want to alter contained Groups or
Tag objects in some way, you probably don't want to call
`DoToAll' as it will return an possibly unhelpful list of
results - for example if the result array is all objects
inside a bounding box you may get objects within groups
multiple times; once when the check is performed on the
object itself, and again within each group that also meets
the test condition.
Replace <what>, arguments...
is like `Do' except it *replaces* the contents of each
container with the return values of *what*, so *what* had
better be returning DrawFile objects. If a container
contains at least one object afterwards it returns a
reference to itself, whereas an empty container returns
`undef'. Beware that this way a container (*e.g.* an entire
DrawFile) can end up deleting itself, so do check the return
value, before your script crashes when attempting to call a
method on a now undefined scalar.
Change <method_name>, <test_value> arguments...
is similar to `Do', but can only take a named method. The
method is called with no arguments in scalar context, and if
the result is *numerically* equal (`==') to *test_value* the
method is called again with the arguments supplied.
So to change all 4 point lines to 6
$draw->Change('Width', 2560, 3840);
(without having to ungroup or regroup anything...)
ChangeString <method_name>, <test_value> arguments...
is identical to `Change' except that the comparison is for a
string (`eq').
$draw->ChangeString('Font','Homerton.Medium','AvantG.Book');
BBox
returns a reference to an array giving the bounding box, or
`undef' if there is no bounding box for this object (*e.g.*
an empty group, a tagged empty path). `BBox' will call
`BBox_Calc' if the bounding box is currently unknown.
As the returned array reference is the internal copy of the
bounding box it must not be modified.
BBox_Calc
recalculates and returns the bounding box, by calling
`BBox_Calc' for each contained object and merging the
bounding boxes. `BBox_Calc' will return `undef' if no
contained object returned a valid bounding box. (This is far
more elegant than returning (int_max, int_max, int_min,
int_min), as is the wont of `Draw_ProcessPath' when
presented with an empty path - yes, we're trapping this one,
and `Font_ScanString' when given an empty string).
PrePack <hash_reference>
is provided as 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 by
`RISCOS::DrawFile::Text' objects. `PrePack' calls `PrePack'
for each contained object, and merges the bounding boxes.
Size
returns the size of the object when saved in a DrawFile, by
summing the results of calling `Size' on the contents.
Pack <undef>, fonttable, ...
returns a scalar containing the object packed ready to save
into a DrawFile, by concatenating the results of calling
`Pack' on the contents.
Write <filehandle>, <fonttable>, ...
writes the object to the given filehandle. The default
implementation calls `Write' with the remainder of the
argument list for each item in the contents, returning false
if any call to `Write' did not return true.
Second_Font_Table
prints a warning that a second font table has been found,
and returns an empty list. Mostly of use to the DrawFile
class.
Objfunc
returns a reference to a hash of code references, keyed by
object type. This hash determines the correct object
constructor to call when the DrawFile data is split into
objects. Mostly of use to the DrawFile class.
Unknown_Obj
prints a warning that an unknown object type has been found,
and returns the result of calling
`RISCOS::DrawFile::OpaqueObject'. Mostly of use to the
DrawFile class.
_split_drawobjs <data>, <split>, <fonttable>, <sub_constructors>, <duplicate_fonttable>, <unknown_object>
splits the data passed as a scalar reference into a list of
DrawFile objects. *split* is a split function as described
in `new' in `RISCOS::DrawFile::Object'. *fonttable* is
initially `undef', but for recursive calls is replaced with
the fonttable object once found. *sub_constructors* is a
hash or array reference used to find code to construct
objects keyed by type. Usually this is supplied by calling
`Objfunc', but a custom hash/array can be used.
*duplicate_fonttable* is called as a constructor when a
second fonttable is found. Usually this is a reference to
`&Second_Font_Table'. *unknown_object* is called as a
constructor for any object type not found in
*sub_constructors*. Usually this is a reference to
*&Unknown_Obj*.
`_split_drawobjs' returns a list ([objects], undef,
fonttable) as for a DrawFile object constructor.
This method is used by groups and DrawFile objects to split
their contents into objects. It probably isn't needed by
anyone else.
Do <what>, arguments...
recursively does something to all contained objects.
For each contained item:
* If it has a `Do' method, calls it with the arguments passed
to this method.
* If <what> is a code reference, calls it as
&what (I<object>, I<arguments...>
else looks for a method *what* in the object, and if
found calls that method with the arguments given
`Do' returns the list of all results returned from all
called subroutines.
This method is extremely powerful. For example, to set all
line widths to thin in the object `$draw'
$draw->Do('Width', 0);
To change all occurrences of the font 'Homerton.Medium' to
'AvantG.Book' in all text objects:
$draw->Do(sub {$_[0]->Font ('AvantG.Book')
if $_[0]->can('Font')
and $_[0]->Font() eq 'Homerton.Medium'});
(note that if you pass code you need to check that the
method exists with `can' before you try to call it)
BUGS
Currently doesn't allow derived classes to limit the number of
objects that they can hold. (`TagObject's only hold one object)
AUTHOR
Nicholas Clark <nick@unfortu.net>