/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2013 by Alexander Heusel
*
* This file is part of svgfx.
*
* svgfx is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3
* as published by the Free Software Foundation.
*
* see: http://opensource.org/licenses/LGPL-3.0
*
* svgfx is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* This version of svgfx includes copyright notice and attribution requirements.
* According to the LGPL this information must be displayed even if you modify
* the source code of svgfx. Neither the copyright statement nor the attribution
* may be removed.
*
* Attribution Requirements:
*
* If you create derived work you must do two things regarding copyright notice
* and author attribution.
*
* First, the copyright notice must remain. It must be reproduced in any program
* that uses svgfx.
*
* Second, add an additional notice, stating that you modified svgfx. A suitable
* notice might read "svgfx source code modified by YourName 2012".
*
* Note, that these requirements are in full accordance with the LGPL v3
* (see 7. Additional Terms, b).
*
*/
package svg2fx;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javafx.scene.effect.GaussianBlur;
import javafx.scene.image.Image;
import javafx.scene.paint.ImagePattern;
import javafx.scene.transform.*;
import org.w3c.dom.NodeList;
import org.w3c.dom.svg.SVGFEGaussianBlurElement;
import org.w3c.dom.svg.SVGFilterElement;
import org.w3c.dom.svg.SVGImageElement;
import org.w3c.dom.svg.SVGPatternElement;
import svg2fx.interfaces.DefsVisitor;
/**
*
* @author Alexander Heusel
*/
public class DefsBuilder implements DefsVisitor
{
private HashMap<String, Object> defs = new HashMap<>();
public DefsBuilder()
{
}
@Override
public void visitSVGPatternElement(SVGPatternElement pe)
{
String id = pe.getId();
double dx = 0.0;
double dy = 0.0;
ArrayList<Transform> tr = Tools.decodeSVGTransforms(pe.getAttribute("patternTransform"));
for(int i = 0; i < tr.size(); i++)
{
if(tr.get(i) instanceof Translate)
{
dx += ((Translate)tr.get(i)).getX();
dy += ((Translate)tr.get(i)).getY();
}
}
double width = pe.getWidth().getBaseVal().getValue();
double height = pe.getHeight().getBaseVal().getValue();
Image image = null;
NodeList il = pe.getChildNodes();
for(int k = 0; k < il.getLength(); k++)
{
if(il.item(k) instanceof SVGImageElement)
{
image = visitSVGImageElement((SVGImageElement)il.item(k));
break;
}
}
if(image == null)
{
throw new java.lang.IllegalStateException("Unsupportet pattern-type!");
}
else
{
ImagePattern imgPat = new ImagePattern(image, dx, dy, width, height, false);
defs.put(id, imgPat);
//System.out.format("[ImagePattern] id: %s, x: %f, y: %f, width:%f, height: %f\n", id, imgPat.getX(), imgPat.getY(), imgPat.getWidth(), imgPat.getHeight());
}
}
private Image visitSVGImageElement(SVGImageElement ie)
{
// data:image/jpeg;base64,
int startIdx = ie.getHref().getBaseVal().indexOf("base64");
String mimeType = ie.getHref().getBaseVal().substring(0, startIdx);
mimeType = mimeType.substring(mimeType.indexOf(":") + 1);
mimeType = mimeType.substring(0, mimeType.indexOf(";")).trim();
startIdx = ie.getHref().getBaseVal().indexOf(",", startIdx) + 1;
String base64Data = ie.getHref().getBaseVal().substring(startIdx).trim();
byte[] newBytes = Base64.decode(base64Data);
//Image img = new Image(new ByteArrayInputStream(newBytes), ie.getWidth().getBaseVal().getValue(), ie.getHeight().getBaseVal().getValue(), false, false);
Image img = new Image(new ByteArrayInputStream(newBytes));
//System.out.format("[Image] width: %f , height %f, MiME-type: %s, length: %d, base64 starts with: %s...\n", img.getWidth(), img.getHeight(), mimeType, newBytes.length, base64Data.substring(0, 7));
return img;
}
private GaussianBlur visitSVGFEGaussianBlurElement(SVGFEGaussianBlurElement gb)
{
final double inkscapeCompensationFactor = 3.0;
return new GaussianBlur(inkscapeCompensationFactor*Double.parseDouble(gb.getAttribute("stdDeviation")));
}
@Override
public void visitSVGFilterElement(SVGFilterElement fe)
{
String id = fe.getId();
GaussianBlur gb = null;
NodeList nl = fe.getChildNodes();
for(int k = 0; k < nl.getLength(); k++)
{
if(nl.item(k) instanceof SVGFEGaussianBlurElement)
{
gb = visitSVGFEGaussianBlurElement((SVGFEGaussianBlurElement)nl.item(k));
break;
}
}
if(gb == null)
{
throw new java.lang.IllegalStateException("Unsupportet filter-type!");
}
else
{
defs.put(id, gb);
//System.out.format("[GaussianBlur] id: %s, radius: %f\n", id, gb.getRadius());
}
}
public Map<String, Object> getDefs()
{
return Collections.unmodifiableMap(defs);
}
}