home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / xampp / xampp-perl-addon-1.4.9-installer.exe / Svg2AnyFormat.pm < prev    next >
Encoding:
Perl POD Document  |  2003-03-06  |  11.4 KB  |  453 lines

  1. package Apache::AxKit::Language::Svg2AnyFormat;
  2.  
  3. @ISA = ( 'Apache::AxKit::Language' );
  4.  
  5. BEGIN {
  6.    $Apache::AxKit::Language::Svg2AnyFormat::VERSION = 0.02
  7. }
  8.  
  9. use Apache;
  10. # use Image::Magick;
  11. use Apache::Request;
  12. Apache::AxKit::Cache;
  13. use File::Copy ();
  14. use File::Temp ();
  15. use File::Path ();
  16. use Cwd;
  17. use strict;
  18.  
  19. my $olddir;
  20. my $tempdir;
  21. my $cache;
  22.  
  23. my %Config = 
  24. (  
  25.     SVGOutputMimeType   => "image/png",
  26.     SVGOutputSerializer => "ImageMagick",
  27.     SVGOutputLibRSVGBin => "/usr/local/bin"
  28. );
  29.  
  30. my %MimeTypeSuffixMappings =
  31. (
  32.     "image/png"              => "png",
  33.     "image/jpeg"             => "jpg",
  34.     "image/gif"              => "gif",
  35.     "application/pdf"        => "pdf",
  36.     "application/postscript" => "eps"
  37. );
  38.  
  39. my %MimeTypeLibRSVGFormatMappings =
  40. (
  41.     "image/png"        => "png",
  42. ## DOES NOT WORK CORRECTLY AT THE MOMENT
  43. ## ONE CAN TURN ON BY COMMENTING IN
  44. ##    "image/jpeg"       => "jpeg"
  45. );
  46.  
  47. sub stylesheet_exists () { 0; }
  48.  
  49. sub handler
  50. {
  51.     my $class = shift;
  52.     my ( $r, $xml_provider, undef, $last_in_chain ) = @_;
  53.     
  54.     my $mime;
  55.     my $suffix = "png";
  56.     my $serializer;
  57.     my $rsvg_bin;
  58.     
  59.     AxKit::Debug(8, "Transform started!!!!");
  60.     
  61.     print STDERR "IN HERE!!!!!!\n";
  62.     
  63.     if( ! $last_in_chain )
  64.     {
  65.         fail( "This is a Serializer, hence it has to be the last in the chain!" );
  66.     }
  67.     
  68.     if( $r->pnotes( "axkit_mime_type" ) )
  69.     {
  70.         AxKit::Debug(8, "MimeType retrieved from Plugin");
  71.         $mime = $r->pnotes( "axkit_mime_type" );
  72.     }
  73.     else
  74.     {
  75.         AxKit::Debug(8, "MimeType retrieved from CONF or using Default");
  76.         $mime = $r->dir_config( "SVGOutputMimeType" ) || $Config{SVGOutputMimeType};
  77.     }
  78.     
  79.     AxKit::Debug(8, "MimeType is set to '$mime'");
  80.     
  81.     if( ! exists $MimeTypeSuffixMappings{$mime} )
  82.     {
  83.         AxKit::Debug(8, "MimeType is not known. We are using DEFAULTS");
  84.         $mime   = $Config{SVGOutputMimeType};
  85.         $suffix = "png";
  86.     }
  87.     else
  88.     {
  89.         AxKit::Debug(8, "Setting suffix. To mapped value");
  90.         $suffix = $MimeTypeSuffixMappings{$mime};
  91.     }
  92.  
  93.     $serializer = $r->dir_config( "SVGOutputSerializer" ) || $Config{SVGOutputSerializer};
  94.     $rsvg_bin   = $r->dir_config( "SVGOutputLibRSVGBin" ) || $Config{SVGOutputLibRSVGBin};
  95.     
  96.     if( $serializer eq "ImageMagick" || ! exists $MimeTypeLibRSVGFormatMappings{$mime} ) 
  97.     {
  98.         AxKit::Debug(8, "We need Image-Magick because ImageMagick should be used as serializer or LibRSVG could not create desired format");
  99.         
  100.         ## Loading at runtime
  101.         require Image::Magick;
  102.     }
  103.     elsif( $serializer eq "LibRSVG" )
  104.     {
  105.         AxKit::Debug(8, "LibRSVG is registered as serializer");
  106.         
  107.         ## nothing to be loaded because we are using command line
  108.     }
  109.     else
  110.     {
  111.         fail( "This is an unknown serializer for me." );
  112.     }
  113.     
  114.     my $tempdir = File::Temp::tempdir();
  115.     
  116.     AxKit::Debug(8, "Got tempdir: $tempdir");
  117.     
  118.     if ( ! $tempdir ) 
  119.     {
  120.         die "Cannot create tempdir: $!";
  121.     }
  122.     
  123.     $olddir = cwd;
  124.     
  125.     if( my $dom = $r->pnotes('dom_tree') )
  126.     {
  127.         AxKit::Debug(8, "Got a dom tree");
  128.         my $xmlstring = $dom->toString();
  129.         delete $r->pnotes()->{'dom_tree'};
  130.         
  131.         my $fh = Apache->gensym();
  132.         chdir( $tempdir ) || fail( "Cannot cd: $!" );
  133.         open($fh, ">temp.svg") || fail( "Cannot write: $!" );
  134.         print $fh $xmlstring;
  135.         close( $fh ) || fail( "Cannot close: $!" );
  136.     }
  137.     elsif( my $xmlstring = $r->pnotes('xml_string') )
  138.     {
  139.         AxKit::Debug(8, "Got a xml-string");
  140.         my $fh = Apache->gensym();
  141.         chdir( $tempdir ) || fail( "Cannot cd: $!" );
  142.         open($fh, ">temp.svg") || fail( "Cannot write: $!" );
  143.         print $fh $xmlstring;
  144.         close( $fh ) || fail( "Cannot close: $!" );
  145.     }
  146.     else
  147.     {
  148.         my $text = eval { ${$xml_provider->get_strref()} };
  149.         
  150.         if ( $@ ) 
  151.         {
  152.             AxKit::Debug(8, "No ref");
  153.             my $fh = $xml_provider->get_fh();
  154.             chdir($tempdir) || fail("Cannot cd: $!");
  155.             File::Copy::copy($fh, "temp.svg");
  156.         }
  157.         else 
  158.         {
  159.             AxKit::Debug(8, "It has been a ref");
  160.             
  161.             my $fh = Apache->gensym();
  162.             chdir($tempdir) || fail( "Cannot cd: $!" );
  163.             open($fh, ">temp.svg") || fail( "Cannot write: $!" );
  164.             print $fh $text;
  165.             close($fh) || fail("Cannot close: $!");
  166.         }
  167.     }
  168.     
  169.     chdir( $tempdir ) || fail("Cannot cd: $!");
  170.     
  171.     my $retval;
  172.     
  173.     if( $serializer eq "ImageMagick" )
  174.     {
  175.         AxKit::Debug(8, "Serializer is ImageMagick");
  176.         
  177.         my $image = new Image::Magick();
  178.         $retval = $image->Read( "temp.svg" );
  179.         
  180.         if( "$retval" )
  181.         {
  182.             fail( "ImageMagick failed. Reason: $retval" );
  183.         }
  184.         
  185.         $image->Write( "temp.$suffix" );
  186.     }
  187.     else
  188.     {
  189.         AxKit::Debug(8, "Serializer is: LibRSVG");
  190.         
  191.         if( exists $MimeTypeLibRSVGFormatMappings{$mime} )
  192.         {
  193.             AxKit::Debug(8, "MimeType is supported by LibRSVG");
  194.             
  195.             $retval = system( "$rsvg_bin/rsvg -f ".$MimeTypeLibRSVGFormatMappings{$mime}." temp.svg temp.$suffix" );
  196.     
  197.  
  198.             if( $retval )
  199.             {
  200.                 fail( "rsvg exited with status code $retval" );
  201.             }
  202.         }
  203.         else
  204.         {
  205.             AxKit::Debug(8, "MimeType '$mime' **NOT** is supported by LibRSVG");
  206.             
  207.             my $image = new Image::Magick();
  208.  
  209.             AxKit::Debug(8, "STEP 1: rsvg convert to PNG");
  210.             
  211.             $retval = system( "$rsvg_bin/rsvg -f png temp.svg temp.png" );
  212.             
  213.             if( $retval )
  214.             {
  215.                 fail( "rsvg exited with status code $retval" );
  216.             }
  217.             
  218.             AxKit::Debug(8, "STEP 2: ImageMagick to FINAL format '$mime'");
  219.  
  220.             chdir( $tempdir ) || fail("Cannot cd: $!");
  221.  
  222.             $retval = $image->Read( "temp.png" );
  223.             
  224.             if( "$retval" )
  225.             {
  226.                 fail( "ImageMagick failed. Reason: $retval" );
  227.             }
  228.             
  229.             $image->Write( "temp.$suffix" );
  230.             
  231.             if( "$retval" )
  232.             {
  233.                 fail( "ImageMagick failed. Reason: $retval" );
  234.             }
  235.         }
  236.     }
  237.  
  238.     AxKit::Debug(8, "Serialization finished.");
  239.  
  240.     $AxKit::Cfg->AllowOutputCharset(0);
  241.     
  242.     my $pdfh = Apache->gensym();
  243.     
  244.     open( $pdfh, "<temp.$suffix" ) or fail( "Could not open $mime: $!" );
  245.     $r->content_type( $mime );
  246.     local $/;
  247.     
  248.     $r->print(<$pdfh>);
  249.     
  250.     return Apache::Constants::OK;
  251. }
  252.  
  253. sub cleanup {
  254.     chdir $olddir;
  255.     File::Path::rmtree($tempdir);
  256. }
  257.  
  258. sub fail {
  259.     cleanup();
  260.     die @_;
  261. }
  262.  
  263. 1;
  264.  
  265.  
  266. __END__
  267.  
  268. =pod
  269.  
  270. =head1 NAME
  271.  
  272. Apache::AxKit::Language::Svg2AnyFormat - SVG Serializer
  273.  
  274. =head1 SYNOPSIS
  275.  
  276. =head2 ImageMagick
  277.  
  278.   AddHandler axkit .svg
  279.  
  280.   ## Fairly important to cache the output because
  281.   ## transformation is highly CPU-Time and Memory consuming
  282.   AxCacheDir /tmp/axkit_cache
  283.  
  284.   ## When using SvgCgiSerialize this is vital 
  285.   ## because the cgi-parameters are not used
  286.   ## by default to build the cache
  287.   AxAddPlugin Apache::AxKit::Plugin::QueryStringCache
  288.  
  289.   <Files ~ *.svg>
  290.     AxAddStyleMap application/svg2anyformat Apache::AxKit::Language::Svg2AnyFormat
  291.     AxAddProcessor application/svg2anyformat NULL
  292.  
  293.     ## optional with this variable you can
  294.     ## overwrite the default output format 
  295.     ## PNG
  296.     ## Supported Values:
  297.     ##    image/jpeg
  298.     ##    image/png
  299.     ##    image/gif
  300.     ##    application/pdf
  301.     PerlSetVar SVGOutputMimeType image/jpeg
  302.   
  303.     ## optional module to pass the format using cgi-parameters
  304.     ## to the module. For supported values see above
  305.     ## and the man-page of the plugin
  306.     AxAddPlugin Apache::AxKit::Plugin::SvgCgiSerialize   
  307.   </Files>
  308.  
  309. =head2 LibRSVG
  310.  
  311.   AddHandler axkit .svg
  312.  
  313.   ## Fairly important to cache the output because
  314.   ## transformation is highly CPU-Time and Memory consuming
  315.   AxCacheDir /tmp/axkit_cache
  316.  
  317.   ## When using SvgCgiSerialize this is vital 
  318.   ## because the cgi-parameters are not used
  319.   ## by default to build the cache
  320.   AxAddPlugin Apache::AxKit::Plugin::QueryStringCache
  321.  
  322.   <Files ~ *.svg>
  323.     AxAddStyleMap application/svg2anyformat Apache::AxKit::Language::Svg2AnyFormat
  324.     AxAddProcessor application/svg2anyformat NULL
  325.  
  326.     ## optional with this variable you can
  327.     ## overwrite the default output format 
  328.     ## PNG
  329.     ## Supported Values(Native Formats):
  330.     ##    image/png
  331.     ## If you specify any other format:
  332.     ##   svg->png is done by LibRSVG
  333.     ##   png->chosen format Image::Magick
  334.     PerlSetVar SVGOutputMimeType image/jpeg
  335.     
  336.     PerlSetVar SVGOutputSerializer LibRSVG
  337.     
  338.     ## only to be set if path differs from
  339.     ## /usr/local/bin
  340.     PerlSetVar SVGOutputLibRSVGBin /usr/bin/rsvg
  341.     
  342.     ## optional module to pass the format using cgi-parameters
  343.     ## to the module. For supported values see above
  344.     ## and the man-page of the plugin
  345.     AxAddPlugin Apache::AxKit::Plugin::SvgCgiSerialize   
  346.   </Files>
  347.  
  348.  
  349. =head1 DESCRIPTION
  350.  
  351. Svg2AnyFormat is a serializer which can transform SVG to many different
  352. output formats(e.g. png, jpg, ... ). At the moment it uses Image::Magick or LibRSVG as conversion libraries
  353. which do not support the whole set of svg features. In one case the conversion
  354. could work in another not. You have to give it a try. Please note because 
  355. Svg2AnyFormat to any format is a searializer it HAS TO BE LAST in the transformer 
  356. chain!!!!
  357.  
  358. Please note when referencing external material (e.g. Images) you'll have to use an absolute path
  359.  
  360. =head2 Image::Magick
  361.  
  362. If no SVGOutputSerializer is set Image::Magick is used as default. The reason is simply
  363. because of backward compatility. You could also set Image::Magick explicitly with
  364.  
  365. =head3 Example:
  366.  
  367.   PerlSetVar SVGOutputSerializer ImageMagick
  368.  
  369. =head3 Advantges:
  370.  
  371. =over
  372.  
  373. =item 
  374.  
  375. Nearly any format can be exported
  376.  
  377. =item 
  378.  
  379. known to work on many os
  380.  
  381. =back
  382.  
  383. =head3 Disadvantages:
  384.  
  385. =over
  386.  
  387. =item 
  388.  
  389. it's fairly big
  390.  
  391. =item 
  392.  
  393. it does not support as much of the SVG-Spec as LibRSVG
  394.  
  395. =back
  396.  
  397. =head2 LibRSVG
  398.  
  399. LibRSVG is part of the gnome project. And could also be used as SVG-Serializer at the moment
  400. the only really supported output-format is PNG. As a matter of that if you want to use
  401. LibRSVG as your SVG-Serializer and the output format is an other than PNG, LibRSVG is used to
  402. transform the SVG to PNG and ImageMagick from PNG to the desired output format.
  403. At the moment no working PERL-Module for LibRSVG exists so we are using the commandline utility
  404. rsvg.
  405.  
  406. =head3 Example:
  407.  
  408.   PerlSetVar SVGOutputSerializer LibRSVG
  409.   PerlSetVar SVGOutputLibRSVGBin /usr/bin/rsvg
  410.  
  411. =head3 Advantages
  412.  
  413. =over
  414.  
  415. =item 
  416.  
  417. supports more of SVG-spec than Image::Magick
  418.  
  419. =item
  420.  
  421. not that big
  422.  
  423. =back
  424.  
  425. =head3 Disadvantages:
  426.  
  427. =over
  428.  
  429. =item 
  430.  
  431. no Perl-Module for C-libary => command line used at the moment
  432.  
  433. =item
  434.  
  435. only PNG supported as output format. This is solved by using
  436. Image::Magick in a second transformation step (LOW Performance!!!).
  437.  
  438. =back
  439.  
  440. =head1 VERSION
  441.  
  442. 0.02
  443.  
  444. =head1 SEE ALSO
  445.  
  446. L<Apache::AxKit::Plugin::SvgCgiSerialize>
  447.  
  448. =head1 AUTHOR
  449.  
  450. Tom Schindl <tom.schindl@bestsolution.at>
  451.  
  452. =cut
  453.