home *** CD-ROM | disk | FTP | other *** search
- package RISCOS::DrawFile;
-
- use strict;
- use vars qw ($VERSION @ISA);
-
- require RISCOS::DrawFile::Container;
-
- use RISCOS::File 0.03 qw(load filetype settype);
- use Carp;
- use IO::File;
-
- $VERSION = 0.04;
- @ISA = 'RISCOS::DrawFile::Container';
-
- # 0.04
- # Add undef as a possible [] of contents, and as a Filetype(undef)
- # 0.03
- # Write blank DrawFiles.
- # Add Write to documentation
-
- sub group {new RISCOS::DrawFile::Group @_}
-
- sub new {
- my $proto = shift;
- my $class = ref($proto) || $proto;
-
- if (defined $_[0] and ref ($_[0]) eq $class) {
- return $_[0]->Clone();
- # Copy it and all done [note that this is derived class safe :-) ]
- }
-
- my $self = $class->SUPER::new();
-
- my ($contents, $oldfont, $minor, $creator, $filetype);
-
- if (ref($_[0]) eq 'ARRAY' or !defined $_[0]) {
- ($contents, $creator, $oldfont, $filetype) = @_;
- $contents = [] unless defined $contents;
- $filetype = 0xAFF unless defined $filetype;
- $minor = 0;
- } else {
- # arg 0 is filename (whatever)
- # arg 1 is type splitfunction
- my $split = $_[1];
- $split = \&RISCOS::DrawFile::Common::drawplus_split_type
- if defined $split and $split eq '+';
- my ($file, $a, $b, $load, $exec) = &load; # Pass on our arguments
-
- unless (defined $file) {
- carp 'Could not load file' if $^W;
- return undef;
- }
- $filetype = defined $load ? filetype ($load) : 0xAFF;
- my ($tag, $major); # Ignore BBox in file header - will recalculate
- ($tag, $major, $minor, $creator) = unpack 'a4I2A12', $file;
- unless ($tag eq 'Draw') {
- carp "File is not a DrawFile ('$tag')" if $^W;
- return undef;
- }
- unless ($major == 201) {
- carp "DrawFile major version $major != 201" if $^W;
- return undef;
- }
-
- ($contents, undef, $oldfont) = $self->_split_drawobjs
- (\(substr $file, 40), $split, \$oldfont, $self->Objfunc(),
- $self->can ('Second_Font_Table'), $self->can ('Unknown_Obj'));
- }
- $self->Stuff ($contents);
- $self->{'__CREATOR'} = defined $creator ? $creator : "PerlDraw$VERSION";
- $self->{'__MINOR'} = $minor;
- $self->{'__FONT'} = defined ($oldfont) ? $oldfont : [];
- $self->{'__FILETYPE'} = $filetype;
-
- bless ($self, $class);
- }
-
- # Really not tested.
- sub Pack {
- my $self = shift;
-
- my $used_fonts = {};
- my $bbox = $self->PrePack($used_fonts);
- $_[1] = RISCOS::DrawFile::FontTable->new($used_fonts);
- pack ('A4I2A12i4', 'Draw', $self->Major(), $self->Minor(), $self->Creator(),
- ($bbox ? @$bbox : (0,0,0,0)))
- . $_[1]->Pack (@_) # Fonttable
- . $self->SUPER::Pack (@_);
- }
-
- sub Write {
- local $\; undef $\;
- my $self = shift;
- $self = RISCOS::DrawFile->new ([])
- if !defined $self or $self eq __PACKAGE__;
- # Create an empty DrawFile to write
-
- unless (ref($_[0]) ? (ref($_[0]) eq 'GLOB'
- || UNIVERSAL::isa($_[0], 'GLOB')
- || UNIVERSAL::isa($_[0], 'IO::Handle'))
- : (ref(\$_[0]) eq 'GLOB')) {
- my $file = shift;
- unshift @_ , new IO::File ">$file";
- croak "Unable to open '$file': $!" unless $_[0];
- # Can't overwrite $_[0] as it may be read only.
- }
- my $used_fonts = {};
- my $bbox = $self->PrePack($used_fonts);
- my $good = print {$_[0]} pack 'A4I2A12i4', 'Draw', $self->Major(),
- $self->Minor(),
- $self->Creator(),
- ($bbox ? @$bbox : (0,0,0,0));
- # Do the fonttable here.
- if (%$used_fonts) {
- $_[1] = RISCOS::DrawFile::FontTable->new($used_fonts);
- $_[1]->Write (@_);
- }
- $good = settype ($self->{'__FILETYPE'}, $_[0])
- if defined $self->{'__FILETYPE'};
- $good & $self->SUPER::Write (@_);
- }
-
- sub Major { 201; }
- sub Minor {
- my $self = shift;
- my $minor = $self->{'__MINOR'};
- $self->{'__MINOR'} = $_[0] if defined $_[0];
- $minor;
- }
- sub Creator {
- my $self = shift;
- my $creator = $self->{'__CREATOR'};
- $self->{'__CREATOR'} = $_[0] if defined $_[0];
- $creator;
- }
-
- sub FileType {
- my $self = shift;
- my $filetype = $self->{'__FILETYPE'};
- $self->{'__FILETYPE'} = $_[0] if @_;
- $filetype;
- }
- 1;
- __END__
-
- =head1 NAME
-
- RISCOS::DrawFile
-
- =head1 SYNOPSIS
-
- A class to manipulate DrawFiles
-
- =head1 DESCRIPTION
-
- C<RISCOS::DrawFile> provides a class to manipulate DrawFiles. It is derived from
- C<RISCOS::DrawFile::Container> (which provides all the really cool methods),
- and provides the following additional methods.
-
- =over 4
-
- =item new [<contents>, [<creator>, [<oldfont>, [<filetype>]]]]
-
- =item new <filename>, [<split_function>]
-
- creates a new DrawFile. If the first argument is C<undef> or a reference to an
- array it is taken to be an array of objects derived from
- <RISCOS::DrawFile::Object> which are to be used as the contents. Otherwise the
- first argument is passed to C<RISCOS::File::load>, so I<filename> can actually
- be a filehandle, or the file data to use.
-
- I<creator> defaults to C<"PerlDraw$VERSION">, which at 12 characters can cause
- problems for some drawing programs (I<e.g.> DrawPlus prior to 2.41). I<oldfont>
- if defined should be a reference to an array of fonts found when loading the
- DrawFile and isn't really used, as C<RISCOS::DrawFile::TextObject> objects each
- store their own font. I<filetype> defaults to 0xAFF (DrawFile).
-
- I<split_function> is passed as the second argument to
- C<RISCOS::DrawFile::Object::new> for each object found in the DrawFile to
- process the DrawFile object type to extract layer information. If defined this
- should either be a code reference, or the string 'C<+>' to use
- C<RISCOS::DrawFile::Common::drawplus_split_type>
-
- =item Write <filename>
-
- =item Write <filehandle>
-
- writes the DrawFile to the given filename or filehandle, and attempts to set the
- file's filetype to the type set/returned with C<FileType>. Calling this Write as
- a class method will write an empty DrawFile:
-
-
- Write RISCOS::DrawFile ('DrawFile') # Write a blank DrawFile
- RISCOS::DrawFile->Write ('DrawFile') # There's More Than One Way To Do It
-
- =item Major
-
- returns the major version number of this DrawFile, which will always be 201.
- C<new> will correctly refuse to load DrawFiles with any other major version
- number.
-
- =item Minor [<version>]
-
- returns the minor version number of this DrawFile. If an defined argument is
- supplied sets the minor verion to this, and returns the old value.
-
- =item Creator [<creator>]
-
- returns the creator string for this DrawFile. If an defined argument is
- supplied sets the creator, and returns the old value. Creator strings are
- truncated or padded with B<spaces> to give 12 characters when the DrawFile is
- written out. Note that 12 character creator names can cause problems for poorly
- written programs.
-
- =item FileType [<filetype>]
-
- returns the filetype that C<Write> will give this file. If I<filetype> is
- supplied this value is set, and the old value returned. The value is stored
- verbatim, relying on C<RISCOS::File::settype> to do any conversion necessary.
- If the filetype is C<undef> then C<Write> will not attempt to set the filetype.
-
- Note that while C<RISCOS::DrawFile> has no problem loading Equasor files, the
- file written out will have the FontTable as first object, rather than the tagged
- empty path that Equasor expects, and so Equasor will refuse to recognise the
- file. Regrettably the transparency that C<RISCOS::DrawFile> by automaticaly
- tabulating fonts and creating a FontTable means that it is not possible for this
- general purpose class to ensure that the FontTable is at a specific loation
- within the file. (Well, not without breaking various other programs that wrongly
- expect the FontTable to be the B<very> first object in a file. RTFM carefully.)
-
- =back
-
- =head1 BUGS
-
- Not tested enough. Especially C<Pack>
-
- =head1 AUTHOR
-
- Nicholas Clark <F<nick@unfortu.net>>
-