A Slide-Show Presentation via SVG - Part 1 of Chapter 7 from Perl Graphics Programming (3/4) | WebReference

A Slide-Show Presentation via SVG - Part 1 of Chapter 7 from Perl Graphics Programming (3/4)

To page 1To page 2current pageTo page 4
[previous] [next]

Perl Graphics Programming, Chapter 7: Creating SVG with Perl

Next, iterate through the slide elements. Normally the XML::Writer module writes to an IO::Handle filehandle. The IO::Scalar module subclasses IO::Handle and ties the filehandle output to a scalar. This provides an easy means of buffering the XML output so that we can embed one <svg> element within another.

my $dir = $slideshow->{'subdir'};
   
my $n = 0;                # the current slide
my $max = $#slides+1;     # the total number of slides
   
foreach my $s (@slides) {
    my $y = 0;
    $n++;
    my $textblock = new IO::Scalar;
    my $writer = XML::Writer->new(OUTPUT=>$textblock);

The setDataMode( ) and setDataIndent( ) methods control the formatting of the output XML; here we enter newlines around elements and indent them:

    $writer->setDataMode(1);      
    $writer->setDataIndent(2);

Use XML::Writer's startTag( ) method to start a tag and the endTag( ) method for the closing tag. Attributes are added for each additional named parameter. The characters( ) method writes strings to the XML output, escaping all special characters:

    $writer->startTag('svg',          # Start an SVG element
                      width=>"2000",
                      height=> "2000");
    $writer->startTag('text',
                       transform => "translate(0, $titlesize)",
                       style => "font-size:$titlesize;".
                       "font-weight:bold;fill:#000000");
    $writer->characters($s->{'title'});
    $writer->endTag('text');          # Close the text element
    $y += $titlesize + 10;            # track the current y position

Next, iterate through all the blocks in the slide, adding a new line of SVG text for each textline element in the original template.

    my @blocks = dereference($s->{'block'});
    foreach my $b (@blocks) {
        if ($b->{'type'} eq 'textline') {
            $y +=18;
            $writer->startTag('text',
                         transform => "translate(0, $y)",
                         style => 'font-size:18;fill:#000000');
            $writer->characters($b->{'content'});
            $writer->endTag('text');
        }

A bulletlist contains a sequence of bullet items, each of which is indented and starts with a Unicode bullet character. Unfortunately, the characters( ) method escapes the Unicode bullet character, so we'll bypass it by printing directly to the text block.

        if ($b->{'type'} eq 'bulletlist') {
            $y += 4;            # give it a little space
            my @bullets = dereference($b->{'bullet'});
            foreach my $bulleted_text (@bullets) {
                $y += 18;
                $writer->startTag('text',
                            transform => "translate(20, $y)", 
                            style => 'font-size:18;fill:#000000');
   
                print $textblock "&#x2022; ";   # A Unicode bullet
                $writer->characters($bulleted_text); 
                $writer->endTag('text');
            }
            $y += 4;            # Add more space after the list
        }
    }
    $writer->endTag('svg');     # Close the 'text block' SVG graphic
    $writer->end(  );

Compute an appropriate scaling factor. If the text block already fits, leave it as is; otherwise, shrink it.

my $scale =1;
    if ($y > ($height-40)) {
        $scale = ($height-40)/$y;
    }

To page 1To page 2current pageTo page 4
[previous] [next]

Created: February 12, 2003
Revised: February 12, 2003

URL: https://webreference.com/programming/perl/chap7/1/3.html