File: //usr/local/share/man/man3/Imager::Fountain.3pm
.\" Automatically generated by Pod::Man 4.11 (Pod::Simple 3.35)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Set up some character translations and predefined strings. \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
.\" nothing in troff, for use with C<>.
.tr \(*W-
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
. ds -- \(*W-
. ds PI pi
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
. ds L" ""
. ds R" ""
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds -- \|\(em\|
. ds PI \(*p
. ds L" ``
. ds R" ''
. ds C`
. ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{\
. if \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. if !\nF==2 \{\
. nr % 0
. nr F 2
. \}
. \}
.\}
.rr rF
.\" ========================================================================
.\"
.IX Title "Imager::Fountain 3"
.TH Imager::Fountain 3 "2020-06-13" "perl v5.26.3" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH "NAME"
.Vb 2
\& Imager::Fountain \- a class for building fountain fills suitable for use by
\& the fountain filter.
.Ve
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
.Vb 8
\& use Imager::Fountain;
\& my $f1 = Imager::Fountain\->read(gimp=>$filename);
\& $f\->write(gimp=>$filename);
\& my $f1 = Imager::Fountain\->new;
\& $f1\->add(start=>0, middle=>0.5, end=>1.0,
\& c0=>Imager::Color\->new(...),
\& c1=>Imager::Color\->new(...),
\& type=>$trans_type, color=>$color_trans_type);
.Ve
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
Provide an interface to build arrays suitable for use by the Imager
fountain filter. These can be loaded from or saved to a \s-1GIMP\s0 gradient
file or you can build them from scratch.
.IP "read(gimp=>$filename)" 4
.IX Item "read(gimp=>$filename)"
.PD 0
.IP "read(gimp=>$filename, name=>\e$name)" 4
.IX Item "read(gimp=>$filename, name=>$name)"
.PD
Loads a gradient from the given \s-1GIMP\s0 gradient file, and returns a
new Imager::Fountain object.
.Sp
If the name parameter is supplied as a scalar reference then any name
field from newer \s-1GIMP\s0 gradient files will be returned in it.
.Sp
.Vb 3
\& my $gradient = Imager::Fountain\->read(gimp=>\*(Aqfoo.ggr\*(Aq);
\& my $name;
\& my $gradient2 = Imager::Fountain\->read(gimp=>\*(Aqbar.ggr\*(Aq, name=>\e$name);
.Ve
.IP "write(gimp=>$filename)" 4
.IX Item "write(gimp=>$filename)"
.PD 0
.IP "write(gimp=>$filename, name=>$name)" 4
.IX Item "write(gimp=>$filename, name=>$name)"
.PD
Save the gradient to a \s-1GIMP\s0 gradient file.
.Sp
The second variant allows the gradient name to be set (for newer
versions of the \s-1GIMP\s0).
.Sp
.Vb 4
\& $gradient\->write(gimp=>\*(Aqfoo.ggr\*(Aq)
\& or die Imager\->errstr;
\& $gradient\->write(gimp=>\*(Aqbar.ggr\*(Aq, name=>\*(Aqthe bar gradient\*(Aq)
\& or die Imager\->errstr;
.Ve
.IP "new" 4
.IX Item "new"
Create an empty fountain fill description.
.IP "add(start=>$start, middle=>$middle, end=>1.0, c0=>$start_color, c1=>$end_color, type=>$trans_type, color=>$color_trans_type)" 4
.IX Item "add(start=>$start, middle=>$middle, end=>1.0, c0=>$start_color, c1=>$end_color, type=>$trans_type, color=>$color_trans_type)"
Adds a new segment to the fountain fill, the possible options are:
.RS 4
.IP "\(bu" 4
\&\f(CW\*(C`start\*(C'\fR \- the start position in the gradient where this segment takes
effect between 0 and 1. Default: 0.
.IP "\(bu" 4
\&\f(CW\*(C`middle\*(C'\fR \- the mid-point of the transition between the 2
colors, between 0 and 1. Default: average of \f(CW\*(C`start\*(C'\fR and \f(CW\*(C`end\*(C'\fR.
.IP "\(bu" 4
\&\f(CW\*(C`end\*(C'\fR \- the end of the gradient, from 0 to 1. Default: 1.
.IP "\(bu" 4
\&\f(CW\*(C`c0\*(C'\fR \- the color of the fountain fill where the fill parameter is
equal to \fIstart\fR. Default: opaque black.
.IP "\(bu" 4
\&\f(CW\*(C`c1\*(C'\fR \- the color of the fountain fill where the fill parameter is
equal to \fIend\fR. Default: opaque black.
.IP "\(bu" 4
\&\f(CW\*(C`type\*(C'\fR \- the type of segment, controls the way in which the fill parameter
moves from 0 to 1. Default: linear.
.Sp
This can take any of the following values:
.RS 4
.IP "\(bu" 4
\&\f(CW\*(C`linear\*(C'\fR
.IP "\(bu" 4
\&\f(CW\*(C`curved\*(C'\fR \- unimplemented so far.
.IP "\(bu" 4
\&\f(CW\*(C`sine\*(C'\fR
.IP "\(bu" 4
\&\f(CW\*(C`sphereup\*(C'\fR
.IP "\(bu" 4
\&\f(CW\*(C`spheredown\*(C'\fR
.RE
.RS 4
.RE
.IP "\(bu" 4
\&\f(CW\*(C`color\*(C'\fR \- the way in which the color transitions between \f(CW\*(C`c0\*(C'\fR and \f(CW\*(C`c1\*(C'\fR.
Default: direct.
.Sp
This can take any of the following values:
.RS 4
.IP "\(bu" 4
\&\f(CW\*(C`direct\*(C'\fR \- each channel is simple scaled between c0 and c1.
.IP "\(bu" 4
\&\f(CW\*(C`hueup\*(C'\fR \- the color is converted to a \s-1HSV\s0 value and the scaling is
done such that the hue increases as the fill parameter increases.
.IP "\(bu" 4
\&\f(CW\*(C`huedown\*(C'\fR \- the color is converted to a \s-1HSV\s0 value and the scaling is
done such that the hue decreases as the fill parameter increases.
.RE
.RS 4
.RE
.RE
.RS 4
.Sp
In most cases you can ignore some of the arguments, eg.
.Sp
.Vb 7
\& # assuming $f is a new Imager::Fountain in each case here
\& use Imager \*(Aq:handy\*(Aq;
\& # simple transition from red to blue
\& $f\->add(c0=>NC(\*(Aq#FF0000\*(Aq), c1=>NC(\*(Aq#0000FF\*(Aq));
\& # simple 2 stages from red to green to blue
\& $f\->add(end=>0.5, c0=>NC(\*(Aq#FF0000\*(Aq), c1=>NC(\*(Aq#00FF00\*(Aq))
\& $f\->add(start=>0.5, c0=>NC(\*(Aq#00FF00\*(Aq), c1=>NC(\*(Aq#0000FF\*(Aq));
.Ve
.RE
.IP "simple(positions=>[ ... ], colors=>[...])" 4
.IX Item "simple(positions=>[ ... ], colors=>[...])"
Creates a simple fountain fill object consisting of linear segments.
.Sp
The array references passed as positions and colors must have the same
number of elements. They must have at least 2 elements each.
.Sp
colors must contain Imager::Color or Imager::Color::Float objects.
.Sp
eg.
.Sp
.Vb 3
\& my $f = Imager::Fountain\->simple(positions=>[0, 0.2, 1.0],
\& colors=>[ NC(255,0,0), NC(0,255,0),
\& NC(0,0,255) ]);
.Ve
.SS "Implementation Functions"
.IX Subsection "Implementation Functions"
Documented for internal use.
.ie n .IP "_load_gimp_gradient($class, $fh, $name)" 4
.el .IP "_load_gimp_gradient($class, \f(CW$fh\fR, \f(CW$name\fR)" 4
.IX Item "_load_gimp_gradient($class, $fh, $name)"
Does the work of loading a \s-1GIMP\s0 gradient file.
.ie n .IP "_save_gimp_gradient($self, $fh, $name)" 4
.el .IP "_save_gimp_gradient($self, \f(CW$fh\fR, \f(CW$name\fR)" 4
.IX Item "_save_gimp_gradient($self, $fh, $name)"
Does the work of saving to a \s-1GIMP\s0 gradient file.
.SH "FILL PARAMETER"
.IX Header "FILL PARAMETER"
The \fBadd()\fR documentation mentions a fill parameter in a few places,
this is as good a place as any to discuss it.
.PP
The process of deciding the color produced by the gradient works
through the following steps:
.IP "1." 4
calculate the base value, which is typically a distance or an angle of
some sort. This can be positive or occasionally negative, depending on
the type of fill being performed (linear, radial, etc).
.IP "2." 4
clamp or convert the base value to the range 0 through 1, how this is
done depends on the repeat parameter. I'm calling this result the
fill parameter.
.IP "3." 4
the appropriate segment is found. This is currently done with a
linear search, and the first matching segment is used. If there is no
matching segment the pixel is not touched.
.IP "4." 4
the fill parameter is scaled from 0 to 1 depending on the segment type.
.IP "5." 4
the color produced, depending on the segment color type.
.SH "AUTHOR"
.IX Header "AUTHOR"
Tony Cook <tony@develop\-help.com>
.SH "SEE ALSO"
.IX Header "SEE ALSO"
\&\fBImager\fR\|(3)