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>

