On 24/05/07, George <[EMAIL PROTECTED]> wrote:
i am trying to draw a polygon , in the code below wich is adapted from the
Draw.pl demo in the win32-Gui package, the program run successfully if we
uncomment the line :
$DC->Rectangle(100, 100, 300, 200);
and comment the line:
 $DC->Polygon(10, 10, 10, 200, 200, 200, 10, 10);
but if we uncomment the $DC->Polygon(10, 10, 10, 200, 200, 200, 10, 10);
and comment the  $DC->Rectangle(100, 100, 300, 200);
the program will crash.
can someone tell me how to draw the polygon

A quick look at the code shows that Polygon(),  PolyBezier(),
PolyBezierTo(), PolyLine(), and PolyLineTo() all suffer from array
indexing problems, which is causing the allocated memory to overrun.
I'll fix this in the next release.  In the meantime, here one way to
write a replacement function to perform (almost) the same
functionality as Polygon().

Thanks for the report.
Rob.

#!perl -w
use strict;
use warnings;

use Win32::GUI qw();

my $mw = Win32::GUI::Window->new(
        -title => 'Polygon',
        -size  => [ 400, 300 ],
        -onPaint => \&paint,
);

$mw->Show();
Win32::GUI::Dialog();
$mw->Hide();
exit(0);

sub paint {
        my ($self, $dc) = @_;

        # Must always validate the DC during a paint handler
        $dc->Validate();

        # Draw a rectangle
        $dc->Rectangle(10,10,100,100);

        # Draw a polygon - Win32::GUI::DC::Polygon is broken in v1.05
        # $dc->Polygon( (110, 110), (115, 200), (300, 150), (150, 150), (200, 
50), );
        _polygon($dc, (110, 110), (115, 200), (300, 150), (150, 150), (200, 
50), );

        return 0;
}

# Perl implementation of Win32::GUI::DC::Polygon(), this will be slow
# in comparison, but probably not noticable unless you have many
# polygons, or a polygon with many points.
sub _polygon {
        my ($dc, @points) = @_;

        die unless (@points % 2 == 0); # each point is 2 entries in array
        die unless @points > 2;    # must be at least 1 points

        # TODO record original position, so we can restore
        # it at the end - Win32::GUI::DC is missing GetCurrentPositionEx()
        # my ($orig_x, $orig_y) = $dc->GetCurrentPositionEx();
        
        # Using a path gets us the correct line joins, as opposed
        # to line ends
        $dc->BeginPath();

        my $i = 0;

        # Move to the starting point
        $dc->MoveTo(@points[$i++, $i++]);

        # Draw the path to each vertex
        while ( $i < @points ) {
                $dc->LineTo(@points[$i++, $i++]);
        }

        # Select the path into the DC
        $dc->EndPath();

        # Stroke and fill the path; closes the figure for us
        $dc->StrokeAndFillPath();

        # TODO restore the current position to where it was originally
        # $dc->MoveTo($orig_x, $orig_y);
        
        return 1;
}

Reply via email to