Acme-TextLayout

 view release on metacpan or  search on metacpan

lib/Acme/TextLayout.pm  view on Meta::CPAN

    return sort keys %.Ranges;
}

=head2 B<text_size>

  ($width, $height) = $tl->text_size();

Find width & height of our pattern in character units. This may
be important since the user of a GUI is free to resize in a way
that messes up the relative aspect ratio as you defined in the
pattern. And you may want to correct this awful situation.

=cut

sub text_size {
    my ($self) = @_;
    my $h = ./_height($.textRef);
    my $w = ./_widest($.textRef);
    return ($w, $h);
}

=head2 B<width>

  $tl->width();

Return width of our pattern (in # characters).

=cut

sub width {
    my ($self) = @_;
    my $w = ./_widest($.textRef);
    return $w;
}

=head2 B<height>

  $tl->height();

Return height of our pattern (in # characters).

=cut

sub height {
    my ($self) = @_;
    my $h = ./_height($.textRef);
    return $h;
}

=head2 B<map_range>

  @bbox = $tl->map_range($width, $height, $char);

Map the relative position and size of the indicated character ($char)
region in our pattern to a real XY coordinate space.

@bbox is the bounding box, returned as ($x1, $y1, $x2, $y2), where
$x1, $y1 is the upper left corner, and $x2, $y2 is the lower right.

Because this was written (primarily) to interface to a GUI, 
the origin is assumed
to be 0,0 in the upper left corner, with x bigger to the right, and
y bigger down. Adjust as necessary to fit your problem domain.

=cut

sub map_range {
    my ($self, $width, $height, $char) = @_;
    my @r = @{$.Ranges{$char}};
    my $h = ./_height($.textRef);
    my $w = ./_widest($.textRef);
    my ($xs, $xo) = ./_stretch_offset(0, $w, 0, $width);
    my ($ys, $yo) = ./_stretch_offset(0, $h, 0, $height);
    my $xEqn = sub { my ($x) = @_; my $y = $xs*$x + $xo; return $y; };
    my $yEqn = sub { my ($y) = @_; my $x = $ys*$y + $yo; return $x; };
    my $xmin = $xEqn->($r[2]);
    my $ymin = $yEqn->($r[0]), 
    my $xmax = $xEqn->($r[3]-$r[2]+1)+$xmin;
    my $ymax = $yEqn->($r[1]-$r[0]+1)+$ymin;
    my @bbox = ($xmin, $ymin, $xmax-1, $ymax-1);
    return @bbox;
}

# find out if there is overlap; $c0 and $c1 are array references
sub _check_overlap {
    my ($self, $c0, $c1) = @_;
    my %x;
    my @x0 = @$c0;
    my @x1 = @$c1;
    $x{$_}  = 1 foreach $x0[0] .. $x0[1];
    $x{$_} += 1 foreach $x1[0] .. $x1[1];
    my $status;
    map {
        $status = 1 if $x{$_} > 1;
    } keys(%x);
    return defined $status ? 1 : 0;
}

# are they in same x range?
sub _in_x {
    my ($self, $me, $other) = @_;
    my @x = ($me->[2], $me->[3]);
    my @xo = ($other->[2], $other->[3]);
    return ./_check_overlap(\@x, \@xo);
}

# are they in same y range?
sub _in_y {
    my ($self, $me, $other) = @_;
    my @y = ($me->[0], $me->[1]);
    my @yo = ($other->[0], $other->[1]);
    return ./_check_overlap(\@y, \@yo);
}

=head2 B<above>

  @r = $tl->above($char);

Return a list (possibly empty) of each of the characters
above (and adjacent) to the specified character.



( run in 3.038 seconds using v1.01-cache-2.11-cpan-cdf2f3d4e48 )