Graphics-Framebuffer

 view release on metacpan or  search on metacpan

src/Framebuffer.pm  view on Meta::CPAN

                    $self->plot({ 'x' => $start_x, 'y' => $start_y });
                    $start_x--;
                    $start_y--;
                }
            } ## end elsif (($start_x > $x_end...))

        } ## end else [ if (($x_end == $start_x...))]
    } ## end else [ if ($self->{'ACCELERATED'...})]
    $self->{'X'} = $XX;
    $self->{'Y'} = $YY;
} ## end sub drawto

sub _flush_screen {
    # Since the framebuffer is mappeed as a string device, Perl buffers the output, and this must be flushed.
    my $self = shift;

	if ($self->{'DEVICE'} eq 'EMULATED') {
		select(STDERR);
		$| = 1;
	} elsif (defined($self->{'FB'})) {
		select($self->{'FB'});
		$| = 1;
		$self->{'FB'}->flush();
		eval {sync $self->{'SCREEN'}, TRUE;};
		$self->vsync();
	}
	$self->{'LAST_FLUSHED'} = time;
} ## end sub _flush_screen

sub _adj_plot {
    # Part of antialiased drawing
    my ($self, $x, $y, $c, $s) = @_;

    $self->set_color({ 'red' => $s->{'red'} * $c, 'green' => $s->{'green'} * $c, 'blue' => $s->{'blue'} * $c });
    $self->plot({ 'x' => $x, 'y' => $y });
} ## end sub _adj_plot

sub _draw_line_antialiased {
    my ($self, $x0, $y0, $x1, $y1) = @_;

    my $saved = { %{ $self->{'SET_RAW_FOREGROUND_COLOR'} } };

    my $plot = \&_adj_plot;

    if (abs($y1 - $y0) > abs($x1 - $x0)) {
        $plot = sub { _adj_plot(@_[0, 2, 1, 3, 4]) };
        ($x0, $y0, $x1, $y1) = ($y0, $x0, $y1, $x1);
    }

    if ($x0 > $x1) {
        ($x0, $x1, $y0, $y1) = ($x1, $x0, $y1, $y0);
    }

    my $dx       = $x1 - $x0;
    my $dy       = $y1 - $y0;
    my $gradient = $dy / $dx;

    my @xends;
    my $intery;

    # handle the endpoints
    foreach my $xy ([$x0, $y0], [$x1, $y1]) {
        my ($x, $y) = @{$xy};
        my $xend = int($x + 0.5);                   # POSIX::lround($x);
        my $yend = $y + $gradient * ($xend - $x);
        my $xgap = _rfpart($x + 0.5);

        my $x_pixel = $xend;
        my $y_pixel = int($yend);
        push(@xends, $x_pixel);

        $plot->($self, $x_pixel, $y_pixel,     _rfpart($yend) * $xgap, $saved);
        $plot->($self, $x_pixel, $y_pixel + 1, _fpart($yend) * $xgap,  $saved);
        next if (defined($intery));

        # first y-intersection for the main loop
        $intery = $yend + $gradient;
    } ## end foreach my $xy ([$x0, $y0],...)

    # main loop

    foreach my $x ($xends[0] + 1 .. $xends[1] - 1) {
        $plot->($self, $x, int($intery),     _rfpart($intery), $saved);
        $plot->($self, $x, int($intery) + 1, _fpart($intery),  $saved);
        $intery += $gradient;
    }
    $self->set_color($saved);
} ## end sub _draw_line_antialiased

=head2 bezier

Draws a Bezier curve, based on a list of control points.

=over 4

 $fb->bezier(
     {
         'coordinates' => [
             x0,y0,
             x1,y1,
             ...              # As many as needed, there MUST be an even number of elements
         ],
         'points'     => 100, # Number of total points plotted for curve
                              # The higher the number, the smoother the curve.
         'closed'     => 1,   # optional, close it and make it a full shape.
         'filled'     => 1    # Results may vary, optional
         'gradient' => {
              'direction' => 'horizontal', # or vertical
              'colors'    => { # 2 to any number of transitions allowed
                  'red'   => [255,255,0], # Red to yellow to cyan
                  'green' => [0,255,255],
                  'blue'  => [0,0,255]
              }
          }
     }
 );

=back

* This is not affected by the Acceleration setting



( run in 1.141 second using v1.01-cache-2.11-cpan-524268b4103 )