home *** CD-ROM | disk | FTP | other *** search
- 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
-