Robidu Robidu -4 years ago 43
CSS Question

SVG filter doesn't work at all

I'm trying to set up a Daltonian filter (i. e. an emulation of the various types of color-blindness), however, the SVG that I'm using for this completely fails. Firefox displays everything in the background color (everything is rendered, though, but is absolutely invisible), and Chrome displays the page normally.

Since I'm reading in the transformation values from a database, the SVG is generated by this Perl script:

#!/usr/bin/perl -wT -I /srv/www1/cgi-lib

use strict;
use DBI;
use helpers qw(aindex);

my $dbname = 'DBI:mysql:<dbname>';
my $dbuser = '<dbuser>';
my $passwd = '<dbpass>';

my $p_http_ver = $ENV{'SERVER_PROTOCOL'};

my $p_debug = 0;

if($p_debug)
{
print "Content-Type: text/plain; charset=utf-8\n\n";
}

sub get_params
{
my ($l_script, $l_paramstr) = split(/\?/, $ENV{'REQUEST_URI'});

return undef if(!defined $l_paramstr);

my @l_paramlist = split(/[&;]/, $l_paramstr);
my $l_this;
my %l_params = ( );

foreach $l_this (@l_paramlist)
{
my ($l_var, $l_value) = split(/=/, $l_this);

next if(!defined $l_value);

$l_value =~ s/\+/ /g;
$l_value =~ s/%([0-9a-fA-F]{2})/pack("C", hex($1))/eg;

$l_params{$l_var} = $l_value;
}

return \%l_params;
}

my $params = get_params();
my %matrix = ( );
my @valid_modes = ( 'normal', 'protanopia', 'protanomaly', 'deuteranopia', 'deuteranomaly', 'tritanopia', 'tritanomaly', 'achromatopsia', 'achromatomaly' );

foreach (@valid_modes)
{
# Fill in the normal matrix: Default for database failures!
$matrix{$_} = [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ];
}

my $p_mode = ${$params}{'mode'};
$p_mode = 'normal' if(!defined $p_mode);
$p_mode = 'normal' if(aindex(@valid_modes, $p_mode) == -1);

print "Content-Type: image/svg+xml; charset=utf-8\n";
print "Expires: -60s\n";
print "Pragma: no-cache\n" if($p_http_ver eq 'HTTP/1.0');
print "Cache-Control: no-cache, no-store, must-revalidate\n" if($p_http_ver eq 'HTTP/1.1');

# Empty line to end the header section...
print "\n";

my $dbh = DBI->connect($dbname, $dbuser, $passwd, { PrintError => 0, AutoCommit => 0 });
if($dbh)
{
my $l_sth;
my @l_row;
my $l_i;

$l_sth = $dbh->prepare(qq{select * from dalton});
$l_sth->execute();

while(@l_row = $l_sth->fetchrow_array)
{
for($l_i = 0; $l_i < @l_row - 1; $l_i++)
{
${$matrix{$l_row[0]}}[$l_i] = $l_row[$l_i + 1];
}
}

$l_sth->finish();

$dbh->disconnect();
}

print <<"EOT";
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg>
<defs>
EOT

my $filter;

foreach $filter (@valid_modes)
{
my $l_i = 0;

print "<filter id=\"$filter\">\n";
print "<feColorMatrix type=\"matrix\" values=\"";
for($l_i = 0; $l_i < @{$matrix{$filter}}; $l_i++)
{
print " " if($l_i);
print ${$matrix{$filter}}[$l_i];
if($l_i % 4 == 3)
{
print " 0.000";
print "," if($l_i < @{$matrix{$filter}} - 1);
}
}
print "\" />\n";
print "</filter>\n";
}

print <<"EOT";
</defs>
</svg>
EOT


The following is used to attach this filter to the
body
element:

body {
filter: url('/cgi-bin/svg/dalton.pl#normal'); /* substitute any other ID for "normal" here if required */
}


When calling the script stand-alone in the browser, I get the document structure (no CSS present for the SVG), and validating it at validator.w3.org also didn't reveal any errors.
However, once I include it in the CSS for my XHTML documents, things start to go haywire (no,
-webkit-filter
doesn't make the thing work for Chrome, either...).

What could be going wrong here? Right now I don't see the forest for the trees.

EDIT: The script produces the following output:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg>
<defs>
<filter id="normal">
<feColorMatrix type="matrix" values="1.000 0.000 0.000 0.000 0.000, 0.000 1.000 0.000 0.000 0.000, 0.000 0.000 1.000 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" />
</filter>
<filter id="protanopia">
<feColorMatrix type="matrix" values="0.567 0.433 0.000 0.000 0.000, 0.558 0.442 0.000 0.000 0.000, 0.000 0.242 0.758 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" />
</filter>
<filter id="protanomaly">
<feColorMatrix type="matrix" values="0.817 0.183 0.000 0.000 0.000, 0.333 0.667 0.000 0.000 0.000, 0.000 0.125 0.875 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" />
</filter>
<filter id="deuteranopia">
<feColorMatrix type="matrix" values="0.625 0.375 0.000 0.000 0.000, 0.700 0.300 0.000 0.000 0.000, 0.000 0.300 0.700 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" />
</filter>
<filter id="deuteranomaly">
<feColorMatrix type="matrix" values="0.800 0.200 0.000 0.000 0.000, 0.258 0.742 0.000 0.000 0.000, 0.000 0.142 0.858 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" />
</filter>
<filter id="tritanopia">
<feColorMatrix type="matrix" values="0.950 0.050 0.000 0.000 0.000, 0.000 0.433 0.567 0.000 0.000, 0.000 0.475 0.525 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" />
</filter>
<filter id="tritanomaly">
<feColorMatrix type="matrix" values="0.967 0.033 0.000 0.000 0.000, 0.000 0.733 0.267 0.000 0.000, 0.000 0.183 0.817 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" />
</filter>
<filter id="achromatopsia">
<feColorMatrix type="matrix" values="0.299 0.587 0.114 0.000 0.000, 0.299 0.587 0.114 0.000 0.000, 0.299 0.587 0.114 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" />
</filter>
<filter id="achromatomaly">
<feColorMatrix type="matrix" values="0.618 0.320 0.062 0.000 0.000, 0.163 0.775 0.062 0.000 0.000, 0.163 0.320 0.516 0.000 0.000, 0.000 0.000 0.000 1.000 0.000" />
</filter>
</defs>
</svg>

Answer Source

Your root SVG element has no namespace. You need your root element to be

<svg xmlns="http://www.w3.org/2000/svg">
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download