







=encoding UTF-8

=head1 NAME

Image::CairoSVG - Render SVG into a Cairo surface

=head1 SYNOPSIS

This example converts an SVG file into PNG:

    
    use FindBin '$Bin';
    use Cairo;
    use Image::CairoSVG;
    my $cairosvg = Image::CairoSVG->new ();
    my $surface = $cairosvg->render ("$Bin/locust.svg");
    $surface->write_to_png ("$Bin/locust.png");


=begin html 

<p>
This renders the following image:
</p>

<img width="451.271" height="187.542"
 src='https://fastapi.metacpan.org/source/BKB/Image-CairoSVG-0.21/examples/locust.png'>

=end html

(This example is included as
L<F<synopsis.pl>|https://fastapi.metacpan.org/source/BKB/Image-CairoSVG-0.21/examples/synopsis.pl> in the distribution. The
L<input|https://fastapi.metacpan.org/source/BKB/Image-CairoSVG-0.21/examples/locust.svg> and L<output
files|https://fastapi.metacpan.org/source/BKB/Image-CairoSVG-0.21/examples/locust.png> are also included.)

=head1 VERSION

This documents Image::CairoSVG version 0.21
corresponding to git commit L<c42b33aba018e51fe57e6efd943267e763cef7bb|https://github.com/benkasminbullock/image-cairosvg/commit/c42b33aba018e51fe57e6efd943267e763cef7bb> released on Mon May 17 10:35:33 2021 +0900. 

=head1 DESCRIPTION

This module renders SVG ("Scalable Vector Graphics") instructions into
a Cairo surface. The user can then choose what to do with the surface,
for example write it out to a PNG file.

=head1 METHODS

=head2 new

    my $cairosvg = Image::CairoSVG->new (%arguments);

Arguments are as follows

=over

=item surface

The user can supply a Cairo surface:

    my $cairosvg = Image::CairoSVG->new (surface => $surface);

For example,

    my $cairosvg = Image::CairoSVG->new (
        surface => Cairo::ImageSurface->create ('argb32', 100, 100)
    );

=item context

The user can also supply a Cairo context:

    my $cairosvg = Image::CairoSVG->new (context => $cr);

If a Cairo context and a surface are both supplied, the value of
C<surface> is ignored, a warning is printed, and the image is drawn
using only the C<context> value.

=back

For simple drawing tasks, we recommend using the default surface
generated by this module, which is the return value from
L</render>. Only supply a surface if the module gets the dimensions of
your image wrong. Only use a Cairo context if you want to include the
image in some other image or rescale it. See L</Scaling the output>
for an example.

=head2 render

    my $surface = $cairosvg->render ('some.svg');

Draw an SVG file or scalar into a Cairo surface. The return value is
the surface drawn into. If the call value is a scalar containing what
looks like XML, it is parsed from the scalar instead. This method
guesses whether its argument is a file or a scalar by looking for a
pair of angle brackets (<>) in its first argument. If it does not find
angle brackets, it assumes the argument is a file name.

If the user did not supply a context or a surface to L</new>, a new
Cairo::ImageSurface object is generated. If the user supplies a
context argument with L</new>, the return value of render should be
ignored. If the user supplied a surface with L</new>, the return value
is just that surface.

If the user does not specify a surface, the generated surface returned
by C<render> is based on the attributes of the <svg> element,
specifically either the C<width> and C<height> attributes, or the
width and height specified in the C<viewBox> attribute.

Calling with a scalar containing XML was added in version 0.08.

=head1 EXAMPLES

=head2 Scaling the output

This example shows how to scale the output image using Cairo commands.

    
    use FindBin '$Bin';
    use Cairo;
    use Image::CairoSVG;
    # Using defaults
    my $dcairosvg = Image::CairoSVG->new ();
    my $dsurface = $dcairosvg->render ("$Bin/urn.svg");
    $dsurface->write_to_png ("$Bin/durn.png");
    # Scale to 200 pixels
    my $size = 200;
    my $twsize = 36;
    my $surface = Cairo::ImageSurface->create ('argb32', $size, $size);
    my $context = Cairo::Context->create ($surface);
    my $cairosvg = Image::CairoSVG->new (context => $context);
    $context->scale ($size/$twsize, $size/$twsize);
    $cairosvg->render ("$Bin/urn.svg");
    $surface->write_to_png ("$Bin/urn.png");


=begin html 

<p>
The default size looks like this:
</p>
<img width="36" height="36" src='https://fastapi.metacpan.org/source/BKB/Image-CairoSVG-0.21/examples/durn.png'>
<p>
The scaled image looks like this:
</p>
<img width="200" height="200" src='https://fastapi.metacpan.org/source/BKB/Image-CairoSVG-0.21/examples/urn.png'>

=end html

(This example is included as L<F<scale.pl>|https://fastapi.metacpan.org/source/BKB/Image-CairoSVG-0.21/examples/scale.pl> in the
distribution. The original image is part of the L<Twitter Emoji
collection|https://twemoji.twitter.com/>, F<1f3fa.svg>, representing
C<U+1F3FA AMPHORA>. This illustration is used under the terms of
L<CC-BY 4.0|https://creativecommons.org/licenses/by/4.0/>)

=head1 DRAWING METHODS

The drawing methods of the module are as follows.

=head2 circle

    $cairosvg->circle (%attr);

Draw the circle specified by the SVG attributes in C<%attr> into the
surface of C<$cairosvg>.

=head2 ellipse

    $cairosvg->ellipse (%attr);

Draw the ellipse specified by the SVG attributes in C<%attr> into the
surface of C<$cairosvg>.

=head2 line

    $cairosvg->line (%attr);

Render the line specified by the SVG attributes in C<%attr> into the
surface specified by C<$cairosvg>.  Given SVG input of the form C<<
<line > >>, this renders it onto the Cairo surface.

=head2 path

    $cairosvg->path (%attr);

Given an SVG path element, send its attribute key / value pairs as
C<%attr> to render into the Cairo surface of C<$cairosvg>. This uses
L<Image::SVG::Path> to parse the "d" attibute of the path. 

This converts any quadratic bezier curves found in the path into cubic
bezier curves, since Cairo does not support quadratic bezier curves.

=head2 polygon

    $cairosvg->polygon (%attr);

Draw the polygon specified by the C<points> attribute of C<%attr>,
closing the path.

=head2 polyline

    $cairosvg->polyline (%attr);

Similar to L</polygon> except that it doesn't close the path.

=head2 processUse

    $cairosvg->processUse (%attr);

Process a <use> SVG element. It relies on C<$cairosvg> already having
processed the XML file in order to find the used element.

=head2 rect

    $cairosvg->rect (%attr);

Draw the rectangle specified by C<%attr> into the surface contained in
C<$cairosvg>.

If the rectangle has rounded corners (a non-zero C<rx> attribute), a
shim function is used to draw the rectangle, since Cairo has no native
support for rectangles with rounded corners.

=head1 DEPENDENCIES

This module depends on the following other modules.

=over

=item L<Cairo>

Cairo is used for rendering the image.

=item L<Carp>

Carp is used for reporting errors.

=item L<Image::SVG::Path>

Image::SVG::Path is used for parsing the "path" information of the
SVG, see L</path>.

=item L<Math::Trig>

This is used for the value of C<pi>, and for various functions related
to drawing arcs, and for converting angles between radians (used by
Cairo) and degrees (used by SVG).

=item L<XML::Parser>

XML::Parser is used for parsing SVG files.

=back

=head1 SEE ALSO

=head2 Demonstration website and blog articles

L<This demonstration
website|https://benkasminbullock.github.io/supertinyiconscairosvg/>
shows the output of Image::CairoSVG on the Super Tiny Icons collection
and the L<Twitter Emoji
Collection|https://benkasminbullock.github.io/supertinyiconscairosvg/twemoji/>.

Please see L</BUGS> below for notable errors in the rendering.

=head3 Blog articles

I've written some blog articles about extending the SVG support in
this module.

=over

=item L<Trying to get SVG right|https://benbullock.substack.com/p/trying-to-get-svg-right>

This was the first article, where I had discovered that the module's
arc-drawing code and arc-parsing code was not working.

=item L<Improvements to Image::CairoSVG|https://benbullock.substack.com/p/improvements-to-imagecairosvg>

This illustrates some of the improvements made up to version 0.16,
such as addition of opacity, support for the <use> tag, and more
correct drawing of circular arcs.

=item L<SVG matrix and miter limit|https://benbullock.substack.com/p/svg-matrix-and-miter-limit>

This documents visually the rendering improvements between version
0.17 and version 0.18.

=back

=head2 Other software

=over

=item CairoSVG

L<CairoSVG|http://cairosvg.org/> is a Python SVG renderer in
Cairo. The elliptical arc drawing part of Image::CairoSVG is a
translation of its code into Perl.

=back

=head2 Other CPAN modules related to SVG

=over

=item L<Image::LibRSVG>

Perl extension for a Gnome library called librsvg which converts SVG
to PNG or JPEG, etc. We have not tested this library.

=item L<Image::Magick>

Does SVG to PNG conversion.

=item L<Image::SVG::Path>

This is a specialised module for reading the "d" attribute of SVG
paths.

=item L<Image::SVG::Transform>

Read the "transform" attribute of an SVG element.

=item L<MarpaX::Languages::SVG::Parser>

This extends the L<Marpa::R2> parser to parse SVG.

=item L<SVG>

This is for generating SVG documents.

=item L<SVG::Parser>

Parse the XML for SVG files. It can use either L<XML::Parser> or
L<XML::SAX> but XML::Parser seems not to work. See
L<https://rt.cpan.org/Ticket/Display.html?id=136404>.

=item L<SVG::Rasterize>

Rasterize SVG content to pixel graphics. We couldn't get this to
produce output. See
L<https://rt.cpan.org/Ticket/Display.html?id=136405>.

=back

=head2 More information

=over

=item Perl Maven article

L<SVG - Scalable Vector Graphics with
Perl|http://perlmaven.com/scalable-vector-graphics-with-perl> -
article at Perl Maven

=item Perl Cairo tutorial

The Cairo CPAN module is mostly undocumented. This L<Perl Cairo
tutorial|https://www.lemoda.net/cairo/cairo-tutorial/index.html> may
be useful if you need to go beyond defaults.

=back

=head1 BUGS

Various parts of the SVG standard are not implemented, as follows.

If viewing the HTML version of this page, the illustrations below each
bug description demonstrate instances from the Super Tiny Icons
collection where the bug causes a rendering problem. See
L</"Demonstration website and blog articles"> above.

=over

=item Default fill is incorrect in some cases

Default fill is not handled correctly.



=begin html

<table>
<tr>
<td>
<img height="250"
     src="https://benkasminbullock.github.io/supertinyiconscairosvg//svg/fritz.svg"
     width="250">
</td>

<td>
<img height="250"
     src="https://benkasminbullock.github.io/supertinyiconscairosvg//png/fritz.png"
     width="250">
</td>
</tr>

<tr>
<td>
Input SVG
<td>
Output of Image::CairoSVG
</tr>

</table>

=end html





=begin html

<table>
<tr>
<td>
<img height="250"
     src="https://benkasminbullock.github.io/supertinyiconscairosvg//svg/php.svg"
     width="250">
</td>

<td>
<img height="250"
     src="https://benkasminbullock.github.io/supertinyiconscairosvg//png/php.png"
     width="250">
</td>
</tr>

<tr>
<td>
Input SVG
<td>
Output of Image::CairoSVG
</tr>

</table>

=end html



=item Gradients

Gradients are not supported.

There is L<support in
Cairo|https://www.cairographics.org/samples/gradient/> so it should be
possible to add them.



=begin html

<table>
<tr>
<td>
<img height="250"
     src="https://benkasminbullock.github.io/supertinyiconscairosvg//svg/gandi.svg"
     width="250">
</td>

<td>
<img height="250"
     src="https://benkasminbullock.github.io/supertinyiconscairosvg//png/gandi.png"
     width="250">
</td>
</tr>

<tr>
<td>
Input SVG
<td>
Output of Image::CairoSVG
</tr>

</table>

=end html





=begin html

<table>
<tr>
<td>
<img height="250"
     src="https://benkasminbullock.github.io/supertinyiconscairosvg//svg/glitch.svg"
     width="250">
</td>

<td>
<img height="250"
     src="https://benkasminbullock.github.io/supertinyiconscairosvg//png/glitch.png"
     width="250">
</td>
</tr>

<tr>
<td>
Input SVG
<td>
Output of Image::CairoSVG
</tr>

</table>

=end html



=item Shadows

Shadows are not supported.



=begin html

<table>
<tr>
<td>
<img height="250"
     src="https://benkasminbullock.github.io/supertinyiconscairosvg//svg/keepassdx.svg"
     width="250">
</td>

<td>
<img height="250"
     src="https://benkasminbullock.github.io/supertinyiconscairosvg//png/keepassdx.png"
     width="250">
</td>
</tr>

<tr>
<td>
Input SVG
<td>
Output of Image::CairoSVG
</tr>

</table>

=end html



=item Styles

Styles are not supported very well.



=begin html

<table>
<tr>
<td>
<img height="250"
     src="https://benkasminbullock.github.io/supertinyiconscairosvg//svg/tiktok.svg"
     width="250">
</td>

<td>
<img height="250"
     src="https://benkasminbullock.github.io/supertinyiconscairosvg//png/tiktok.png"
     width="250">
</td>
</tr>

<tr>
<td>
Input SVG
<td>
Output of Image::CairoSVG
</tr>

</table>

=end html



=item Text

Text rendering is not supported.



=begin html

<table>
<tr>
<td>
<img height="250"
     src="https://benkasminbullock.github.io/supertinyiconscairosvg//svg/calendar.svg"
     width="250">
</td>

<td>
<img height="250"
     src="https://benkasminbullock.github.io/supertinyiconscairosvg//png/calendar.png"
     width="250">
</td>
</tr>

<tr>
<td>
Input SVG
<td>
Output of Image::CairoSVG
</tr>

</table>

=end html



=item Units

Currently only pixels, millimetres, and inches are supported. 

The conversion ratios are one millimetre is 25.4 inches, and one
inch is 96 pixels.

=back



=head1 AUTHOR

Ben Bullock, <bkb@cpan.org>

=head1 COPYRIGHT & LICENCE

This package and associated files are copyright (C) 
2014-2021
Ben Bullock.

You can use, copy, modify and redistribute this package and associated
files under the Perl Artistic Licence or the GNU General Public
Licence.



