home *** CD-ROM | disk | FTP | other *** search
/ Acorn User 10 / AU_CD10.iso / Updates / Perl / Non-RPC / !Perl / riscos / RISCOS / Units.pm < prev    next >
Text File  |  1998-07-26  |  4KB  |  161 lines

  1. package RISCOS::Units;
  2.  
  3. require Exporter;
  4. use Carp;
  5. use strict;
  6. use vars qw (@ISA @EXPORT_OK $VERSION $AUTOLOAD %factors);
  7.  
  8. @ISA = qw(Exporter);
  9. @EXPORT_OK = qw(pack_transform unpack_transform
  10.         pack_transform_block unpack_transform_block);
  11. $VERSION = 0.03;
  12. # 0.02 does Map
  13. # 0.03 packs transform blocks
  14.  
  15. %factors = (
  16.   draw => 1, os => 256, inch => 256 * 180, user => 1,
  17.   point => 256 * 180 / 72, millipoint => 256 / 400);
  18.  
  19. my ($a, $b);
  20. foreach $a (keys %factors) {
  21.     foreach $b (keys %factors) {
  22.     push @EXPORT_OK, "${a}2$b" unless $a eq $b;
  23.     # Dynamic function generation :-)
  24.     }
  25. }
  26.  
  27. sub pack_transform {
  28.     return pack 'i', $_[0] * 65536 unless wantarray;
  29.     map  { pack 'i', $_ * 65536 } @_;
  30. }
  31.  
  32. sub unpack_transform {
  33.     return unpack ('i', $_[0]) / 65536 unless wantarray;
  34.     map  { unpack ('i', $_) / 65536 } @_;
  35. }
  36.  
  37. sub pack_transform_block {
  38.     my $input = ref $_[0] ? $_[0] : \@_;
  39.     join ('', pack_transform ((@$input)[0..3])) . pack 'i2', (@$input)[4,5]
  40. }
  41.  
  42. sub unpack_transform_block {
  43.     my $result = [];
  44.     $_[0] =~ /^(....)(....)(....)(....)(.{8})/s;
  45.     @$result = (unpack_transform ($1, $2, $3, $4), unpack 'i2', $5);
  46.     wantarray ? @$result : $result;
  47. }
  48.  
  49. sub AUTOLOAD {
  50.     my($from, $to);
  51.     ($from, $to) = $AUTOLOAD =~ /.*::(\S+)2(\S+)/;
  52.     $from = $factors{$from};
  53.     $to = $factors{$to};
  54.      
  55.     croak "Undefined subroutine $AUTOLOAD"
  56.       unless defined ($from) && defined ($to);
  57.       
  58.     return $_[0] / $to * $from unless wantarray;
  59.     map  { $_ / $to * $from } @_;
  60. }
  61. 1;
  62.  
  63. __END__
  64.  
  65. =head1 NAME
  66.  
  67. RISCOS::Units -- conversions between various S<RISC OS> screen measurement units
  68.  
  69. =head1 SYNOPSIS
  70.  
  71.     use RISCOS::Units qw(draw2inch);
  72.     $length = draw2inch ($x2 - $x1);
  73.  
  74. =head1 DESCRIPTION
  75.  
  76. This module provides conversion functions between a variety of different
  77. S<RISC OS> measures of screen length. Currently known units are
  78.  
  79. =over 4
  80.  
  81. =item draw 
  82.  
  83. draw units, as used by the C<Draw> module. 256 per OS unit, 46080 per inch.
  84.  
  85. =item inch
  86.  
  87. as used in the real world.
  88.  
  89. =item os
  90.  
  91. os units, as used by the VDU drivers. Nominally there are 180 in an inch.
  92.  
  93. =item point
  94.  
  95. points, 1/72 of an inch
  96.  
  97. =item millipoint
  98.  
  99. 1/1000th of a point, as used by the Font manager
  100.  
  101. =item user
  102.  
  103. User draw units. Currently the exchange rate is fixed at 1:1 with draw units.
  104.  
  105. =back
  106.  
  107. All conversion functions are actually created dynamically by the exporter and
  108. the C<AUTOLOAD>er, but this implementation is transparent. Just C<use> them and
  109. call them as if they were declared in full in C<EXPORT_OK> (OK, the one caveat
  110. is that you can't pass in pattern match variables such as C<$1>).
  111.  
  112. To convert from OS units to draw units just call
  113.  
  114.     $as_draw = os2draw ($as_os)
  115.  
  116. To convert a list call in list context
  117.  
  118.     ($length, $width) = draw2point @size;
  119.  
  120. =head1 DRAW TRANSFORM MATRICES
  121.  
  122. Four other functions are provided to convert the values draw transform matrices
  123. to numbers
  124.  
  125. =over 4
  126.  
  127. =item pack_transform <scale>, ...
  128.  
  129. takes a list of numbers, and converts each to a fixed point 32 bit number packed
  130. in a 4 byte scalar for use in a draw transform matrix. Returns a list of packed
  131. scalars in list context, in scalar context returns just the first scalar.
  132.  
  133. =item unpack_transform <packed_scale>, ...
  134.  
  135. takes a list of fixed point 32 bit numbers packed into separate scalars, and
  136. converts each to a number. Returns a list of numbers in list context, in scalar
  137. context returns just the first number.
  138.  
  139. =item pack_transform_block <transform_array>
  140.  
  141. packs an array of 6 values into a Draw transform block. If the first argument is
  142. an array reference it is taken as pointing to the array to use, else the
  143. argument array is packed. 
  144.  
  145. =item unpack_transform_block <transform_block>
  146.  
  147. unpacks a Draw transform block into an array of 6 values. In scalar context
  148. returns a reference to the array, in array context the array itself.
  149.  
  150. =back
  151.  
  152. =head1 BUGS
  153.  
  154. Not tested enough.
  155.  
  156. =head1 AUTHOR
  157.  
  158. Nicholas Clark <F<nick@unfortu.net>>
  159.  
  160. =cut
  161.