home *** CD-ROM | disk | FTP | other *** search
/ Acorn User 10 / AU_CD10.iso / Updates / Perl / Non-RPC / !Perl / riscos / RISCOS / DrawFile / TextArea.pm < prev   
Text File  |  1999-01-20  |  5KB  |  192 lines

  1. package RISCOS::DrawFile::TextArea;
  2. use Carp;
  3.  
  4. use strict;
  5. use vars qw ($VERSION @ISA $default_header $user_default_header);
  6. #use RISCOS::Units qw(pack_transform_block unpack_transform_block
  7. #             millipoint2draw point2draw);
  8. require RISCOS::DrawFile::Object;
  9. # require RISCOS::Font;
  10.  
  11. $VERSION = 0.04;
  12. # 0.04 adds Translate
  13. # 0.03 adds TextArea method
  14. # 0.02 keep colours internally as 4 bytes packed
  15. @ISA = 'RISCOS::DrawFile::Object';
  16.  
  17. $default_header = <<'Wizzo';
  18. \! 1
  19. \F 0 Trinity.Medium 12
  20. \F 1 Corpus.Medium 12
  21. \0\AD/\L12
  22. Wizzo
  23.  
  24. ### use SelfLoader;
  25. sub RISCOS::DrawFile::TextArea::DefaultHeader ($);
  26. sub RISCOS::DrawFile::TextArea::new ($$);
  27. sub RISCOS::DrawFile::TextArea::Type ;
  28. sub RISCOS::DrawFile::TextArea::Cols ;
  29. sub RISCOS::DrawFile::TextArea::ShiftCols ;
  30. sub RISCOS::DrawFile::TextArea::TextArea ;
  31. sub RISCOS::DrawFile::TextArea::Translate ($$$$);
  32. sub RISCOS::DrawFile::TextArea::BBox_Calc ;
  33. sub RISCOS::DrawFile::TextArea::Size ;
  34. sub RISCOS::DrawFile::TextArea::Pack ($$);
  35. sub RISCOS::DrawFile::TextArea::DefaultHeader ($);
  36. sub RISCOS::DrawFile::TextArea::new ($$);
  37. sub RISCOS::DrawFile::TextArea::Type ;
  38. sub RISCOS::DrawFile::TextArea::Cols ;
  39. sub RISCOS::DrawFile::TextArea::ShiftCols ;
  40. sub RISCOS::DrawFile::TextArea::TextArea ;
  41. sub RISCOS::DrawFile::TextArea::Translate ($$$$);
  42. sub RISCOS::DrawFile::TextArea::BBox_Calc ;
  43. sub RISCOS::DrawFile::TextArea::Size ;
  44. sub RISCOS::DrawFile::TextArea::Pack ($$);
  45. 1;
  46. ### __DATA__
  47. sub DefaultHeader ($) {
  48.     my $result = defined $user_default_header ? $user_default_header
  49.                           : $default_header;
  50.     $user_default_header = shift if (@_);
  51.     $result;
  52. }
  53.  
  54. sub new ($$) {
  55.     my $proto = shift;
  56.     my $class = ref($proto) || $proto;
  57.  
  58.     my ($self, $type) = $class->SUPER::new (@_);
  59.     return $self if ref ($self) eq 'ARRAY';
  60.  
  61.     my ($bbox, $fore, $back, $text, $cols) = ([]);
  62.     return wantarray ? () : undef unless defined $_[0];
  63.     if (ref $_[0] eq 'ARRAY') {
  64.     ($text, $fore, $back, $cols) = @{$_[0]};
  65.     $cols = [@$cols];    # Copy theirs, rather than taking a reference.
  66.     $text = $self->DefaultHeader() unless $text =~ /^\\!/;
  67.     $text .= "\n" unless $text =~ /\n$/s;
  68.     } else {
  69.     # Time to unpack data
  70.     my $data;
  71.     if (ref $_[0] eq 'SCALAR' or ref $_[0] eq 'LVALUE') {
  72.         # Has bounding box stripped
  73.         $data = ${$_[0]};
  74.     } else {
  75.         my $length;
  76.         ($length, @$bbox) = unpack 'x4Ii4', $_[0];
  77.         return undef unless length ($_[0]) == $length or $length & 3;
  78.         $data = substr $_[0], 24;
  79.     }
  80.     while (length $data) {
  81.         # Hmm. I think that I know why there are two reserved words...
  82.         my ($ctype, $sublength, @box) = unpack 'I2i4', $data;
  83.         # Text area is at least 24 bytes after the columns
  84.         last if ($ctype == 0);
  85.         if ($ctype != 10 or $sublength != 24) {
  86.         warn sprintf "Tag &%X length $sublength when expecting text " .
  87.                  'column object', $ctype;
  88.         return wantarray ? () : undef;
  89.         }
  90.         push @$cols, [@box];
  91.         $data = substr $data, 24;
  92.     }
  93.     my ($res1, $res2);
  94.     ($res1, $res2, $fore, $back, $text) = unpack 'x4I2a4a4a*', $data;
  95.     carp sprintf 'Text area reserved words area &%08X &%08X - should be 0',
  96.              $res1, $res2 if $res1 or $res2;
  97.     $text =~ s/\0.*//s;
  98.     }
  99.     $self->{'__BBOX'} = $bbox;
  100.     $self->{'__COLS'} = $cols;
  101.     $self->{'__FORE'} = $fore;
  102.     $self->{'__BACK'} = $back;
  103.     $self->{'__TEXT'} = $text;
  104.  
  105.     wantarray ? ($self, $type) : $self;
  106. }
  107.  
  108. sub Type { 9; }
  109.  
  110. sub Cols {
  111.     my $self = shift;
  112.     my $old = $self->{'__COLS'};
  113.     $self->{'__COLS'} = $_[0] if (@_);
  114.     $old;
  115. }
  116.  
  117. sub ShiftCols {
  118.     my $self = shift;
  119.     shift @{$self->{'__COLS'}};
  120. }
  121.  
  122. sub TextArea {
  123.     my $self = shift;
  124.     my $old = $self->{'__TEXT'};
  125.     $self->{'__TEXT'} = $_[0] if (@_);
  126.     $old;
  127. }
  128.  
  129. sub Translate ($$$$) {
  130.     my ($self, $x, $y) = @_;
  131.     my $bbox = $self->{'__BBOX'};
  132.     if (defined $bbox) {
  133.     $$bbox[0] += $x;
  134.     $$bbox[1] += $y;
  135.     $$bbox[2] += $x;
  136.     $$bbox[3] += $y;
  137.     }
  138.     foreach (@{$self->{'__COLS'}}) {
  139.     $$_[0] += $x;
  140.     $$_[1] += $y;
  141.     $$_[2] += $x;
  142.     $$_[3] += $y;
  143.     }
  144.     ();
  145. }
  146.     
  147.     
  148. sub BBox_Calc {
  149.     my $self = shift;
  150.     my $box = [0x7FFFFFFF, 0x7FFFFFFF, -0x7FFFFFF, -0x7FFFFFF];
  151.  
  152.     foreach (@{$self->{'__COLS'}}) {
  153.     $$box[0] = $$_[0] if $$box[0] > $$_[0];    # min
  154.     $$box[1] = $$_[1] if $$box[1] > $$_[1];
  155.     $$box[2] = $$_[2] if $$box[2] < $$_[2];    # max
  156.     $$box[3] = $$_[3] if $$box[3] < $$_[3];
  157.     }
  158.     $self->{'__BBOX'} = $box;    # Return the bbox we made, and store it
  159. }
  160.  
  161. sub Size {
  162.     my $self = shift;
  163.     # 4 for '\0' and padding.
  164.     (24 + 24 * @{$self->{'__COLS'}} + 20 + 4 + length $self->{'__TEXT'}) & ~3;
  165. }
  166.  
  167. sub Pack ($$) {
  168.     my $self = shift;
  169.     $self->PackTypeSizeBBox(9)
  170.       . join ('', map { $self->PackTypeSizeBBox(10, 24, $_) }
  171.               @{$self->{'__COLS'}})
  172.       . pack ('I3a4a4', 0, 0, 0, $self->{'__FORE'}, $self->{'__BACK'})
  173.       . $self->{'__TEXT'} . "\0" x (4 - (length ($self->{'__TEXT'}) & 3))
  174. }
  175.  
  176. 1;
  177. __END__
  178.  
  179. =head1 NAME
  180.  
  181. RISCOS::Drawfile
  182.  
  183. =head1 SYNOPSIS
  184.  
  185. =head1 DESCRIPTION
  186.  
  187. =head1 BUGS
  188.  
  189. =head1 AUTHOR
  190.  
  191. Nicholas Clark <F<nick@unfortu.net>>
  192.