the top level "aa" style. Each text style depends on text.aa, each
line style depends on lineaa.
add _line_style() to populate a hash similar in concept to that used
by by _text_style(), so we can easily support pens and thick lines
from future Imager
(
back=> 'lookup(bg)',
line=> 'lookup(fg)',
(
back=> 'lookup(bg)',
line=> 'lookup(fg)',
text=>{
color => 'lookup(fg)',
font => 'lookup(font)',
size => 14,
text=>{
color => 'lookup(fg)',
font => 'lookup(font)',
size => 14,
},
title=>{
color => 'lookup(text.color)',
},
title=>{
color => 'lookup(text.color)',
halign => 'center',
valign => 'top',
size => 'scale(text.size,2.0)',
halign => 'center',
valign => 'top',
size => 'scale(text.size,2.0)',
+ aa => 'lookup(text.aa)',
},
legend =>{
color => 'lookup(text.color)',
font => 'lookup(text.font)',
},
legend =>{
color => 'lookup(text.color)',
font => 'lookup(text.font)',
+ aa => 'lookup(text.aa)',
size => 'lookup(text.size)',
patchsize => 'scale(legend.size,0.9)',
patchgap => 'scale(legend.patchsize,0.3)',
size => 'lookup(text.size)',
patchsize => 'scale(legend.size,0.9)',
patchgap => 'scale(legend.patchsize,0.3)',
outside => 'lookup(callout.size)',
leadlen => 'scale(0.8,callout.size)',
gap => 'scale(callout.size,0.3)',
outside => 'lookup(callout.size)',
leadlen => 'scale(0.8,callout.size)',
gap => 'scale(callout.size,0.3)',
+ aa => 'lookup(text.aa)',
+ lineaa => 'lookup(lineaa)',
},
label => {
font => 'lookup(text.font)',
},
label => {
font => 'lookup(text.font)',
pad => 'scale(label.size,0.2)',
pcformat => sub { sprintf "%s (%.0f%%)", $_[0], $_[1] },
pconlyformat => sub { sprintf "%.1f%%", $_[0] },
pad => 'scale(label.size,0.2)',
pcformat => sub { sprintf "%s (%.0f%%)", $_[0], $_[1] },
pconlyformat => sub { sprintf "%.1f%%", $_[0] },
+ aa => 'lookup(text.aa)',
+ lineaa => 'lookup(lineaa)',
},
dropshadow => {
fill => { solid => Imager::Color->new(0, 0, 0, 96) },
},
dropshadow => {
fill => { solid => Imager::Color->new(0, 0, 0, 96) },
},
outline => {
line =>'lookup(line)',
},
outline => {
line =>'lookup(line)',
+ lineaa => 'lookup(lineaa)',
},
size=>256,
width=>'scale(1.5,size)',
height=>'lookup(size)',
},
size=>256,
width=>'scale(1.5,size)',
height=>'lookup(size)',
+
+ # yes, the handling of fill and line AA is inconsistent, lack of
+ # forethought, unfortunately
+ fill => {
+ aa => 'lookup(aa)',
+ },
+ lineaa => 'lookup(aa)',
);
=item _error($message)
);
=item _error($message)
Returns an empty list on failure.
Returns an empty list on failure.
+Returns the following attributes: font, color, size, aa, sizew
+(optionally)
+
$work{size} = $self->_get_number("$name.size");
$work{sizew} = $self->_get_number("$name.sizew")
if $work{sizew};
$work{size} = $self->_get_number("$name.size");
$work{sizew} = $self->_get_number("$name.sizew")
if $work{sizew};
+ $work{aa} = $self->_get_number("$name.aa");
+=item _line_style($name)
+
+Return parameters suitable for calls to Imager's line(), polyline(),
+and box() methods.
+
+For now this returns only color and aa parameters, but future releases
+of Imager may support extra parameters.
+
+=cut
+
+sub _line_style {
+ my ($self, $name) = @_;
+
+ my %line;
+ $line{color} = $self->_get_color("$name.line")
+ or return;
+ $line{aa} = $self->_get_number("$name.lineaa");
+ defined $line{aa} or $line{aa} = $self->_get_number("aa");
+
+ return %line;
+}
+
sub _align_box {
my ($self, $box, $chart_box, $name) = @_;
sub _align_box {
my ($self, $box, $chart_box, $name) = @_;
}
my @fill_box = ( $cx-$radius, $cy-$radius, $cx+$radius, $cy+$radius );
}
my @fill_box = ( $cx-$radius, $cy-$radius, $cx+$radius, $cy+$radius );
+ my $fill_aa = $self->_get_number('fill.aa');
for my $item (@info) {
$item->{begin} < $item->{end}
or next;
my @fill = $self->_data_fill($item->{index}, \@fill_box)
or return;
for my $item (@info) {
$item->{begin} < $item->{end}
or next;
my @fill = $self->_data_fill($item->{index}, \@fill_box)
or return;
- $img->arc(x=>$cx, 'y'=>$cy, r=>$radius, aa => 1,
+ $img->arc(x=>$cx, 'y'=>$cy, r=>$radius, aa => $fill_aa,
d1=>180/PI * $item->{begin}, d2=>180/PI * $item->{end},
@fill);
}
if ($style->{features}{outline}) {
d1=>180/PI * $item->{begin}, d2=>180/PI * $item->{end},
@fill);
}
if ($style->{features}{outline}) {
- my $outcolor = $self->_get_color('outline.line');
+ my %outstyle = $self->_line_style('outline');
+ my $out_radius = 0.5 + $radius;
- my $px = int($cx + $radius * cos($item->{begin}));
- my $py = int($cy + $radius * sin($item->{begin}));
+ my $px = int($cx + $out_radius * cos($item->{begin}));
+ my $py = int($cy + $out_radius * sin($item->{begin}));
$item->{begin} < $item->{end}
or next;
$item->{begin} < $item->{end}
or next;
- $img->line(x1=>$cx, y1=>$cy, x2=>$px, y2=>$py, color=>$outcolor);
+ $img->line(x1=>$cx, y1=>$cy, x2=>$px, y2=>$py, %outstyle);
for (my $i = $item->{begin}; $i < $item->{end}; $i += PI/180) {
my $stroke_end = $i + PI/180;
$stroke_end = $item->{end} if $stroke_end > $item->{end};
for (my $i = $item->{begin}; $i < $item->{end}; $i += PI/180) {
my $stroke_end = $i + PI/180;
$stroke_end = $item->{end} if $stroke_end > $item->{end};
- my $nx = int($cx + $radius * cos($stroke_end));
- my $ny = int($cy + $radius * sin($stroke_end));
- $img->line(x1=>$px, y1=>$py, x2=>$nx, y2=>$ny, color=>$outcolor,
- antialias=>1);
+ my $nx = int($cx + $out_radius * cos($stroke_end));
+ my $ny = int($cy + $out_radius * sin($stroke_end));
+ $img->line(x1=>$px, y1=>$py, x2=>$nx, y2=>$ny, %outstyle);
($px, $py) = ($nx, $ny);
}
}
($px, $py) = ($nx, $ny);
}
}
$callout_outside += $radius;
my %callout_text;
my %label_text;
$callout_outside += $radius;
my %callout_text;
my %label_text;
+ my %callout_line;
+ my $leader_aa = $self->_get_number('callout.leadaa');
for my $label (@info) {
if ($label->{label} && !$label->{callout}) {
# at this point we know we need the label font, to calculate
for my $label (@info) {
if ($label->{label} && !$label->{callout}) {
# at this point we know we need the label font, to calculate
# color=>Imager::Color->new(0,0,0));
$img->string(%label_text, x=>$tcx-$label->{lbox}[2]/2,
'y'=>$tcy+$label->{lbox}[3]/2+$label->{lbox}[1],
# color=>Imager::Color->new(0,0,0));
$img->string(%label_text, x=>$tcx-$label->{lbox}[2]/2,
'y'=>$tcy+$label->{lbox}[3]/2+$label->{lbox}[1],
- text=>$label->{text}, aa => 1);
}
else {
$label->{callout} = 1;
}
else {
$label->{callout} = 1;
unless (%callout_text) {
%callout_text = $self->_text_style('callout')
or return;
unless (%callout_text) {
%callout_text = $self->_text_style('callout')
or return;
+ %callout_line = $self->_line_style('callout');
}
my $ix = floor(0.5 + $cx + $callout_inside * cos($label->{cangle}));
my $iy = floor(0.5 + $cy + $callout_inside * sin($label->{cangle}));
my $ox = floor(0.5 + $cx + $callout_outside * cos($label->{cangle}));
my $oy = floor(0.5 + $cy + $callout_outside * sin($label->{cangle}));
my $lx = ($ox < $cx) ? $ox - $callout_leadlen : $ox + $callout_leadlen;
}
my $ix = floor(0.5 + $cx + $callout_inside * cos($label->{cangle}));
my $iy = floor(0.5 + $cy + $callout_inside * sin($label->{cangle}));
my $ox = floor(0.5 + $cx + $callout_outside * cos($label->{cangle}));
my $oy = floor(0.5 + $cy + $callout_outside * sin($label->{cangle}));
my $lx = ($ox < $cx) ? $ox - $callout_leadlen : $ox + $callout_leadlen;
- $img->line(x1=>$ix, y1=>$iy, x2=>$ox, y2=>$oy, antialias=>1,
- color=>$self->_get_color('callout.color'));
- $img->line(x1=>$ox, y1=>$oy, x2=>$lx, y2=>$oy, antialias=>1,
- color=>$self->_get_color('callout.color'));
+ $img->polyline(points => [ [ $ix, $iy ],
+ [ $ox, $oy ],
+ [ $lx, $oy ] ],
+ %callout_line);
#my $tx = $lx + $callout_gap;
my $ty = $oy + $label->{cbox}[3]/2+$label->{cbox}[1];
if ($lx < $cx) {
$img->string(%callout_text, x=>$lx-$callout_gap-$label->{cbox}[2],
#my $tx = $lx + $callout_gap;
my $ty = $oy + $label->{cbox}[3]/2+$label->{cbox}[1];
if ($lx < $cx) {
$img->string(%callout_text, x=>$lx-$callout_gap-$label->{cbox}[2],
- 'y'=>$ty, text=>$label->{text}, aa=>1);
+ 'y'=>$ty, text=>$label->{text});
}
else {
$img->string(%callout_text, x=>$lx+$callout_gap, 'y'=>$ty,
}
else {
$img->string(%callout_text, x=>$lx+$callout_gap, 'y'=>$ty,
- text=>$label->{text}, aa=>1);
my $col_width = int($size / $column_count) -1;
my $graph_width = $col_width * $column_count + 1;
my $col_width = int($size / $column_count) -1;
my $graph_width = $col_width * $column_count + 1;
+ my $line_aa = $self->_get_number("lineaa");
foreach my $series (@$line_series) {
my @data = @{$series->{'data'}};
my $data_size = scalar @data;
foreach my $series (@$line_series) {
my @data = @{$series->{'data'}};
my $data_size = scalar @data;
my $y2 = $bottom + ($value_range - $data[$i + 1] + $min_value)/$value_range * $size;
push @marker_positions, [$x1, $y1];
my $y2 = $bottom + ($value_range - $data[$i + 1] + $min_value)/$value_range * $size;
push @marker_positions, [$x1, $y1];
- $img->line(x1 => $x1, y1 => $y1, x2 => $x2, y2 => $y2, aa => 1, color => $color) || die $img->errstr;
+ $img->line(x1 => $x1, y1 => $y1, x2 => $x2, y2 => $y2, aa => $line_aa, color => $color) || die $img->errstr;
}
my $x2 = $left + ($data_size - 1) * $interval;
}
my $x2 = $left + ($data_size - 1) * $interval;
my $type = $style->{'shape'};
my $radius = $style->{'radius'};
my $type = $style->{'shape'};
my $radius = $style->{'radius'};
+ my $line_aa = $self->_get_number("lineaa");
+ my $fill_aa = $self->_get_number("fill.aa");
if ($type eq 'circle') {
my @fill = $self->_data_fill($series_counter, [$x1 - $radius, $y1 - $radius, $x1 + $radius, $y1 + $radius]);
if ($type eq 'circle') {
my @fill = $self->_data_fill($series_counter, [$x1 - $radius, $y1 - $radius, $x1 + $radius, $y1 + $radius]);
- $img->circle(x => $x1, y => $y1, r => $radius, aa => 1, filled => 1, @fill);
+ $img->circle(x => $x1, y => $y1, r => $radius, aa => $fill_aa, filled => 1, @fill);
}
elsif ($type eq 'square') {
my @fill = $self->_data_fill($series_counter, [$x1 - $radius, $y1 - $radius, $x1 + $radius, $y1 + $radius]);
}
elsif ($type eq 'square') {
my @fill = $self->_data_fill($series_counter, [$x1 - $radius, $y1 - $radius, $x1 + $radius, $y1 + $radius]);
[$x1 + $radius, $y1],
[$x1, $y1 - $radius],
],
[$x1 + $radius, $y1],
[$x1, $y1 - $radius],
],
- filled => 1, color => $color, aa => 1);
+ filled => 1, color => $color, aa => $fill_aa);
}
elsif ($type eq 'triangle') {
# The gradient really doesn't work for triangle
}
elsif ($type eq 'triangle') {
# The gradient really doesn't work for triangle
[$x1 + $radius, $y1 + $radius],
[$x1, $y1 - $radius],
],
[$x1 + $radius, $y1 + $radius],
[$x1, $y1 - $radius],
],
- filled => 1, color => $color, aa => 1);
+ filled => 1, color => $color, aa => $fill_aa);
}
elsif ($type eq 'x') {
my $color = $self->_data_color($series_counter);
}
elsif ($type eq 'x') {
my $color = $self->_data_color($series_counter);
- $img->line(x1 => $x1 - $radius, y1 => $y1 -$radius, x2 => $x1 + $radius, y2 => $y1+$radius, aa => 1, color => $color) || die $img->errstr;
- $img->line(x1 => $x1 + $radius, y1 => $y1 -$radius, x2 => $x1 - $radius, y2 => $y1+$radius, aa => 1, color => $color) || die $img->errstr;
+ $img->line(x1 => $x1 - $radius, y1 => $y1 -$radius, x2 => $x1 + $radius, y2 => $y1+$radius, aa => $line_aa, color => $color) || die $img->errstr;
+ $img->line(x1 => $x1 + $radius, y1 => $y1 -$radius, x2 => $x1 - $radius, y2 => $y1+$radius, aa => $line_aa, color => $color) || die $img->errstr;
}
elsif ($type eq 'plus') {
my $color = $self->_data_color($series_counter);
}
elsif ($type eq 'plus') {
my $color = $self->_data_color($series_counter);
- $img->line(x1 => $x1, y1 => $y1 -$radius, x2 => $x1, y2 => $y1+$radius, aa => 1, color => $color) || die $img->errstr;
- $img->line(x1 => $x1 + $radius, y1 => $y1, x2 => $x1 - $radius, y2 => $y1, aa => 1, color => $color) || die $img->errstr;
+ $img->line(x1 => $x1, y1 => $y1 -$radius, x2 => $x1, y2 => $y1+$radius, aa => $line_aa, color => $color) || die $img->errstr;
+ $img->line(x1 => $x1 + $radius, y1 => $y1, x2 => $x1 - $radius, y2 => $y1, aa => $line_aa, color => $color) || die $img->errstr;