#!/usr/bin/perl
use strict;
use warnings;
use Cairo;
use constant
{
LINE_WIDTH => 13,
};
sub spline_path
{
my ($cr) = @_;
$cr->save;
{
$cr->translate (-106.0988385, -235.84433);
$cr->move_to (49.517857, 235.84433);
$cr->curve_to (86.544809, 175.18401,
130.19603, 301.40165,
162.67982, 240.42946);
}
$cr->restore;
}
sub source_path
{
my ($cr) = @_;
spline_path ($cr);
$cr->set_line_width (1);
$cr->stroke;
}
sub stroke
{
my ($cr) = @_;
spline_path ($cr);
$cr->set_line_width (LINE_WIDTH);
$cr->stroke;
}
sub scale_both_set_line_width_stroke
{
my ($cr) = @_;
$cr->scale (0.5, 0.5);
spline_path ($cr);
$cr->set_line_width (LINE_WIDTH);
$cr->stroke;
}
sub scale_both_set_line_width_double_stroke
{
my ($cr) = @_;
$cr->scale (0.5, 0.5);
spline_path ($cr);
$cr->set_line_width (2 * LINE_WIDTH);
$cr->stroke;
}
sub save_scale_path_restore_set_line_width_stroke
{
my ($cr) = @_;
$cr->save;
{
$cr->scale (0.5, 1.0);
spline_path ($cr);
}
$cr->restore;
$cr->set_line_width (LINE_WIDTH);
$cr->stroke;
}
# XXX: Ouch. It looks like there's an API bug in the implemented semantics for
# cairo_set_line_width. I believe the following function
# (set_line_width_scale_path_stroke_BUGGY) should result in a figure identical
# to the version above it (save_scale_path_restore_set_line_width_stroke), but
# it's currently giving the same result as the one beloe
# (scale_path_set_line_width_stroke).
sub set_line_width_scale_path_stroke_BUGGY
{
my ($cr) = @_;
$cr->set_line_width (LINE_WIDTH);
$cr->scale (0.5, 1.0);
spline_path ($cr);
$cr->stroke;
}
sub scale_path_set_line_width_stroke
{
my ($cr) = @_;
$cr->scale (0.5, 1.0);
$cr->set_line_width (LINE_WIDTH);
spline_path ($cr);
$cr->stroke;
}
{
my @pipelines = (
\&source_path,
\&stroke,
\&scale_both_set_line_width_stroke,
\&scale_both_set_line_width_double_stroke,
\&save_scale_path_restore_set_line_width_stroke,
\&scale_path_set_line_width_stroke,
);
my $width = 140;
my $height = 68.833 * scalar @pipelines;
my $surface = Cairo::ImageSurface->create ('argb32', $width, $height);
my $cr = Cairo::Context->create ($surface);
foreach (0 .. $#pipelines) {
$cr->save;
{
$cr->translate ($width/2, ($_+0.5)*($height/scalar @pipelines));
$pipelines[$_]->($cr);
}
$cr->restore;
if ($cr->status ne 'success') {
warn "Cairo is unhappy after pipeline #$_: " . $cr->status . "\n";
exit 1;
}
}
$surface->write_to_png ('spline-pipeline.png');
}