home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Acorn User 10
/
AU_CD10.iso
/
Updates
/
Perl
/
Non-RPC
/
!Perl
/
riscos
/
RISCOS
/
Units.pm
< prev
next >
Wrap
Text File
|
1998-07-26
|
4KB
|
161 lines
package RISCOS::Units;
require Exporter;
use Carp;
use strict;
use vars qw (@ISA @EXPORT_OK $VERSION $AUTOLOAD %factors);
@ISA = qw(Exporter);
@EXPORT_OK = qw(pack_transform unpack_transform
pack_transform_block unpack_transform_block);
$VERSION = 0.03;
# 0.02 does Map
# 0.03 packs transform blocks
%factors = (
draw => 1, os => 256, inch => 256 * 180, user => 1,
point => 256 * 180 / 72, millipoint => 256 / 400);
my ($a, $b);
foreach $a (keys %factors) {
foreach $b (keys %factors) {
push @EXPORT_OK, "${a}2$b" unless $a eq $b;
# Dynamic function generation :-)
}
}
sub pack_transform {
return pack 'i', $_[0] * 65536 unless wantarray;
map { pack 'i', $_ * 65536 } @_;
}
sub unpack_transform {
return unpack ('i', $_[0]) / 65536 unless wantarray;
map { unpack ('i', $_) / 65536 } @_;
}
sub pack_transform_block {
my $input = ref $_[0] ? $_[0] : \@_;
join ('', pack_transform ((@$input)[0..3])) . pack 'i2', (@$input)[4,5]
}
sub unpack_transform_block {
my $result = [];
$_[0] =~ /^(....)(....)(....)(....)(.{8})/s;
@$result = (unpack_transform ($1, $2, $3, $4), unpack 'i2', $5);
wantarray ? @$result : $result;
}
sub AUTOLOAD {
my($from, $to);
($from, $to) = $AUTOLOAD =~ /.*::(\S+)2(\S+)/;
$from = $factors{$from};
$to = $factors{$to};
croak "Undefined subroutine $AUTOLOAD"
unless defined ($from) && defined ($to);
return $_[0] / $to * $from unless wantarray;
map { $_ / $to * $from } @_;
}
1;
__END__
=head1 NAME
RISCOS::Units -- conversions between various S<RISC OS> screen measurement units
=head1 SYNOPSIS
use RISCOS::Units qw(draw2inch);
$length = draw2inch ($x2 - $x1);
=head1 DESCRIPTION
This module provides conversion functions between a variety of different
S<RISC OS> measures of screen length. Currently known units are
=over 4
=item draw
draw units, as used by the C<Draw> module. 256 per OS unit, 46080 per inch.
=item inch
as used in the real world.
=item os
os units, as used by the VDU drivers. Nominally there are 180 in an inch.
=item point
points, 1/72 of an inch
=item millipoint
1/1000th of a point, as used by the Font manager
=item user
User draw units. Currently the exchange rate is fixed at 1:1 with draw units.
=back
All conversion functions are actually created dynamically by the exporter and
the C<AUTOLOAD>er, but this implementation is transparent. Just C<use> them and
call them as if they were declared in full in C<EXPORT_OK> (OK, the one caveat
is that you can't pass in pattern match variables such as C<$1>).
To convert from OS units to draw units just call
$as_draw = os2draw ($as_os)
To convert a list call in list context
($length, $width) = draw2point @size;
=head1 DRAW TRANSFORM MATRICES
Four other functions are provided to convert the values draw transform matrices
to numbers
=over 4
=item pack_transform <scale>, ...
takes a list of numbers, and converts each to a fixed point 32 bit number packed
in a 4 byte scalar for use in a draw transform matrix. Returns a list of packed
scalars in list context, in scalar context returns just the first scalar.
=item unpack_transform <packed_scale>, ...
takes a list of fixed point 32 bit numbers packed into separate scalars, and
converts each to a number. Returns a list of numbers in list context, in scalar
context returns just the first number.
=item pack_transform_block <transform_array>
packs an array of 6 values into a Draw transform block. If the first argument is
an array reference it is taken as pointing to the array to use, else the
argument array is packed.
=item unpack_transform_block <transform_block>
unpacks a Draw transform block into an array of 6 values. In scalar context
returns a reference to the array, in array context the array itself.
=back
=head1 BUGS
Not tested enough.
=head1 AUTHOR
Nicholas Clark <F<nick@unfortu.net>>
=cut