PDF-Builder
view release on metacpan or search on metacpan
lib/PDF/Builder/Resource/XObject/Image/SVG.pm view on Meta::CPAN
such as B<Arial>, which may or may not be installed on non-Windows platforms,
and even for Windows, would need to be added to FontManager. You should check
the resulting SVG files produced by Third-Party packages to see what fonts
they are expecting. MathJax creates text characters as filled outlines in SVG,
and does not appear to use any standard fonts.
=item combine => 'method'
If there are multiple XObjects defined by an SVG (due to multiple C<svg>
entries), they may be combined into a single XObject. The default is B<none>,
which does I<not> combine XObjects. Currently, the only other supported method
is B<stacked>, which vertically stacks images, with C<sep> spacing between
them. At this writing, the B<bbox> combine method is I<not> supported by
SVGPDF, but may be in the future. It is passed to C<$svg-E<gt>process()>.
=item sep => n
Vertical space (in points) to add between individual images when C<combine> is
not 'none'. The default is 0 (no space between images).
It is passed to C<$svg-E<gt>process()>.
=back
=back
=head3 What is returned
Returns an image in the SVG. Unlike other image formats, it is I<not> actually
some form of image object, but an array (of at least one element) containing
XObjects of the SVG converted into PDF graphics and text commands. If an SVG
includes a pixel-based image, that image will be scaled up and down in the
normal image way, while PDF graphics and text are always fully scalable, both
when setting an image size I<and> when zooming in and out in a PDF Reader.
A returned "object" is always an array of hashes (including the XObject as one
of the elements), one per C<svg> tag. Note that C<svg>s must be peers
(top-level), and may B<not> be nested one within another! In most applications,
an SVG file will have one C<svg> tag and thus a single element in the array.
However, some SVGs will produce multiple array elements from multiple C<svg>
tags.
=head3 Dealing with multiple image objects, and combining them
If you don't set C<subimage>, the full array will be returned. If
you set C<subimage =E<gt> n>, where I<n> is a valid element number (0...), all
elements I<except> the n-th will be discarded, leaving a single element array.
When it comes time for C<object()> to display this XObject array, the first
(0th) element will be displayed, and any other elements will be ignored. Thus,
the default behavior is effectively C<subimage =E<gt> 0>. You may call either
C<object> or C<image>, as C<image> will simply pass everything on to C<object>.
Remember that I<not> setting C<subimage> will cause the entire array to be
returned. You are free to rearrange and/or subset this array, if you wish.
If you want to display (in the PDF) multiple images, you can select one or more
of the array elements to be processed (see the examples). If you want to stack
all of them vertically, perhaps with some space between them, consider using
the C<combine =E<gt> 'stacked'> option, but be aware that the total height of
the single resulting image may be too large for your page! You may need to
output them separately, as many as will fit on a page.
This leaves the possibility of I<overlaying> multiple images to overlap in one
large combined image. You have the various width and height (and bounding box
coordinates), so it I<is> possible to align images to have the same origin.
SVGPDF I<may> get C<combine =E<gt> 'bbox'> at some point in the future, to
automate this, but for the time being you need to do it yourself. Keep an eye
out for different C<svg>s scaled at different sizes; they may need rescaling
to overlay properly.
=cut
# -------------------------------------------------------------------
# produce an array of XObject hashes describing one or more <svg> tags in
# the input, by calling SVGPDF new() and process(). if 'subimage' is given,
# discard all other array elements.
sub new {
my ($class, $pdf, $file, %opts) = @_;
my $verbose = $opts{'verbose'} || 0;
my $fontsz = $opts{'fontsize'} || 12;
my $callbacks = $opts{'fc'}; # either routine or array ref of routines
my $subimage = $opts{'subimage'};
my $MScore = $opts{'MScore'} || 0;
if ($MScore) { # TBD
}
# delete modified options
delete $opts{'verbose'};
delete $opts{'fontsize'};
# TBD for 'display' SVG's with tags, remove tag (nested <svg>) and
# deal with separately. must remove before call new(). might extract
# back in Builder.pm (image_svg) and could let high-level code in
# examples/SVG.pl handle its placement? or possibly as separate array
# element (if includes sufficient positioning information).
my $svg;
if ($MScore) {
if (defined $callbacks) {
# existing callback(s) to add MScore processing to
delete $opts{'fc'};
$callbacks = [ ($callbacks), &MScoreCB ];
$svg = SVGPDF->new( 'pdf'=>$pdf, 'verbose'=>$verbose,
'fc'=>$callbacks,
'fontsize'=>$fontsz, %opts );
} else {
# no existing callback(s) in %opts to add MScore processing to
$callbacks = \&MScoreCB;
$svg = SVGPDF->new( 'pdf'=>$pdf, 'verbose'=>$verbose,
'fc'=>$callbacks,
'fontsize'=>$fontsz, %opts );
}
} else {
# not adding MScore, any existing callbacks still in %opts
$svg = SVGPDF->new( 'pdf'=>$pdf, 'verbose'=>$verbose,
'fontsize'=>$fontsz, %opts );
}
my $xof = $svg->process($file, 'fontsize'=>$fontsz, %opts);
# $xof is anonymous array ref with one element per <svg> (should be
# at minimum, one), and each element is a hash of width, vwidth,
# height, vheight, vbox, bbox(), and the xobject itself, xo
# if subimage given, return only that subimage (0th if invalid number)
if (defined $subimage) {
my @array = @$xof;
if ($subimage < 0 || $subimage > $#array ) {
( run in 1.645 second using v1.01-cache-2.11-cpan-39bf76dae61 )