working on SVG salamander, but with little success

This commit is contained in:
Jörg Prante 2021-12-21 22:23:49 +01:00
parent 2ec059f276
commit e6c560a1a8
86 changed files with 774 additions and 969 deletions

View file

@ -1,4 +1,5 @@
dependencies { dependencies {
api "org.apache.pdfbox:pdfbox:${project.property('pdfbox.version')}" api "org.apache.pdfbox:pdfbox:${project.property('pdfbox.version')}"
testImplementation "org.jfree:jfreechart:${project.property('jfreechart.version')}" testImplementation "org.jfree:jfreechart:${project.property('jfreechart.version')}"
testImplementation project(':graphics-svg')
} }

View file

@ -24,10 +24,16 @@ import org.xbib.graphics.pdfbox.color.DefaultColorMapper;
import org.xbib.graphics.pdfbox.color.RGBtoCMYKColorMapper; import org.xbib.graphics.pdfbox.color.RGBtoCMYKColorMapper;
import org.xbib.graphics.pdfbox.font.DefaultFontDrawer; import org.xbib.graphics.pdfbox.font.DefaultFontDrawer;
import org.xbib.graphics.pdfbox.font.FontDrawer; import org.xbib.graphics.pdfbox.font.FontDrawer;
import org.xbib.graphics.svg.SVGDiagram;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.SVGUniverse;
import java.awt.color.ICC_Profile; import java.awt.color.ICC_Profile;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.logging.Logger;
public class RenderSVGsTest extends PdfBoxGraphics2DTestBase { public class RenderSVGsTest extends PdfBoxGraphics2DTestBase {
@ -63,7 +69,19 @@ public class RenderSVGsTest extends PdfBoxGraphics2DTestBase {
renderSVGCMYK("atmospheric-composiition.svg", 0.7); renderSVGCMYK("atmospheric-composiition.svg", 0.7);
} }
private void renderSVG(String name, final double scale) throws IOException { private void renderSVG(String name, final double scale) {
URL url = getClass().getResource(name);
SVGUniverse svgUniverse = new SVGUniverse();
SVGDiagram diagram = svgUniverse.getDiagram(svgUniverse.loadSVG(url));
exportGraphic("xbibsvg", name.replace(".svg", ""), gfx -> {
gfx.scale(scale, scale);
try {
diagram.render(gfx);
} catch (SVGException e) {
throw new IllegalArgumentException(e);
}
});
/*String uri = RenderSVGsTest.class.getResource(name).toString(); /*String uri = RenderSVGsTest.class.getResource(name).toString();
SAXSVGDocumentFactory f = new SAXSVGDocumentFactory(); SAXSVGDocumentFactory f = new SAXSVGDocumentFactory();
Document document = f.createDocument(uri, RenderSVGsTest.class.getResourceAsStream(name)); Document document = f.createDocument(uri, RenderSVGsTest.class.getResourceAsStream(name));

View file

@ -0,0 +1,13 @@
module org.xbib.graphics.svg {
requires transitive java.desktop;
requires java.logging;
exports org.xbib.graphics.svg;
exports org.xbib.graphics.svg.element;
exports org.xbib.graphics.svg.element.filtereffects;
exports org.xbib.graphics.svg.element.glyph;
exports org.xbib.graphics.svg.element.gradient;
exports org.xbib.graphics.svg.element.shape;
exports org.xbib.graphics.svg.pathcmd;
exports org.xbib.graphics.svg.xml;
exports org.xbib.graphics.svg.util;
}

View file

@ -1,42 +0,0 @@
package org.xbib.graphics.svg;
import org.xbib.graphics.svg.element.SVGElement;
import org.xbib.graphics.svg.xml.StyleAttribute;
import java.io.IOException;
public class Hkern extends SVGElement {
public static final String TAG_NAME = "hkern";
String u1;
String u2;
int k;
@Override
public String getTagName() {
return TAG_NAME;
}
@Override
protected void build() throws SVGException, IOException {
super.build();
StyleAttribute sty = new StyleAttribute();
if (getPres(sty.setName("u1"))) {
u1 = sty.getStringValue();
}
if (getPres(sty.setName("u2"))) {
u2 = sty.getStringValue();
}
if (getPres(sty.setName("k"))) {
k = sty.getIntValue();
}
}
@Override
public boolean updateTime(double curTime) throws SVGException {
return false;
}
}

View file

@ -1,30 +0,0 @@
package org.xbib.graphics.svg;
public class MarkerPos {
private int type;
double x;
double y;
double dx;
double dy;
public MarkerPos(int type, double x, double y, double dx, double dy) {
this.type = type;
this.x = x;
this.y = y;
this.dx = dx;
this.dy = dy;
}
public void setType(int type) {
this.type = type;
}
public int getType() {
return type;
}
}

View file

@ -1,21 +0,0 @@
package org.xbib.graphics.svg;
import org.xbib.graphics.svg.element.SVGElement;
public class Metadata extends SVGElement {
public static final String TAG_NAME = "metadata";
public Metadata() {
}
@Override
public String getTagName() {
return TAG_NAME;
}
@Override
public boolean updateTime(double curTime) {
return false;
}
}

View file

@ -20,17 +20,17 @@ public class SVGDiagram {
private static final Logger logger = Logger.getLogger(SVGDiagram.class.getName()); private static final Logger logger = Logger.getLogger(SVGDiagram.class.getName());
final Map<String, SVGElement> idMap = new HashMap<>(); private final Map<String, SVGElement> idMap = new HashMap<>();
SVGRoot root; private SVGRoot root;
final SVGUniverse universe; private final SVGUniverse universe;
private final Rectangle deviceViewport = new Rectangle(100, 100); private final Rectangle deviceViewport = new Rectangle(100, 100);
protected boolean ignoreClipHeuristic = false; protected boolean ignoreClipHeuristic = false;
final URI xmlBase; private final URI xmlBase;
public SVGDiagram(URI xmlBase, SVGUniverse universe) { public SVGDiagram(URI xmlBase, SVGUniverse universe) {
this.universe = universe; this.universe = universe;

View file

@ -12,59 +12,47 @@ import java.awt.RenderingHints;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class SVGIcon extends ImageIcon { public class SVGIcon extends ImageIcon {
public static final String PROP_AUTOSIZE = "PROP_AUTOSIZE"; private SVGUniverse svgUniverse = new SVGUniverse();
private final PropertyChangeSupport changes = new PropertyChangeSupport(this); private static final int INTERP_NEAREST_NEIGHBOR = 0;
SVGUniverse svgUniverse = new SVGUniverse(); private static final int INTERP_BILINEAR = 1;
public static final int INTERP_NEAREST_NEIGHBOR = 0; private static final int INTERP_BICUBIC = 2;
public static final int INTERP_BILINEAR = 1; private static final int AUTOSIZE_NONE = 0;
public static final int INTERP_BICUBIC = 2; private static final int AUTOSIZE_HORIZ = 1;
private static final int AUTOSIZE_VERT = 2;
private static final int AUTOSIZE_BESTFIT = 3;
private static final int AUTOSIZE_STRETCH = 4;
private boolean antiAlias; private boolean antiAlias;
private int interpolation = INTERP_NEAREST_NEIGHBOR; private int interpolation = INTERP_NEAREST_NEIGHBOR;
private boolean clipToViewbox; private boolean clipToViewbox;
URI svgURI; private URI svgURI;
AffineTransform scaleXform = new AffineTransform(); private final AffineTransform scaleXform = new AffineTransform();
public static final int AUTOSIZE_NONE = 0;
public static final int AUTOSIZE_HORIZ = 1;
public static final int AUTOSIZE_VERT = 2;
public static final int AUTOSIZE_BESTFIT = 3;
public static final int AUTOSIZE_STRETCH = 4;
private int autosize = AUTOSIZE_NONE; private int autosize = AUTOSIZE_NONE;
Dimension preferredSize; private Dimension preferredSize;
public SVGIcon() { public SVGIcon() {
} }
public void addPropertyChangeListener(PropertyChangeListener p) {
changes.addPropertyChangeListener(p);
}
public void removePropertyChangeListener(PropertyChangeListener p) {
changes.removePropertyChangeListener(p);
}
@Override @Override
public Image getImage() { public Image getImage() {
BufferedImage bi = new BufferedImage(getIconWidth(), getIconHeight(), BufferedImage.TYPE_INT_ARGB); BufferedImage bi = new BufferedImage(getIconWidth(), getIconHeight(), BufferedImage.TYPE_INT_ARGB);
@ -211,7 +199,6 @@ public class SVGIcon extends ImageIcon {
public void setSvgUniverse(SVGUniverse svgUniverse) { public void setSvgUniverse(SVGUniverse svgUniverse) {
SVGUniverse old = this.svgUniverse; SVGUniverse old = this.svgUniverse;
this.svgUniverse = svgUniverse; this.svgUniverse = svgUniverse;
changes.firePropertyChange("svgUniverse", old, svgUniverse);
} }
public URI getSvgURI() { public URI getSvgURI() {
@ -229,14 +216,12 @@ public class SVGIcon extends ImageIcon {
} }
diagram.setDeviceViewport(new Rectangle(0, 0, size.width, size.height)); diagram.setDeviceViewport(new Rectangle(0, 0, size.width, size.height));
} }
changes.firePropertyChange("svgURI", old, svgURI);
} }
public void setSvgResourcePath(String resourcePath) { public void setSvgResourcePath(String resourcePath) {
URI old = this.svgURI; URI old = this.svgURI;
try { try {
svgURI = new URI(getClass().getResource(resourcePath).toString()); svgURI = new URI(getClass().getResource(resourcePath).toString());
changes.firePropertyChange("svgURI", old, svgURI);
SVGDiagram diagram = svgUniverse.getDiagram(svgURI); SVGDiagram diagram = svgUniverse.getDiagram(svgURI);
if (diagram != null) { if (diagram != null) {
diagram.setDeviceViewport(new Rectangle(0, 0, preferredSize.width, preferredSize.height)); diagram.setDeviceViewport(new Rectangle(0, 0, preferredSize.width, preferredSize.height));
@ -272,8 +257,6 @@ public class SVGIcon extends ImageIcon {
if (diagram != null) { if (diagram != null) {
diagram.setDeviceViewport(new Rectangle(0, 0, preferredSize.width, preferredSize.height)); diagram.setDeviceViewport(new Rectangle(0, 0, preferredSize.width, preferredSize.height));
} }
changes.firePropertyChange("preferredSize", old, preferredSize);
} }
public boolean getUseAntiAlias() { public boolean getUseAntiAlias() {
@ -291,7 +274,6 @@ public class SVGIcon extends ImageIcon {
public void setAntiAlias(boolean antiAlias) { public void setAntiAlias(boolean antiAlias) {
boolean old = this.antiAlias; boolean old = this.antiAlias;
this.antiAlias = antiAlias; this.antiAlias = antiAlias;
changes.firePropertyChange("antiAlias", old, antiAlias);
} }
public int getInterpolation() { public int getInterpolation() {
@ -301,7 +283,6 @@ public class SVGIcon extends ImageIcon {
public void setInterpolation(int interpolation) { public void setInterpolation(int interpolation) {
int old = this.interpolation; int old = this.interpolation;
this.interpolation = interpolation; this.interpolation = interpolation;
changes.firePropertyChange("interpolation", old, interpolation);
} }
public boolean isClipToViewbox() { public boolean isClipToViewbox() {
@ -319,6 +300,5 @@ public class SVGIcon extends ImageIcon {
public void setAutosize(int autosize) { public void setAutosize(int autosize) {
int oldAutosize = this.autosize; int oldAutosize = this.autosize;
this.autosize = autosize; this.autosize = autosize;
changes.firePropertyChange(PROP_AUTOSIZE, oldAutosize, autosize);
} }
} }

View file

@ -1,23 +1,40 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg;
import org.xbib.graphics.svg.element.Circle; import org.xbib.graphics.svg.element.A;
import org.xbib.graphics.svg.element.Metadata;
import org.xbib.graphics.svg.element.PatternSVG;
import org.xbib.graphics.svg.element.Stop;
import org.xbib.graphics.svg.element.Symbol;
import org.xbib.graphics.svg.element.Title;
import org.xbib.graphics.svg.element.shape.Circle;
import org.xbib.graphics.svg.element.ClipPath; import org.xbib.graphics.svg.element.ClipPath;
import org.xbib.graphics.svg.element.Defs; import org.xbib.graphics.svg.element.Defs;
import org.xbib.graphics.svg.element.Desc; import org.xbib.graphics.svg.element.Desc;
import org.xbib.graphics.svg.element.Ellipse; import org.xbib.graphics.svg.element.shape.Ellipse;
import org.xbib.graphics.svg.element.Filter; import org.xbib.graphics.svg.element.Filter;
import org.xbib.graphics.svg.element.Font; import org.xbib.graphics.svg.element.Font;
import org.xbib.graphics.svg.element.Group; import org.xbib.graphics.svg.element.FontFace;
import org.xbib.graphics.svg.element.Line; import org.xbib.graphics.svg.element.shape.Group;
import org.xbib.graphics.svg.element.Mask; import org.xbib.graphics.svg.element.Hkern;
import org.xbib.graphics.svg.element.ImageSVG;
import org.xbib.graphics.svg.element.shape.Line;
import org.xbib.graphics.svg.element.shape.Marker;
import org.xbib.graphics.svg.element.shape.Mask;
import org.xbib.graphics.svg.element.SVGElement; import org.xbib.graphics.svg.element.SVGElement;
import org.xbib.graphics.svg.element.ShapeElement; import org.xbib.graphics.svg.element.ShapeElement;
import org.xbib.graphics.svg.element.Style; import org.xbib.graphics.svg.element.Style;
import org.xbib.graphics.svg.element.filtereffects.GaussianBlur; import org.xbib.graphics.svg.element.filtereffects.GaussianBlur;
import org.xbib.graphics.svg.element.glyph.Glyph; import org.xbib.graphics.svg.element.glyph.Glyph;
import org.xbib.graphics.svg.element.glyph.MissingGlyph; import org.xbib.graphics.svg.element.glyph.MissingGlyph;
import org.xbib.graphics.svg.element.gradient.LinearGradient; import org.xbib.graphics.svg.element.gradient.Linear;
import org.xbib.graphics.svg.element.gradient.RadialGradient; import org.xbib.graphics.svg.element.gradient.Radial;
import org.xbib.graphics.svg.element.shape.Path;
import org.xbib.graphics.svg.element.shape.Polygon;
import org.xbib.graphics.svg.element.shape.Polyline;
import org.xbib.graphics.svg.element.shape.Rect;
import org.xbib.graphics.svg.element.shape.Text;
import org.xbib.graphics.svg.element.shape.Tspan;
import org.xbib.graphics.svg.element.shape.Use;
import org.xml.sax.Attributes; import org.xml.sax.Attributes;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.DefaultHandler;
@ -58,7 +75,7 @@ public class SVGLoader extends DefaultHandler {
nodeClasses.put("desc", Desc.class); nodeClasses.put("desc", Desc.class);
nodeClasses.put("ellipse", Ellipse.class); nodeClasses.put("ellipse", Ellipse.class);
nodeClasses.put("filter", Filter.class); nodeClasses.put("filter", Filter.class);
nodeClasses.put(GaussianBlur.TAG_NAME, GaussianBlur.class); nodeClasses.put("fegaussianblur", GaussianBlur.class);
nodeClasses.put("font", Font.class); nodeClasses.put("font", Font.class);
nodeClasses.put("font-face", FontFace.class); nodeClasses.put("font-face", FontFace.class);
nodeClasses.put("g", Group.class); nodeClasses.put("g", Group.class);
@ -66,7 +83,7 @@ public class SVGLoader extends DefaultHandler {
nodeClasses.put("hkern", Hkern.class); nodeClasses.put("hkern", Hkern.class);
nodeClasses.put("image", ImageSVG.class); nodeClasses.put("image", ImageSVG.class);
nodeClasses.put("line", Line.class); nodeClasses.put("line", Line.class);
nodeClasses.put("lineargradient", LinearGradient.class); nodeClasses.put("lineargradient", Linear.class);
nodeClasses.put("marker", Marker.class); nodeClasses.put("marker", Marker.class);
nodeClasses.put("mask", Mask.class); nodeClasses.put("mask", Mask.class);
nodeClasses.put("metadata", Metadata.class); nodeClasses.put("metadata", Metadata.class);
@ -75,7 +92,7 @@ public class SVGLoader extends DefaultHandler {
nodeClasses.put("pattern", PatternSVG.class); nodeClasses.put("pattern", PatternSVG.class);
nodeClasses.put("polygon", Polygon.class); nodeClasses.put("polygon", Polygon.class);
nodeClasses.put("polyline", Polyline.class); nodeClasses.put("polyline", Polyline.class);
nodeClasses.put("radialgradient", RadialGradient.class); nodeClasses.put("radialgradient", Radial.class);
nodeClasses.put("rect", Rect.class); nodeClasses.put("rect", Rect.class);
nodeClasses.put("shape", ShapeElement.class); nodeClasses.put("shape", ShapeElement.class);
nodeClasses.put("stop", Stop.class); nodeClasses.put("stop", Stop.class);

View file

@ -14,5 +14,4 @@ public class SVGLoaderHelper {
this.universe = universe; this.universe = universe;
this.diagram = diagram; this.diagram = diagram;
} }
} }

View file

@ -1,7 +1,7 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg;
import org.xbib.graphics.svg.element.Defs; import org.xbib.graphics.svg.element.Defs;
import org.xbib.graphics.svg.element.Group; import org.xbib.graphics.svg.element.shape.Group;
import org.xbib.graphics.svg.element.SVGElement; import org.xbib.graphics.svg.element.SVGElement;
import org.xbib.graphics.svg.element.Style; import org.xbib.graphics.svg.element.Style;
import org.xbib.graphics.svg.xml.NumberWithUnits; import org.xbib.graphics.svg.xml.NumberWithUnits;

View file

@ -37,13 +37,11 @@ public class SVGUniverse {
private static final Logger logger = Logger.getLogger(SVGUniverse.class.getName()); private static final Logger logger = Logger.getLogger(SVGUniverse.class.getName());
final Map<URI, SVGDiagram> loadedDocs = new HashMap<>(); private final Map<URI, SVGDiagram> loadedDocs = new HashMap<>();
final Map<String, Font> loadedFonts = new HashMap<>(); private final Map<String, Font> loadedFonts = new HashMap<>();
final Map<URL, SoftReference<BufferedImage>> loadedImages = new HashMap<>(); private final Map<URL, SoftReference<BufferedImage>> loadedImages = new HashMap<>();
public static final String INPUTSTREAM_SCHEME = "svgXbib";
protected double curTime = 0.0; protected double curTime = 0.0;
@ -131,7 +129,7 @@ public class SVGUniverse {
} }
} }
void registerImage(URL imageURL) { public void registerImage(URL imageURL) {
if (loadedImages.containsKey(imageURL)) { if (loadedImages.containsKey(imageURL)) {
return; return;
} }
@ -156,7 +154,7 @@ public class SVGUniverse {
} }
} }
BufferedImage getImage(URL imageURL) throws IOException { public BufferedImage getImage(URL imageURL) throws IOException {
SoftReference<BufferedImage> ref = loadedImages.get(imageURL); SoftReference<BufferedImage> ref = loadedImages.get(imageURL);
if (ref == null) { if (ref == null) {
return null; return null;
@ -202,12 +200,13 @@ public class SVGUniverse {
} }
public SVGElement getElement(URI path, boolean loadIfAbsent) { public SVGElement getElement(URI path, boolean loadIfAbsent) {
path = cleanUri(path);
try { try {
path = cleanUri(path);
URI xmlBase = new URI(path.getScheme(), path.getSchemeSpecificPart(), null); URI xmlBase = new URI(path.getScheme(), path.getSchemeSpecificPart(), null);
SVGDiagram dia = loadedDocs.get(xmlBase); SVGDiagram dia = loadedDocs.get(xmlBase);
if (dia == null && loadIfAbsent) { if (dia == null && loadIfAbsent) {
URL url = xmlBase.toURL(); URL url;
url = xmlBase.toURL();
loadSVG(url, false); loadSVG(url, false);
dia = loadedDocs.get(xmlBase); dia = loadedDocs.get(xmlBase);
if (dia == null) { if (dia == null) {
@ -216,7 +215,7 @@ public class SVGUniverse {
} }
String fragment = path.getFragment(); String fragment = path.getFragment();
return fragment == null ? dia.getRoot() : dia.getElement(fragment); return fragment == null ? dia.getRoot() : dia.getElement(fragment);
} catch (Exception e) { } catch (MalformedURLException | URISyntaxException e) {
logger.log(Level.SEVERE, "Could not parse path " + path, e); logger.log(Level.SEVERE, "Could not parse path " + path, e);
return null; return null;
} }
@ -323,7 +322,7 @@ public class SVGUniverse {
name = '/' + name; name = '/' + name;
} }
try { try {
return new URI(INPUTSTREAM_SCHEME, name, null); return new URI("svg", name, null);
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.SEVERE, "Could not parse", e); logger.log(Level.SEVERE, "Could not parse", e);
return null; return null;

View file

@ -1,6 +1,7 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.element;
import org.xbib.graphics.svg.element.Group; import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.element.shape.Group;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.io.IOException; import java.io.IOException;
@ -8,18 +9,13 @@ import java.net.URI;
public class A extends Group { public class A extends Group {
public static final String TAG_NAME = "a"; private URI href;
URI href; private String title;
String title;
public A() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "a";
} }
@Override @Override

View file

@ -1,28 +1,20 @@
package org.xbib.graphics.svg.element; package org.xbib.graphics.svg.element;
import org.xbib.graphics.svg.SVGException; import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.util.ClipPathConstants;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Shape; import java.awt.Shape;
import java.awt.geom.Area; import java.awt.geom.Area;
import java.io.IOException; import java.io.IOException;
public class ClipPath extends SVGElement { public class ClipPath extends SVGElement implements ClipPathConstants {
public static final String TAG_NAME = "clippath"; private int clipPathUnits = CP_USER_SPACE_ON_USE;
public static final int CP_USER_SPACE_ON_USE = 0;
public static final int CP_OBJECT_BOUNDING_BOX = 1;
int clipPathUnits = CP_USER_SPACE_ON_USE;
public ClipPath() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "clippath";
} }
@Override @Override

View file

@ -7,14 +7,9 @@ import java.io.IOException;
public class Defs extends TransformableElement { public class Defs extends TransformableElement {
public static final String TAG_NAME = "defs";
public Defs() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "defs";
} }
@Override @Override

View file

@ -4,13 +4,11 @@ import org.xbib.graphics.svg.SVGLoaderHelper;
public class Desc extends SVGElement { public class Desc extends SVGElement {
public static final String TAG_NAME = "desc"; private final StringBuilder text = new StringBuilder();
StringBuilder text = new StringBuilder();
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "desc";
} }
@Override @Override

View file

@ -14,38 +14,51 @@ import java.util.List;
public class Filter extends SVGElement { public class Filter extends SVGElement {
public static final String TAG_NAME = "filter"; private static final int FU_OBJECT_BOUNDING_BOX = 0;
public static final int FU_OBJECT_BOUNDING_BOX = 0; private static final int FU_USER_SPACE_ON_USE = 1;
public static final int FU_USER_SPACE_ON_USE = 1; private static final int PU_OBJECT_BOUNDING_BOX = 0;
public int filterUnits = FU_OBJECT_BOUNDING_BOX; private static final int PU_USER_SPACE_ON_USE = 1;
public static final int PU_OBJECT_BOUNDING_BOX = 0; private int filterUnits = FU_OBJECT_BOUNDING_BOX;
public static final int PU_USER_SPACE_ON_USE = 1; private float x = 0f;
protected int primitiveUnits = PU_OBJECT_BOUNDING_BOX; private float y = 0f;
float x = 0f; private float width = 1f;
float y = 0f; private float height = 1f;
float width = 1f; private URL href = null;
float height = 1f; private final List<FilterEffects> filterEffects = new ArrayList<>();
URL href = null;
public final List<FilterEffects> filterEffects = new ArrayList<>();
public Filter() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "filter";
}
public List<FilterEffects> getFilterEffects() {
return filterEffects;
}
public float getX() {
return x;
}
public float getY() {
return y;
}
public float getWidth() {
return width;
}
public float getHeight() {
return height;
} }
@Override @Override
@ -71,11 +84,6 @@ public class Filter extends SVGElement {
} }
if (getPres(sty.setName("primitiveUnits"))) { if (getPres(sty.setName("primitiveUnits"))) {
strn = sty.getStringValue().toLowerCase(); strn = sty.getStringValue().toLowerCase();
if (strn.equals("userspaceonuse")) {
primitiveUnits = PU_USER_SPACE_ON_USE;
} else {
primitiveUnits = PU_OBJECT_BOUNDING_BOX;
}
} }
if (getPres(sty.setName("x"))) { if (getPres(sty.setName("x"))) {
x = sty.getFloatValueWithUnits(); x = sty.getFloatValueWithUnits();
@ -100,22 +108,6 @@ public class Filter extends SVGElement {
} }
public float getX() {
return x;
}
public float getY() {
return y;
}
public float getWidth() {
return width;
}
public float getHeight() {
return height;
}
@Override @Override
public boolean updateTime(double curTime) throws SVGException { public boolean updateTime(double curTime) throws SVGException {
StyleAttribute sty = new StyleAttribute(); StyleAttribute sty = new StyleAttribute();
@ -183,7 +175,6 @@ public class Filter extends SVGElement {
newVal = PU_OBJECT_BOUNDING_BOX; newVal = PU_OBJECT_BOUNDING_BOX;
} }
if (newVal != filterUnits) { if (newVal != filterUnits) {
primitiveUnits = newVal;
stateChange = true; stateChange = true;
} }
} }

View file

@ -1,6 +1,5 @@
package org.xbib.graphics.svg.element; package org.xbib.graphics.svg.element;
import org.xbib.graphics.svg.FontFace;
import org.xbib.graphics.svg.element.glyph.Glyph; import org.xbib.graphics.svg.element.glyph.Glyph;
import org.xbib.graphics.svg.element.glyph.MissingGlyph; import org.xbib.graphics.svg.element.glyph.MissingGlyph;
import org.xbib.graphics.svg.SVGElementException; import org.xbib.graphics.svg.SVGElementException;
@ -15,32 +14,27 @@ import java.util.Map;
public class Font extends SVGElement { public class Font extends SVGElement {
public static final String TAG_NAME = "font"; private int horizOriginX = 0;
int horizOriginX = 0; private int horizOriginY = 0;
int horizOriginY = 0; private int horizAdvX = -1;
int horizAdvX = -1; private int vertOriginX = -1;
int vertOriginX = -1; private int vertOriginY = -1;
int vertOriginY = -1; private int vertAdvY = -1;
int vertAdvY = -1; private FontFace fontFace = null;
FontFace fontFace = null; private MissingGlyph missingGlyph = null;
MissingGlyph missingGlyph = null; private final Map<String, SVGElement> glyphs = new HashMap<>();
final Map<String, SVGElement> glyphs = new HashMap<>();
public Font() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "font";
} }
@Override @Override

View file

@ -1,16 +1,13 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.element;
import org.xbib.graphics.svg.element.Font; import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.element.SVGElement;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.io.IOException; import java.io.IOException;
public class FontFace extends SVGElement { public class FontFace extends SVGElement {
public static final String TAG_NAME = "fontface"; private String fontFamily;
String fontFamily;
private int unitsPerEm = 1000; private int unitsPerEm = 1000;
@ -32,12 +29,9 @@ public class FontFace extends SVGElement {
private int overlineThickness = -1; private int overlineThickness = -1;
public FontFace() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "fontface";
} }
@Override @Override

View file

@ -1,60 +1,23 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.element;
import org.xbib.graphics.svg.element.Font;
import org.xbib.graphics.svg.element.glyph.Glyph; import org.xbib.graphics.svg.element.glyph.Glyph;
import org.xbib.graphics.svg.element.glyph.MissingGlyph; import org.xbib.graphics.svg.element.glyph.MissingGlyph;
import org.xbib.graphics.svg.element.shape.Text;
import java.awt.GraphicsEnvironment;
import java.awt.font.FontRenderContext; import java.awt.font.FontRenderContext;
import java.awt.font.GlyphMetrics; import java.awt.font.GlyphMetrics;
import java.awt.font.GlyphVector; import java.awt.font.GlyphVector;
import java.awt.font.LineMetrics; import java.awt.font.LineMetrics;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set;
public class FontSystem extends Font { public class FontSystem extends Font {
java.awt.Font sysFont; private final java.awt.Font sysFont;
Map<String, Glyph> glyphCache = new HashMap<>(); private final Map<String, Glyph> glyphCache = new HashMap<>();
static Set<String> sysFontNames = new HashSet<>(); public FontSystem(String fontFamily, int fontStyle, int fontWeight, float fontSize) {
public static boolean checkIfSystemFontExists(String fontName) {
if (sysFontNames.isEmpty()) {
Collections.addAll(sysFontNames, GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(Locale.ENGLISH));
}
return sysFontNames.contains(fontName);
}
public static FontSystem createFont(String[] fontFamilies, int fontStyle, int fontWeight, float fontSize) {
for (String fontName : fontFamilies) {
String javaFontName = mapJavaFontName(fontName);
if (checkIfSystemFontExists(javaFontName)) {
return new FontSystem(javaFontName, fontStyle, fontWeight, fontSize);
}
}
return null;
}
private static String mapJavaFontName(String fontName) {
if ("serif".equals(fontName)) {
return java.awt.Font.SERIF;
} else if ("sans-serif".equals(fontName)) {
return java.awt.Font.SANS_SERIF;
} else if ("monospace".equals(fontName)) {
return java.awt.Font.MONOSPACED;
}
return fontName;
}
private FontSystem(String fontFamily, int fontStyle, int fontWeight, float fontSize) {
int style; int style;
if (fontStyle == Text.TXST_ITALIC) { if (fontStyle == Text.TXST_ITALIC) {
style = java.awt.Font.ITALIC; style = java.awt.Font.ITALIC;

View file

@ -0,0 +1,23 @@
package org.xbib.graphics.svg.element;
import org.xbib.graphics.svg.SVGException;
import java.io.IOException;
public class Hkern extends SVGElement {
@Override
public String getTagName() {
return "hkern";
}
@Override
protected void build() throws SVGException, IOException {
super.build();
}
@Override
public boolean updateTime(double curTime) throws SVGException {
return false;
}
}

View file

@ -1,7 +1,7 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.element;
import org.xbib.graphics.svg.element.RenderableElement; import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.element.SVGElement; import org.xbib.graphics.svg.util.Handler;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.AlphaComposite; import java.awt.AlphaComposite;
@ -22,28 +22,23 @@ public class ImageSVG extends RenderableElement {
private static final Logger logger = Logger.getLogger(ImageSVG.class.getName()); private static final Logger logger = Logger.getLogger(ImageSVG.class.getName());
public static final String TAG_NAME = "image"; private float x = 0f;
float x = 0f; private float y = 0f;
float y = 0f; private float width = 0f;
float width = 0f; private float height = 0f;
float height = 0f; private URL imageSrc = null;
URL imageSrc = null; private AffineTransform xform;
AffineTransform xform; private Rectangle2D bounds;
Rectangle2D bounds;
public ImageSVG() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "image";
} }
@Override @Override
@ -223,7 +218,7 @@ public class ImageSVG extends RenderableElement {
logger.log(Level.SEVERE, "Image provided with illegal value for href: \"" logger.log(Level.SEVERE, "Image provided with illegal value for href: \""
+ sty.getStringValue() + '"', ie); + sty.getStringValue() + '"', ie);
} catch (Exception e) { } catch (Exception e) {
logger.log(Level.WARNING, "Could not parse xlink:href", e); logger.log(Level.SEVERE, "Could not parse xlink:href", e);
} }
if (shapeChange) { if (shapeChange) {
build(); build();

View file

@ -0,0 +1,14 @@
package org.xbib.graphics.svg.element;
public class Metadata extends SVGElement {
@Override
public String getTagName() {
return "metadata";
}
@Override
public boolean updateTime(double curTime) {
return false;
}
}

View file

@ -1,8 +1,9 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.element;
import org.xbib.graphics.svg.element.FillElement; import org.xbib.graphics.svg.util.PatternPaint;
import org.xbib.graphics.svg.element.RenderableElement; import org.xbib.graphics.svg.SVGElementException;
import org.xbib.graphics.svg.element.SVGElement; import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.SVGLoaderHelper;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Graphics2D; import java.awt.Graphics2D;
@ -18,34 +19,29 @@ import java.net.URI;
public class PatternSVG extends FillElement { public class PatternSVG extends FillElement {
public static final String TAG_NAME = "pattern";
public static final int GU_OBJECT_BOUNDING_BOX = 0; public static final int GU_OBJECT_BOUNDING_BOX = 0;
public static final int GU_USER_SPACE_ON_USE = 1; public static final int GU_USER_SPACE_ON_USE = 1;
int gradientUnits = GU_OBJECT_BOUNDING_BOX; private int gradientUnits = GU_OBJECT_BOUNDING_BOX;
float x; private float x;
float y; private float y;
float width; private float width;
float height; private float height;
AffineTransform patternXform = new AffineTransform(); private AffineTransform patternXform = new AffineTransform();
Rectangle2D.Float viewBox; private Rectangle2D.Float viewBox;
Paint texPaint; private Paint texPaint;
public PatternSVG() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "pattern";
} }
@Override @Override

View file

@ -1,8 +1,11 @@
package org.xbib.graphics.svg.element; package org.xbib.graphics.svg.element;
import org.xbib.graphics.svg.SVGException; import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.element.shape.Mask;
import org.xbib.graphics.svg.util.ClipPathConstants;
import org.xbib.graphics.svg.util.PaintCache; import org.xbib.graphics.svg.util.PaintCache;
import org.xbib.graphics.svg.util.PaintUtil; import org.xbib.graphics.svg.util.PaintUtil;
import org.xbib.graphics.svg.util.VectorEffect;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Graphics2D; import java.awt.Graphics2D;
@ -15,19 +18,15 @@ import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.util.List; import java.util.List;
public abstract class RenderableElement extends TransformableElement { public abstract class RenderableElement extends TransformableElement implements VectorEffect {
protected AffineTransform cachedXform = null; protected AffineTransform cachedXform;
public Mask cachedMask; private Mask cachedMask;
public Filter filter; private Filter filter;
protected Shape cachedClip = null; private Shape cachedClip;
public static final int VECTOR_EFFECT_NONE = 0;
public static final int VECTOR_EFFECT_NON_SCALING_STROKE = 1;
protected int vectorEffect; protected int vectorEffect;
@ -40,6 +39,14 @@ public abstract class RenderableElement extends TransformableElement {
super(id, parent); super(id, parent);
} }
public Mask getCachedMask() {
return cachedMask;
}
public Filter getFilter() {
return filter;
}
public PaintCache getBufferCache() { public PaintCache getBufferCache() {
return bufferCache; return bufferCache;
} }
@ -100,7 +107,7 @@ public abstract class RenderableElement extends TransformableElement {
} }
StyleAttribute styleAttrib = new StyleAttribute(); StyleAttribute styleAttrib = new StyleAttribute();
Shape clipPath = null; Shape clipPath = null;
int clipPathUnits = ClipPath.CP_USER_SPACE_ON_USE; int clipPathUnits = ClipPathConstants.CP_USER_SPACE_ON_USE;
if (getStyle(styleAttrib.setName("clip-path"), false) if (getStyle(styleAttrib.setName("clip-path"), false)
&& !"none".equals(styleAttrib.getStringValue())) { && !"none".equals(styleAttrib.getStringValue())) {
URI uri = styleAttrib.getURIValue(getXMLBase()); URI uri = styleAttrib.getURIValue(getXMLBase());
@ -111,7 +118,7 @@ public abstract class RenderableElement extends TransformableElement {
} }
} }
if (clipPath != null) { if (clipPath != null) {
if (clipPathUnits == ClipPath.CP_OBJECT_BOUNDING_BOX && (this instanceof ShapeElement)) { if (clipPathUnits == ClipPathConstants.CP_OBJECT_BOUNDING_BOX && (this instanceof ShapeElement)) {
Rectangle2D rect = this.getBoundingBox(); Rectangle2D rect = this.getBoundingBox();
AffineTransform at = new AffineTransform(); AffineTransform at = new AffineTransform();
at.scale(rect.getWidth(), rect.getHeight()); at.scale(rect.getWidth(), rect.getHeight());

View file

@ -24,6 +24,7 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -32,26 +33,26 @@ public abstract class SVGElement {
public static final String SVG_NS = "http://www.w3.org/2000/svg"; public static final String SVG_NS = "http://www.w3.org/2000/svg";
LinkedList<SVGElement> contexts = new LinkedList<>(); private static final Pattern TRANSFORM_PATTERN = Pattern.compile("\\w+\\([^)]*\\)");
private final LinkedList<SVGElement> contexts = new LinkedList<>();
protected SVGElement parent; protected SVGElement parent;
protected final ArrayList<SVGElement> children = new ArrayList<>(); protected final List<SVGElement> children = new ArrayList<>();
protected String id; protected String id;
protected String cssClass; protected String cssClass;
protected final HashMap<String, StyleAttribute> inlineStyles = new HashMap<>(); protected final Map<String, StyleAttribute> inlineStyles = new HashMap<>();
protected final HashMap<String, StyleAttribute> presAttribs = new HashMap<>(); protected final Map<String, StyleAttribute> presAttribs = new HashMap<>();
protected URI xmlBase = null; protected URI xmlBase = null;
protected SVGDiagram diagram; protected SVGDiagram diagram;
private static final Pattern TRANSFORM_PATTERN = Pattern.compile("\\w+\\([^)]*\\)");
public SVGElement() { public SVGElement() {
this(null, null, null); this(null, null, null);
} }
@ -131,7 +132,7 @@ public abstract class SVGElement {
this.cssClass = (className == null || className.equals("")) ? null : className.intern(); this.cssClass = (className == null || className.equals("")) ? null : className.intern();
String style = attrs.getValue("style"); String style = attrs.getValue("style");
if (style != null) { if (style != null) {
HashMap<?, ?> map = XMLParseUtil.parseStyle(style, inlineStyles); Map<?, ?> map = XMLParseUtil.parseStyle(style, inlineStyles);
} }
String base = attrs.getValue("xml:base"); String base = attrs.getValue("xml:base");
if (base != null && !base.equals("")) { if (base != null && !base.equals("")) {
@ -294,7 +295,6 @@ public abstract class SVGElement {
while (matchExpression.find()) { while (matchExpression.find()) {
retXform.concatenate(parseSingleTransform(matchExpression.group())); retXform.concatenate(parseSingleTransform(matchExpression.group()));
} }
return retXform; return retXform;
} }

View file

@ -1,9 +1,9 @@
package org.xbib.graphics.svg.element; package org.xbib.graphics.svg.element;
import org.xbib.graphics.svg.Marker; import org.xbib.graphics.svg.util.MarkerLayout;
import org.xbib.graphics.svg.MarkerLayout; import org.xbib.graphics.svg.util.MarkerPos;
import org.xbib.graphics.svg.MarkerPos;
import org.xbib.graphics.svg.SVGException; import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.element.shape.Marker;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.AlphaComposite; import java.awt.AlphaComposite;
@ -24,9 +24,6 @@ public abstract class ShapeElement extends RenderableElement {
protected float strokeWidthScalar = 1f; protected float strokeWidthScalar = 1f;
public ShapeElement() {
}
@Override @Override
public abstract void doRender(Graphics2D g) throws SVGException, IOException; public abstract void doRender(Graphics2D g) throws SVGException, IOException;

View file

@ -1,5 +1,6 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.element;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.element.SVGElement; import org.xbib.graphics.svg.element.SVGElement;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
@ -8,20 +9,30 @@ import java.io.IOException;
public class Stop extends SVGElement { public class Stop extends SVGElement {
public static final String TAG_NAME = "stop"; private float offset = 0f;
public float offset = 0f; private float opacity = 1f;
public float opacity = 1f; private Color color = Color.black;
public Color color = Color.black;
public Stop() { public Stop() {
} }
public float getOffset() {
return offset;
}
public float getOpacity() {
return opacity;
}
public Color getColor() {
return color;
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "stop";
} }
@Override @Override

View file

@ -10,20 +10,13 @@ import java.io.IOException;
public class Style extends SVGElement { public class Style extends SVGElement {
public static final String TAG_NAME = "style"; private final StringBuilder text = new StringBuilder();
String type; private StyleSheet styleSheet;
StringBuilder text = new StringBuilder();
StyleSheet styleSheet;
public Style() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "style";
} }
@Override @Override
@ -37,7 +30,7 @@ public class Style extends SVGElement {
super.build(); super.build();
StyleAttribute sty = new StyleAttribute(); StyleAttribute sty = new StyleAttribute();
if (getPres(sty.setName("type"))) { if (getPres(sty.setName("type"))) {
type = sty.getStringValue(); String type = sty.getStringValue();
} }
} }

View file

@ -1,6 +1,7 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.element;
import org.xbib.graphics.svg.element.Group; import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.element.shape.Group;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Graphics2D; import java.awt.Graphics2D;
@ -12,18 +13,13 @@ import java.io.IOException;
public class Symbol extends Group { public class Symbol extends Group {
public static final String TAG_NAME = "symbol"; private AffineTransform viewXform;
AffineTransform viewXform; private Rectangle2D viewBox;
Rectangle2D viewBox;
public Symbol() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "symbol";
} }
@Override @Override

View file

@ -1,19 +1,15 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.element;
import org.xbib.graphics.svg.element.SVGElement; import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.SVGLoaderHelper;
public class Title extends SVGElement { public class Title extends SVGElement {
public static final String TAG_NAME = "title"; private final StringBuilder text = new StringBuilder();
StringBuilder text = new StringBuilder();
public Title() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "title";
} }
@Override @Override

View file

@ -7,15 +7,13 @@ import java.io.IOException;
public class DistantLight extends Light { public class DistantLight extends Light {
public static final String TAG_NAME = "fedistantlight"; private float azimuth = 0f;
float azimuth = 0f; private float elevation = 0f;
float elevation = 0f;
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "fedistantlight";
} }
@Override @Override

View file

@ -6,44 +6,26 @@ import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI; import java.net.URI;
import java.net.URL; import java.net.URL;
import java.util.List; import java.util.List;
public abstract class FilterEffects extends SVGElement { public abstract class FilterEffects extends SVGElement {
public static final String TAG_NAME = "filtereffects"; private float x = 0f;
public static final int FP_SOURCE_GRAPHIC = 0; private float y = 0f;
public static final int FP_SOURCE_ALPHA = 1; private float width = 1f;
public static final int FP_BACKGROUND_IMAGE = 2; private float height = 1f;
public static final int FP_BACKGROUND_ALPHA = 3; private URL href;
public static final int FP_FILL_PAINT = 4;
public static final int FP_STROKE_PAINT = 5;
public static final int FP_CUSTOM = 5;
float x = 0f;
float y = 0f;
float width = 1f;
float height = 1f;
URL href = null;
public FilterEffects() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "filtereffects";
} }
@Override @Override
@ -103,17 +85,18 @@ public abstract class FilterEffects extends SVGElement {
stateChange = true; stateChange = true;
} }
} }
try { if (getPres(sty.setName("xlink:href"))) {
if (getPres(sty.setName("xlink:href"))) { URI src = sty.getURIValue(getXMLBase());
URI src = sty.getURIValue(getXMLBase()); URL newVal;
URL newVal = src.toURL(); try {
if (!newVal.equals(href)) { newVal = src.toURL();
href = newVal; } catch (MalformedURLException e) {
stateChange = true; throw new SVGException(e);
} }
if (!newVal.equals(href)) {
href = newVal;
stateChange = true;
} }
} catch (Exception e) {
throw new SVGException(e);
} }
return stateChange; return stateChange;
} }

View file

@ -5,12 +5,20 @@ import java.awt.image.BufferedImageOp;
public class FilterOp { public class FilterOp {
public final BufferedImageOp op; private final BufferedImageOp op;
public final Rectangle requiredImageBounds; private final Rectangle requiredImageBounds;
public FilterOp(BufferedImageOp op, Rectangle requiredImageBounds) { public FilterOp(BufferedImageOp op, Rectangle requiredImageBounds) {
this.op = op; this.op = op;
this.requiredImageBounds = requiredImageBounds; this.requiredImageBounds = requiredImageBounds;
} }
public BufferedImageOp getOp() {
return op;
}
public Rectangle getRequiredImageBounds() {
return requiredImageBounds;
}
} }

View file

@ -12,8 +12,6 @@ import java.util.List;
public class GaussianBlur extends FilterEffects { public class GaussianBlur extends FilterEffects {
public static final String TAG_NAME = "fegaussianblur";
private float[] stdDeviation; private float[] stdDeviation;
private float xCurrent; private float xCurrent;
@ -26,7 +24,7 @@ public class GaussianBlur extends FilterEffects {
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "fegaussianblur";
} }
@Override @Override
@ -45,14 +43,8 @@ public class GaussianBlur extends FilterEffects {
public List<FilterOp> getOperations(Rectangle inputBounds, float xScale, float yScale) { public List<FilterOp> getOperations(Rectangle inputBounds, float xScale, float yScale) {
float xSigma = xScale * stdDeviation[0]; float xSigma = xScale * stdDeviation[0];
float ySigma = yScale * stdDeviation[Math.min(stdDeviation.length - 1, 1)]; float ySigma = yScale * stdDeviation[Math.min(stdDeviation.length - 1, 1)];
return Arrays.asList( return Arrays.asList(xSigma > 0 ? getGaussianBlurFilter(inputBounds, xSigma, true) : null,
xSigma > 0 ySigma > 0 ? getGaussianBlurFilter(inputBounds, ySigma, false) : null);
? getGaussianBlurFilter(inputBounds, xSigma, true)
: null,
ySigma > 0
? getGaussianBlurFilter(inputBounds, ySigma, false)
: null
);
} }
public FilterOp getGaussianBlurFilter(Rectangle inputBounds, float sigma, boolean horizontal) { public FilterOp getGaussianBlurFilter(Rectangle inputBounds, float sigma, boolean horizontal) {
@ -75,8 +67,7 @@ public class GaussianBlur extends FilterEffects {
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
float distance = middle - i; float distance = middle - i;
distance *= distance; distance *= distance;
data[i] = distance > radius2 data[i] = distance > radius2 ? 0
? 0
: (float) Math.exp(-distance / twoSigmaSquare) / sigmaRoot; : (float) Math.exp(-distance / twoSigmaSquare) / sigmaRoot;
total += data[i]; total += data[i];
} }

View file

@ -2,10 +2,8 @@ package org.xbib.graphics.svg.element.filtereffects;
public abstract class Light extends FilterEffects { public abstract class Light extends FilterEffects {
public static final String TAG_NAME = "feLight";
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "feLight";
} }
} }

View file

@ -7,20 +7,15 @@ import java.io.IOException;
public class PointLight extends Light { public class PointLight extends Light {
public static final String TAG_NAME = "fepointlight"; private float x = 0f;
float x = 0f; private float y = 0f;
float y = 0f; private float z = 0f;
float z = 0f;
public PointLight() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "fepointlight";
} }
@Override @Override

View file

@ -7,27 +7,25 @@ import java.io.IOException;
public class SpotLight extends Light { public class SpotLight extends Light {
public static final String TAG_NAME = "fespotlight"; private float x = 0f;
float x = 0f; private float y = 0f;
float y = 0f; private float z = 0f;
float z = 0f; private float pointsAtX = 0f;
float pointsAtX = 0f; private float pointsAtY = 0f;
float pointsAtY = 0f; private float pointsAtZ = 0f;
float pointsAtZ = 0f; private float specularComponent = 0f;
float specularComponent = 0f; private float limitingConeAngle = 0f;
float limitingConeAngle = 0f;
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "fespotlight";
} }
@Override @Override

View file

@ -7,16 +7,11 @@ import java.io.IOException;
public class Glyph extends MissingGlyph { public class Glyph extends MissingGlyph {
public static final String TAG_NAME = "missingglyph"; private String unicode;
String unicode;
public Glyph() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "glyph";
} }
@Override @Override

View file

@ -20,8 +20,6 @@ import java.io.IOException;
public class MissingGlyph extends ShapeElement { public class MissingGlyph extends ShapeElement {
public static final String TAG_NAME = "missingglyph";
private Shape path = null; private Shape path = null;
private float horizAdvX = -1; private float horizAdvX = -1;
@ -32,12 +30,9 @@ public class MissingGlyph extends ShapeElement {
private float vertAdvY = -1; private float vertAdvY = -1;
public MissingGlyph() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "missingglyph";
} }
@Override @Override

View file

@ -3,7 +3,7 @@ package org.xbib.graphics.svg.element.gradient;
import org.xbib.graphics.svg.SVGElementException; import org.xbib.graphics.svg.SVGElementException;
import org.xbib.graphics.svg.SVGException; import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.SVGLoaderHelper; import org.xbib.graphics.svg.SVGLoaderHelper;
import org.xbib.graphics.svg.Stop; import org.xbib.graphics.svg.element.Stop;
import org.xbib.graphics.svg.element.FillElement; import org.xbib.graphics.svg.element.FillElement;
import org.xbib.graphics.svg.element.SVGElement; import org.xbib.graphics.svg.element.SVGElement;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
@ -17,38 +17,33 @@ import java.util.List;
public abstract class Gradient extends FillElement { public abstract class Gradient extends FillElement {
public static final String TAG_NAME = "gradient"; protected static final int SM_PAD = 0;
public static final int SM_PAD = 0; protected static final int SM_REPEAT = 1;
public static final int SM_REPEAT = 1; protected static final int SM_REFLECT = 2;
public static final int SM_REFLECT = 2; protected int spreadMethod = SM_PAD;
public int spreadMethod = SM_PAD; protected static final int GU_OBJECT_BOUNDING_BOX = 0;
public static final int GU_OBJECT_BOUNDING_BOX = 0; protected static final int GU_USER_SPACE_ON_USE = 1;
public static final int GU_USER_SPACE_ON_USE = 1;
protected int gradientUnits = GU_OBJECT_BOUNDING_BOX; protected int gradientUnits = GU_OBJECT_BOUNDING_BOX;
List<Stop> stops = new ArrayList<>(); private final List<Stop> stops = new ArrayList<>();
URI stopRef = null; private URI stopRef = null;
protected AffineTransform gradientTransform = null; protected AffineTransform gradientTransform = null;
float[] stopFractions; private float[] stopFractions;
Color[] stopColors; private Color[] stopColors;
public Gradient() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "gradient";
} }
@Override @Override
@ -100,9 +95,9 @@ public abstract class Gradient extends FillElement {
private void buildStops() { private void buildStops() {
ArrayList<Stop> stopList = new ArrayList<>(stops); ArrayList<Stop> stopList = new ArrayList<>(stops);
stopList.sort((o1, o2) -> Float.compare(o1.offset, o2.offset)); stopList.sort((o1, o2) -> Float.compare(o1.getOffset(), o2.getOffset()));
for (int i = stopList.size() - 2; i >= 0; --i) { for (int i = stopList.size() - 2; i >= 0; --i) {
if (stopList.get(i + 1).offset == stopList.get(i).offset) { if (stopList.get(i + 1).getOffset() == stopList.get(i).getOffset()) {
stopList.remove(i + 1); stopList.remove(i + 1);
} }
} }
@ -110,10 +105,10 @@ public abstract class Gradient extends FillElement {
stopColors = new Color[stopList.size()]; stopColors = new Color[stopList.size()];
int idx = 0; int idx = 0;
for (Stop stop : stopList) { for (Stop stop : stopList) {
int stopColorVal = stop.color.getRGB(); int stopColorVal = stop.getColor().getRGB();
Color stopColor = new Color((stopColorVal >> 16) & 0xff, (stopColorVal >> 8) & 0xff, stopColorVal & 0xff, clamp((int) (stop.opacity * 255), 0, 255)); Color stopColor = new Color((stopColorVal >> 16) & 0xff, (stopColorVal >> 8) & 0xff, stopColorVal & 0xff, clamp((int) (stop.getOpacity() * 255), 0, 255));
stopColors[idx] = stopColor; stopColors[idx] = stopColor;
stopFractions[idx] = stop.offset; stopFractions[idx] = stop.getOffset();
idx++; idx++;
} }
} }

View file

@ -1,7 +1,6 @@
package org.xbib.graphics.svg.element.gradient; package org.xbib.graphics.svg.element.gradient;
import org.xbib.graphics.svg.SVGException; import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.element.gradient.Gradient;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Color; import java.awt.Color;
@ -13,24 +12,19 @@ import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.io.IOException; import java.io.IOException;
public class LinearGradient extends Gradient { public class Linear extends Gradient {
public static final String TAG_NAME = "lineargradient"; private float x1 = 0f;
float x1 = 0f; private float y1 = 0f;
float y1 = 0f; private float x2 = 1f;
float x2 = 1f; private float y2 = 0f;
float y2 = 0f;
public LinearGradient() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "lineargradient";
} }
@Override @Override

View file

@ -1,7 +1,6 @@
package org.xbib.graphics.svg.element.gradient; package org.xbib.graphics.svg.element.gradient;
import org.xbib.graphics.svg.SVGException; import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.element.gradient.Gradient;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Color; import java.awt.Color;
@ -13,28 +12,23 @@ import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.io.IOException; import java.io.IOException;
public class RadialGradient extends Gradient { public class Radial extends Gradient {
public static final String TAG_NAME = "radialgradient"; private float cx = 0.5f;
float cx = 0.5f; private float cy = 0.5f;
float cy = 0.5f; private boolean hasFocus = false;
boolean hasFocus = false; private float fx = 0f;
float fx = 0f; private float fy = 0f;
float fy = 0f; private float r = 0.5f;
float r = 0.5f;
public RadialGradient() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "radialgradient";
} }
@Override @Override

View file

@ -1,6 +1,7 @@
package org.xbib.graphics.svg.element; package org.xbib.graphics.svg.element.shape;
import org.xbib.graphics.svg.SVGException; import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.element.ShapeElement;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Graphics2D; import java.awt.Graphics2D;
@ -11,22 +12,17 @@ import java.io.IOException;
public class Circle extends ShapeElement { public class Circle extends ShapeElement {
public static final String TAG_NAME = "circle"; private float cx = 0f;
float cx = 0f; private float cy = 0f;
float cy = 0f; private float r = 0f;
float r = 0f; private final Ellipse2D.Float circle = new Ellipse2D.Float();
Ellipse2D.Float circle = new Ellipse2D.Float();
public Circle() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "circle";
} }
@Override @Override

View file

@ -1,6 +1,7 @@
package org.xbib.graphics.svg.element; package org.xbib.graphics.svg.element.shape;
import org.xbib.graphics.svg.SVGException; import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.element.ShapeElement;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Graphics2D; import java.awt.Graphics2D;
@ -11,24 +12,19 @@ import java.io.IOException;
public class Ellipse extends ShapeElement { public class Ellipse extends ShapeElement {
public static final String TAG_NAME = "ellipse"; private float cx = 0.0f;
float cx = 0.0f; private float cy = 0.0f;
float cy = 0.0f; private float rx = 0.0f;
float rx = 0.0f; private float ry = 0.0f;
float ry = 0.0f; private final Ellipse2D.Float ellipse = new Ellipse2D.Float();
Ellipse2D.Float ellipse = new Ellipse2D.Float();
public Ellipse() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "ellipse";
} }
@Override @Override

View file

@ -1,8 +1,11 @@
package org.xbib.graphics.svg.element; package org.xbib.graphics.svg.element.shape;
import org.xbib.graphics.svg.SVGElementException; import org.xbib.graphics.svg.SVGElementException;
import org.xbib.graphics.svg.SVGException; import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.SVGLoaderHelper; import org.xbib.graphics.svg.SVGLoaderHelper;
import org.xbib.graphics.svg.element.RenderableElement;
import org.xbib.graphics.svg.element.SVGElement;
import org.xbib.graphics.svg.element.ShapeElement;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Graphics2D; import java.awt.Graphics2D;
@ -18,18 +21,13 @@ import java.util.List;
public class Group extends ShapeElement { public class Group extends ShapeElement {
public static final String TAG_NAME = "group"; private Rectangle2D boundingBox;
Rectangle2D boundingBox; private Shape cachedShape;
Shape cachedShape;
public Group() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "group";
} }
@Override @Override

View file

@ -1,4 +1,4 @@
package org.xbib.graphics.svg.element; package org.xbib.graphics.svg.element.shape;
import org.xbib.graphics.svg.SVGException; import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.element.ShapeElement; import org.xbib.graphics.svg.element.ShapeElement;
@ -12,24 +12,19 @@ import java.io.IOException;
public class Line extends ShapeElement { public class Line extends ShapeElement {
public static final String TAG_NAME = "line"; private float x1 = 0f;
float x1 = 0f; private float y1 = 0f;
float y1 = 0f; private float x2 = 0f;
float x2 = 0f; private float y2 = 0f;
float y2 = 0f; private Line2D.Float line;
Line2D.Float line;
public Line() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "line";
} }
@Override @Override

View file

@ -1,6 +1,7 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.element.shape;
import org.xbib.graphics.svg.element.Group; import org.xbib.graphics.svg.util.MarkerPos;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Graphics2D; import java.awt.Graphics2D;
@ -12,35 +13,29 @@ import java.io.IOException;
public class Marker extends Group { public class Marker extends Group {
public static final String TAG_NAME = "marker";
public static final int MARKER_START = 0; public static final int MARKER_START = 0;
public static final int MARKER_MID = 1; public static final int MARKER_MID = 1;
public static final int MARKER_END = 2; public static final int MARKER_END = 2;
AffineTransform viewXform; private AffineTransform markerXform;
AffineTransform markerXform; private Rectangle2D viewBox;
Rectangle2D viewBox; private float refX;
float refX; private float refY;
float refY; private float markerWidth = 1;
float markerWidth = 1; private float markerHeight = 1;
float markerHeight = 1; private boolean markerUnitsStrokeWidth = true;
float orient = Float.NaN;
boolean markerUnitsStrokeWidth = true;
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "marker";
} }
@Override @Override
@ -59,14 +54,6 @@ public class Marker extends Group {
if (getPres(sty.setName("markerHeight"))) { if (getPres(sty.setName("markerHeight"))) {
markerHeight = sty.getFloatValueWithUnits(); markerHeight = sty.getFloatValueWithUnits();
} }
if (getPres(sty.setName("orient"))) {
if ("auto".equals(sty.getStringValue())) {
orient = Float.NaN;
} else {
orient = sty.getFloatValue();
}
}
if (getPres(sty.setName("viewBox"))) { if (getPres(sty.setName("viewBox"))) {
float[] dim = sty.getFloatList(); float[] dim = sty.getFloatList();
viewBox = new Rectangle2D.Float(dim[0], dim[1], dim[2], dim[3]); viewBox = new Rectangle2D.Float(dim[0], dim[1], dim[2], dim[3]);
@ -80,7 +67,7 @@ public class Marker extends Group {
markerUnitsStrokeWidth = false; markerUnitsStrokeWidth = false;
} }
} }
viewXform = new AffineTransform(); AffineTransform viewXform = new AffineTransform();
viewXform.scale(1.0 / viewBox.getWidth(), 1.0 / viewBox.getHeight()); viewXform.scale(1.0 / viewBox.getWidth(), 1.0 / viewBox.getHeight());
viewXform.translate(-viewBox.getX(), -viewBox.getY()); viewXform.translate(-viewBox.getX(), -viewBox.getY());
markerXform = new AffineTransform(); markerXform = new AffineTransform();
@ -106,11 +93,11 @@ public class Marker extends Group {
public void render(Graphics2D g, MarkerPos pos, float strokeWidth) throws SVGException, IOException { public void render(Graphics2D g, MarkerPos pos, float strokeWidth) throws SVGException, IOException {
AffineTransform cacheXform = g.getTransform(); AffineTransform cacheXform = g.getTransform();
g.translate(pos.x, pos.y); g.translate(pos.getX(), pos.getY());
if (markerUnitsStrokeWidth) { if (markerUnitsStrokeWidth) {
g.scale(strokeWidth, strokeWidth); g.scale(strokeWidth, strokeWidth);
} }
g.rotate(Math.atan2(pos.dy, pos.dx)); g.rotate(Math.atan2(pos.getDy(), pos.getDx()));
g.transform(markerXform); g.transform(markerXform);
super.doRender(g); super.doRender(g);
g.setTransform(cacheXform); g.setTransform(cacheXform);

View file

@ -1,7 +1,6 @@
package org.xbib.graphics.svg.element; package org.xbib.graphics.svg.element.shape;
import org.xbib.graphics.svg.SVGException; import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.element.Group;
import org.xbib.graphics.svg.element.RenderableElement; import org.xbib.graphics.svg.element.RenderableElement;
import org.xbib.graphics.svg.element.SVGElement; import org.xbib.graphics.svg.element.SVGElement;
import org.xbib.graphics.svg.util.PaintUtil; import org.xbib.graphics.svg.util.PaintUtil;
@ -25,11 +24,9 @@ import java.util.List;
public class Mask extends Group { public class Mask extends Group {
public static final String TAG_NAME = "mask";
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "mask";
} }
@Override @Override

View file

@ -1,5 +1,6 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.element.shape;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.element.ShapeElement; import org.xbib.graphics.svg.element.ShapeElement;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
@ -11,20 +12,15 @@ import java.io.IOException;
public class Path extends ShapeElement { public class Path extends ShapeElement {
public static final String TAG_NAME = "path"; private int fillRule = GeneralPath.WIND_NON_ZERO;
int fillRule = GeneralPath.WIND_NON_ZERO; private String d = "";
String d = ""; private GeneralPath path;
GeneralPath path;
public Path() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "path";
} }
@Override @Override

View file

@ -1,5 +1,6 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.element.shape;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.element.ShapeElement; import org.xbib.graphics.svg.element.ShapeElement;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import org.xbib.graphics.svg.xml.XMLParseUtil; import org.xbib.graphics.svg.xml.XMLParseUtil;
@ -12,43 +13,32 @@ import java.io.IOException;
public class Polygon extends ShapeElement { public class Polygon extends ShapeElement {
public static final String TAG_NAME = "polygon"; private int fillRule = GeneralPath.WIND_NON_ZERO;
int fillRule = GeneralPath.WIND_NON_ZERO; private String pointsStrn = "";
String pointsStrn = "";
GeneralPath path;
/** private GeneralPath path;
* Creates a new instance of Rect
*/
public Polygon() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "polygon";
} }
@Override @Override
protected void build() throws SVGException, IOException { protected void build() throws SVGException, IOException {
super.build(); super.build();
StyleAttribute sty = new StyleAttribute(); StyleAttribute sty = new StyleAttribute();
if (getPres(sty.setName("points"))) { if (getPres(sty.setName("points"))) {
pointsStrn = sty.getStringValue(); pointsStrn = sty.getStringValue();
} }
String fillRuleStrn = getStyle(sty.setName("fill-rule")) ? sty.getStringValue() : "nonzero"; String fillRuleStrn = getStyle(sty.setName("fill-rule")) ? sty.getStringValue() : "nonzero";
fillRule = fillRuleStrn.equals("evenodd") ? GeneralPath.WIND_EVEN_ODD : GeneralPath.WIND_NON_ZERO; fillRule = fillRuleStrn.equals("evenodd") ? GeneralPath.WIND_EVEN_ODD : GeneralPath.WIND_NON_ZERO;
buildPath(); buildPath();
} }
protected void buildPath() { protected void buildPath() {
float[] points = XMLParseUtil.parseFloatList(pointsStrn); float[] points = XMLParseUtil.parseFloatList(pointsStrn);
path = new GeneralPath(fillRule, points.length / 2); path = new GeneralPath(fillRule, points.length / 2);
path.moveTo(points[0], points[1]); path.moveTo(points[0], points[1]);
for (int i = 2; i < points.length; i += 2) { for (int i = 2; i < points.length; i += 2) {
path.lineTo(points[i], points[i + 1]); path.lineTo(points[i], points[i + 1]);
@ -73,22 +63,11 @@ public class Polygon extends ShapeElement {
return boundsToParent(includeStrokeInBounds(path.getBounds2D())); return boundsToParent(includeStrokeInBounds(path.getBounds2D()));
} }
/**
* Updates all attributes in this diagram associated with a time event. Ie,
* all attributes with track information.
*
* @return - true if this node has changed state as a result of the time
* update
*/
@Override @Override
public boolean updateTime(double curTime) throws SVGException, IOException { public boolean updateTime(double curTime) throws SVGException, IOException {
// if (trackManager.getNumTracks() == 0) return false;
boolean changeState = super.updateTime(curTime); boolean changeState = super.updateTime(curTime);
//Get current values for parameters
StyleAttribute sty = new StyleAttribute(); StyleAttribute sty = new StyleAttribute();
boolean shapeChange = false; boolean shapeChange = false;
if (getStyle(sty.setName("fill-rule"))) { if (getStyle(sty.setName("fill-rule"))) {
int newVal = sty.getStringValue().equals("evenodd") int newVal = sty.getStringValue().equals("evenodd")
? GeneralPath.WIND_EVEN_ODD ? GeneralPath.WIND_EVEN_ODD
@ -98,7 +77,6 @@ public class Polygon extends ShapeElement {
shapeChange = true; shapeChange = true;
} }
} }
if (getPres(sty.setName("points"))) { if (getPres(sty.setName("points"))) {
String newVal = sty.getStringValue(); String newVal = sty.getStringValue();
if (!newVal.equals(pointsStrn)) { if (!newVal.equals(pointsStrn)) {
@ -106,14 +84,9 @@ public class Polygon extends ShapeElement {
shapeChange = true; shapeChange = true;
} }
} }
if (shapeChange) { if (shapeChange) {
build(); build();
// buildPath();
// return true;
} }
return changeState || shapeChange; return changeState || shapeChange;
} }
} }

View file

@ -1,5 +1,6 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.element.shape;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.element.ShapeElement; import org.xbib.graphics.svg.element.ShapeElement;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import org.xbib.graphics.svg.xml.XMLParseUtil; import org.xbib.graphics.svg.xml.XMLParseUtil;
@ -12,20 +13,15 @@ import java.io.IOException;
public class Polyline extends ShapeElement { public class Polyline extends ShapeElement {
public static final String TAG_NAME = "polyline"; private int fillRule = GeneralPath.WIND_NON_ZERO;
int fillRule = GeneralPath.WIND_NON_ZERO; private String pointsStrn = "";
String pointsStrn = ""; private GeneralPath path;
GeneralPath path;
public Polyline() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "polyline";
} }
@Override @Override

View file

@ -1,5 +1,6 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.element.shape;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.element.ShapeElement; import org.xbib.graphics.svg.element.ShapeElement;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
@ -12,22 +13,23 @@ import java.io.IOException;
public class Rect extends ShapeElement { public class Rect extends ShapeElement {
public static final String TAG_NAME = "rect"; private float x = 0f;
float x = 0f; private float y = 0f;
float y = 0f;
float width = 0f;
float height = 0f;
float rx = 0f;
float ry = 0f;
RectangularShape rect;
public Rect() { private float width = 0f;
}
private float height = 0f;
private float rx = 0f;
private float ry = 0f;
private RectangularShape rect;
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "rect";
} }
@Override @Override

View file

@ -1,6 +1,8 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.element.shape;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.util.FontUtil; import org.xbib.graphics.svg.util.FontUtil;
import org.xbib.graphics.svg.util.TextConst;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
@ -10,56 +12,13 @@ import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
public class Text extends Tspan { public class Text extends Tspan implements TextConst {
public static final String TAG_NAME = "text"; private int textAnchor = TXAN_START;
public static final int TXAN_START = 0;
public static final int TXAN_MIDDLE = 1;
public static final int TXAN_END = 2;
public static final int TXST_NORMAL = 0;
public static final int TXST_ITALIC = 1;
public static final int TXST_OBLIQUE = 2;
public static final int TXWE_NORMAL = 0;
public static final int TXWE_BOLD = 1;
public static final int TXWE_BOLDER = 2;
public static final int TXWE_LIGHTER = 3;
public static final int TXWE_100 = 4;
public static final int TXWE_200 = 5;
public static final int TXWE_300 = 6;
public static final int TXWE_400 = 7;
public static final int TXWE_500 = 8;
public static final int TXWE_600 = 9;
public static final int TXWE_700 = 10;
public static final int TXWE_800 = 11;
public static final int TXWE_900 = 12;
int textAnchor = TXAN_START;
public Text() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "text";
} }
public void rebuild() throws SVGException, IOException { public void rebuild() throws SVGException, IOException {
@ -138,16 +97,16 @@ public class Text extends Tspan {
public boolean updateTime(double curTime) throws SVGException { public boolean updateTime(double curTime) throws SVGException {
boolean changeState = super.updateTime(curTime); boolean changeState = super.updateTime(curTime);
FontUtil.FontInfo fontInfoOld = fontInfo; FontUtil.FontInfo fontInfoOld = fontInfo;
float[] xOld = x; float[] xOld = getX();
float[] yOld = y; float[] yOld = getY();
float[] dxOld = dx; float[] dxOld = getDx();
float[] dyOld = dy; float[] dyOld = getDy();
buildShapeInformation(); buildShapeInformation();
boolean shapeChange = !fontInfo.equals(fontInfoOld) boolean shapeChange = !fontInfo.equals(fontInfoOld)
|| !Arrays.equals(xOld, x) || !Arrays.equals(xOld, getX())
|| !Arrays.equals(yOld, y) || !Arrays.equals(yOld, getY())
|| !Arrays.equals(dxOld, dx) || !Arrays.equals(dxOld, getDx())
|| !Arrays.equals(dyOld, dy); || !Arrays.equals(dyOld, getDy());
if (shapeChange) { if (shapeChange) {
buildText(); buildText();
} }

View file

@ -1,5 +1,8 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.element.shape;
import org.xbib.graphics.svg.SVGElementException;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.SVGLoaderHelper;
import org.xbib.graphics.svg.element.Font; import org.xbib.graphics.svg.element.Font;
import org.xbib.graphics.svg.element.SVGElement; import org.xbib.graphics.svg.element.SVGElement;
import org.xbib.graphics.svg.element.ShapeElement; import org.xbib.graphics.svg.element.ShapeElement;
@ -21,21 +24,15 @@ import java.util.regex.Pattern;
public class Tspan extends ShapeElement { public class Tspan extends ShapeElement {
public static final String TAG_NAME = "tspan"; private float[] x = null;
float[] x = null; private float[] y = null;
float[] y = null; private float[] dx = null;
float[] dx = null; private float[] dy = null;
float[] dy = null; private float[] rotate = null;
float[] rotate = null;
float textLength = -1;
String lengthAdjust = "spacing";
private final List<Object> content = new ArrayList<>(); private final List<Object> content = new ArrayList<>();
@ -49,12 +46,25 @@ public class Tspan extends ShapeElement {
private Font font; private Font font;
public Tspan() { public float[] getDx() {
return dx;
}
public float[] getDy() {
return dy;
}
public float[] getX() {
return x;
}
public float[] getY() {
return y;
} }
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "tspan";
} }
@Override @Override
@ -107,16 +117,6 @@ public class Tspan extends ShapeElement {
rotate[i] = (float) Math.toRadians(this.rotate[i]); rotate[i] = (float) Math.toRadians(this.rotate[i]);
} }
} }
if (getStyle(sty.setName("textLength"))) {
textLength = sty.getFloatValueWithUnits();
} else {
textLength = -1;
}
if (getStyle(sty.setName("lengthAdjust"))) {
lengthAdjust = sty.getStringValue();
} else {
lengthAdjust = "spacing";
}
} }
protected void buildShapeInformation() throws SVGException { protected void buildShapeInformation() throws SVGException {

View file

@ -1,5 +1,6 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.element.shape;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.element.RenderableElement; import org.xbib.graphics.svg.element.RenderableElement;
import org.xbib.graphics.svg.element.SVGElement; import org.xbib.graphics.svg.element.SVGElement;
import org.xbib.graphics.svg.element.ShapeElement; import org.xbib.graphics.svg.element.ShapeElement;
@ -14,26 +15,21 @@ import java.net.URI;
public class Use extends ShapeElement { public class Use extends ShapeElement {
public static final String TAG_NAME = "use"; private float x = 0f;
float x = 0f; private float y = 0f;
float y = 0f; private float width = 1f;
float width = 1f; private float height = 1f;
float height = 1f; private URI href = null;
URI href = null; private AffineTransform refXform;
AffineTransform refXform;
public Use() {
}
@Override @Override
public String getTagName() { public String getTagName() {
return TAG_NAME; return "use";
} }
@Override @Override

View file

@ -7,19 +7,19 @@ import java.awt.geom.GeneralPath;
public class Arc extends PathCommand { public class Arc extends PathCommand {
public float rx = 0f; private float rx = 0f;
public float ry = 0f; private float ry = 0f;
public float xAxisRot = 0f; private float xAxisRot = 0f;
public boolean largeArc = false; private boolean largeArc = false;
public boolean sweep = false; private boolean sweep = false;
public float x = 0f; private float x = 0f;
public float y = 0f; private float y = 0f;
public Arc() { public Arc() {
} }
@ -37,11 +37,11 @@ public class Arc extends PathCommand {
@Override @Override
public void appendPath(GeneralPath path, BuildHistory hist) { public void appendPath(GeneralPath path, BuildHistory hist) {
float offx = isRelative ? hist.lastPoint.x : 0f; float offx = isRelative() ? hist.getLastPoint().x : 0f;
float offy = isRelative ? hist.lastPoint.y : 0f; float offy = isRelative() ? hist.getLastPoint().y : 0f;
arcTo(path, rx, ry, xAxisRot, largeArc, sweep, arcTo(path, rx, ry, xAxisRot, largeArc, sweep,
x + offx, y + offy, x + offx, y + offy,
hist.lastPoint.x, hist.lastPoint.y); hist.getLastPoint().x, hist.getLastPoint().y);
hist.setLastPoint(x + offx, y + offy); hist.setLastPoint(x + offx, y + offy);
hist.setLastKnot(x + offx, y + offy); hist.setLastKnot(x + offx, y + offy);
} }

View file

@ -4,22 +4,33 @@ import java.awt.geom.Point2D;
public class BuildHistory { public class BuildHistory {
Point2D.Float startPoint = new Point2D.Float(); private final Point2D.Float startPoint = new Point2D.Float();
Point2D.Float lastPoint = new Point2D.Float();
Point2D.Float lastKnot = new Point2D.Float();
public BuildHistory() { private final Point2D.Float lastPoint = new Point2D.Float();
}
private final Point2D.Float lastKnot = new Point2D.Float();
public void setStartPoint(float x, float y) { public void setStartPoint(float x, float y) {
startPoint.setLocation(x, y); startPoint.setLocation(x, y);
} }
public Point2D.Float getStartPoint() {
return startPoint;
}
public void setLastPoint(float x, float y) { public void setLastPoint(float x, float y) {
lastPoint.setLocation(x, y); lastPoint.setLocation(x, y);
} }
public Point2D.Float getLastPoint() {
return lastPoint;
}
public void setLastKnot(float x, float y) { public void setLastKnot(float x, float y) {
lastKnot.setLocation(x, y); lastKnot.setLocation(x, y);
} }
public Point2D.Float getLastKnot() {
return lastKnot;
}
} }

View file

@ -4,12 +4,17 @@ import java.awt.geom.GeneralPath;
public class Cubic extends PathCommand { public class Cubic extends PathCommand {
public float k1x = 0f; private float k1x = 0f;
public float k1y = 0f;
public float k2x = 0f; private float k1y = 0f;
public float k2y = 0f;
public float x = 0f; private float k2x = 0f;
public float y = 0f;
private float k2y = 0f;
private float x = 0f;
private float y = 0f;
public Cubic() { public Cubic() {
} }
@ -26,8 +31,8 @@ public class Cubic extends PathCommand {
@Override @Override
public void appendPath(GeneralPath path, BuildHistory hist) { public void appendPath(GeneralPath path, BuildHistory hist) {
float offx = isRelative ? hist.lastPoint.x : 0f; float offx = isRelative() ? hist.getLastPoint().x : 0f;
float offy = isRelative ? hist.lastPoint.y : 0f; float offy = isRelative() ? hist.getLastPoint().y : 0f;
path.curveTo(k1x + offx, k1y + offy, path.curveTo(k1x + offx, k1y + offy,
k2x + offx, k2y + offy, k2x + offx, k2y + offy,
x + offx, y + offy); x + offx, y + offy);

View file

@ -4,13 +4,13 @@ import java.awt.geom.GeneralPath;
public class CubicSmooth extends PathCommand { public class CubicSmooth extends PathCommand {
public float x = 0f; private float x = 0f;
public float y = 0f; private float y = 0f;
public float k2x = 0f; private float k2x = 0f;
public float k2y = 0f; private float k2y = 0f;
public CubicSmooth() { public CubicSmooth() {
} }
@ -25,12 +25,12 @@ public class CubicSmooth extends PathCommand {
@Override @Override
public void appendPath(GeneralPath path, BuildHistory hist) { public void appendPath(GeneralPath path, BuildHistory hist) {
float offx = isRelative ? hist.lastPoint.x : 0f; float offx = isRelative() ? hist.getLastPoint().x : 0f;
float offy = isRelative ? hist.lastPoint.y : 0f; float offy = isRelative() ? hist.getLastPoint().y : 0f;
float oldKx = hist.lastKnot.x; float oldKx = hist.getLastKnot().x;
float oldKy = hist.lastKnot.y; float oldKy = hist.getLastKnot().y;
float oldX = hist.lastPoint.x; float oldX = hist.getLastPoint().x;
float oldY = hist.lastPoint.y; float oldY = hist.getLastPoint().y;
float k1x = oldX * 2f - oldKx; float k1x = oldX * 2f - oldKx;
float k1y = oldY * 2f - oldKy; float k1y = oldY * 2f - oldKy;
path.curveTo(k1x, k1y, k2x + offx, k2y + offy, x + offx, y + offy); path.curveTo(k1x, k1y, k2x + offx, k2y + offy, x + offx, y + offy);

View file

@ -4,15 +4,7 @@ import java.awt.geom.GeneralPath;
public class Horizontal extends PathCommand { public class Horizontal extends PathCommand {
public float x = 0f; private final float x;
public Horizontal() {
}
@Override
public String toString() {
return "H " + x;
}
public Horizontal(boolean isRelative, float x) { public Horizontal(boolean isRelative, float x) {
super(isRelative); super(isRelative);
@ -21,8 +13,8 @@ public class Horizontal extends PathCommand {
@Override @Override
public void appendPath(GeneralPath path, BuildHistory hist) { public void appendPath(GeneralPath path, BuildHistory hist) {
float offx = isRelative ? hist.lastPoint.x : 0f; float offx = isRelative() ? hist.getLastPoint().x : 0f;
float offy = hist.lastPoint.y; float offy = hist.getLastPoint().y;
path.lineTo(x + offx, offy); path.lineTo(x + offx, offy);
hist.setLastPoint(x + offx, offy); hist.setLastPoint(x + offx, offy);
hist.setLastKnot(x + offx, offy); hist.setLastKnot(x + offx, offy);
@ -32,4 +24,9 @@ public class Horizontal extends PathCommand {
public int getNumKnotsAdded() { public int getNumKnotsAdded() {
return 2; return 2;
} }
@Override
public String toString() {
return "H " + x;
}
} }

View file

@ -4,11 +4,9 @@ import java.awt.geom.GeneralPath;
public class LineTo extends PathCommand { public class LineTo extends PathCommand {
public float x = 0f; private final float x;
public float y = 0f;
public LineTo() { private final float y;
}
public LineTo(boolean isRelative, float x, float y) { public LineTo(boolean isRelative, float x, float y) {
super(isRelative); super(isRelative);
@ -18,8 +16,8 @@ public class LineTo extends PathCommand {
@Override @Override
public void appendPath(GeneralPath path, BuildHistory hist) { public void appendPath(GeneralPath path, BuildHistory hist) {
float offx = isRelative ? hist.lastPoint.x : 0f; float offx = isRelative() ? hist.getLastPoint().x : 0f;
float offy = isRelative ? hist.lastPoint.y : 0f; float offy = isRelative() ? hist.getLastPoint().y : 0f;
path.lineTo(x + offx, y + offy); path.lineTo(x + offx, y + offy);
hist.setLastPoint(x + offx, y + offy); hist.setLastPoint(x + offx, y + offy);
hist.setLastKnot(x + offx, y + offy); hist.setLastKnot(x + offx, y + offy);

View file

@ -4,12 +4,9 @@ import java.awt.geom.GeneralPath;
public class MoveTo extends PathCommand { public class MoveTo extends PathCommand {
public float x = 0f; private final float x;
public float y = 0f; private final float y;
public MoveTo() {
}
public MoveTo(boolean isRelative, float x, float y) { public MoveTo(boolean isRelative, float x, float y) {
super(isRelative); super(isRelative);
@ -19,8 +16,8 @@ public class MoveTo extends PathCommand {
@Override @Override
public void appendPath(GeneralPath path, BuildHistory hist) { public void appendPath(GeneralPath path, BuildHistory hist) {
float offx = isRelative ? hist.lastPoint.x : 0f; float offx = isRelative() ? hist.getLastPoint().x : 0f;
float offy = isRelative ? hist.lastPoint.y : 0f; float offy = isRelative() ? hist.getLastPoint().y : 0f;
path.moveTo(x + offx, y + offy); path.moveTo(x + offx, y + offy);
hist.setStartPoint(x + offx, y + offy); hist.setStartPoint(x + offx, y + offy);
hist.setLastPoint(x + offx, y + offy); hist.setLastPoint(x + offx, y + offy);

View file

@ -4,15 +4,20 @@ import java.awt.geom.GeneralPath;
abstract public class PathCommand { abstract public class PathCommand {
public boolean isRelative = false; private final boolean isRelative;
public PathCommand() { public PathCommand() {
this(true);
} }
public PathCommand(boolean isRelative) { public PathCommand(boolean isRelative) {
this.isRelative = isRelative; this.isRelative = isRelative;
} }
public boolean isRelative() {
return isRelative;
}
abstract public void appendPath(GeneralPath path, BuildHistory hist); abstract public void appendPath(GeneralPath path, BuildHistory hist);
abstract public int getNumKnotsAdded(); abstract public int getNumKnotsAdded();

View file

@ -1,42 +0,0 @@
package org.xbib.graphics.svg.pathcmd;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.PathIterator;
public class PathUtil {
public PathUtil() {
}
public static String buildPathString(GeneralPath path) {
float[] coords = new float[6];
StringBuilder sb = new StringBuilder();
for (PathIterator pathIt = path.getPathIterator(new AffineTransform()); !pathIt.isDone(); pathIt.next()) {
int segId = pathIt.currentSegment(coords);
switch (segId) {
case PathIterator.SEG_CLOSE: {
sb.append(" Z");
break;
}
case PathIterator.SEG_CUBICTO: {
sb.append(" C " + coords[0] + " " + coords[1] + " " + coords[2] + " " + coords[3] + " " + coords[4] + " " + coords[5]);
break;
}
case PathIterator.SEG_LINETO: {
sb.append(" L " + coords[0] + " " + coords[1]);
break;
}
case PathIterator.SEG_MOVETO: {
sb.append(" M " + coords[0] + " " + coords[1]);
break;
}
case PathIterator.SEG_QUADTO: {
sb.append(" Q " + coords[0] + " " + coords[1] + " " + coords[2] + " " + coords[3]);
break;
}
}
}
return sb.toString();
}
}

View file

@ -4,16 +4,13 @@ import java.awt.geom.GeneralPath;
public class Quadratic extends PathCommand { public class Quadratic extends PathCommand {
public float kx = 0f; private final float kx;
public float ky = 0f; private final float ky;
public float x = 0f; private final float x;
public float y = 0f; private final float y;
public Quadratic() {
}
public Quadratic(boolean isRelative, float kx, float ky, float x, float y) { public Quadratic(boolean isRelative, float kx, float ky, float x, float y) {
super(isRelative); super(isRelative);
@ -25,8 +22,8 @@ public class Quadratic extends PathCommand {
@Override @Override
public void appendPath(GeneralPath path, BuildHistory hist) { public void appendPath(GeneralPath path, BuildHistory hist) {
float offx = isRelative ? hist.lastPoint.x : 0f; float offx = isRelative() ? hist.getLastPoint().x : 0f;
float offy = isRelative ? hist.lastPoint.y : 0f; float offy = isRelative() ? hist.getLastPoint().y : 0f;
path.quadTo(kx + offx, ky + offy, x + offx, y + offy); path.quadTo(kx + offx, ky + offy, x + offx, y + offy);
hist.setLastPoint(x + offx, y + offy); hist.setLastPoint(x + offx, y + offy);
hist.setLastKnot(kx + offx, ky + offy); hist.setLastKnot(kx + offx, ky + offy);

View file

@ -4,17 +4,9 @@ import java.awt.geom.GeneralPath;
public class QuadraticSmooth extends PathCommand { public class QuadraticSmooth extends PathCommand {
public float x = 0f; private final float x;
public float y = 0f; private final float y;
public QuadraticSmooth() {
}
@Override
public String toString() {
return "T " + x + " " + y;
}
public QuadraticSmooth(boolean isRelative, float x, float y) { public QuadraticSmooth(boolean isRelative, float x, float y) {
super(isRelative); super(isRelative);
@ -24,12 +16,12 @@ public class QuadraticSmooth extends PathCommand {
@Override @Override
public void appendPath(GeneralPath path, BuildHistory hist) { public void appendPath(GeneralPath path, BuildHistory hist) {
float offx = isRelative ? hist.lastPoint.x : 0f; float offx = isRelative() ? hist.getLastPoint().x : 0f;
float offy = isRelative ? hist.lastPoint.y : 0f; float offy = isRelative() ? hist.getLastPoint().y : 0f;
float oldKx = hist.lastKnot.x; float oldKx = hist.getLastKnot().x;
float oldKy = hist.lastKnot.y; float oldKy = hist.getLastKnot().y;
float oldX = hist.lastPoint.x; float oldX = hist.getLastPoint().x;
float oldY = hist.lastPoint.y; float oldY = hist.getLastPoint().y;
float kx = oldX * 2f - oldKx; float kx = oldX * 2f - oldKx;
float ky = oldY * 2f - oldKy; float ky = oldY * 2f - oldKy;
path.quadTo(kx, ky, x + offx, y + offy); path.quadTo(kx, ky, x + offx, y + offy);
@ -41,4 +33,9 @@ public class QuadraticSmooth extends PathCommand {
public int getNumKnotsAdded() { public int getNumKnotsAdded() {
return 4; return 4;
} }
@Override
public String toString() {
return "T " + x + " " + y;
}
} }

View file

@ -4,23 +4,20 @@ import java.awt.geom.GeneralPath;
public class Terminal extends PathCommand { public class Terminal extends PathCommand {
public Terminal() {
}
@Override
public String toString() {
return "Z";
}
@Override @Override
public void appendPath(GeneralPath path, BuildHistory hist) { public void appendPath(GeneralPath path, BuildHistory hist) {
path.closePath(); path.closePath();
hist.setLastPoint(hist.startPoint.x, hist.startPoint.y); hist.setLastPoint(hist.getStartPoint().x, hist.getStartPoint().y);
hist.setLastKnot(hist.startPoint.x, hist.startPoint.y); hist.setLastKnot(hist.getStartPoint().x, hist.getStartPoint().y);
} }
@Override @Override
public int getNumKnotsAdded() { public int getNumKnotsAdded() {
return 0; return 0;
} }
@Override
public String toString() {
return "Z";
}
} }

View file

@ -4,15 +4,7 @@ import java.awt.geom.GeneralPath;
public class Vertical extends PathCommand { public class Vertical extends PathCommand {
public float y = 0f; private final float y;
public Vertical() {
}
@Override
public String toString() {
return "V " + y;
}
public Vertical(boolean isRelative, float y) { public Vertical(boolean isRelative, float y) {
super(isRelative); super(isRelative);
@ -21,8 +13,8 @@ public class Vertical extends PathCommand {
@Override @Override
public void appendPath(GeneralPath path, BuildHistory hist) { public void appendPath(GeneralPath path, BuildHistory hist) {
float offx = hist.lastPoint.x; float offx = hist.getLastPoint().x;
float offy = isRelative ? hist.lastPoint.y : 0f; float offy = isRelative() ? hist.getLastPoint().y : 0f;
path.lineTo(offx, y + offy); path.lineTo(offx, y + offy);
hist.setLastPoint(offx, y + offy); hist.setLastPoint(offx, y + offy);
hist.setLastKnot(offx, y + offy); hist.setLastKnot(offx, y + offy);
@ -32,4 +24,9 @@ public class Vertical extends PathCommand {
public int getNumKnotsAdded() { public int getNumKnotsAdded() {
return 2; return 2;
} }
@Override
public String toString() {
return "V " + y;
}
} }

View file

@ -1,4 +1,4 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.util;
import java.awt.Composite; import java.awt.Composite;
import java.awt.CompositeContext; import java.awt.CompositeContext;

View file

@ -1,4 +1,4 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.util;
import java.awt.CompositeContext; import java.awt.CompositeContext;
import java.awt.image.Raster; import java.awt.image.Raster;

View file

@ -0,0 +1,7 @@
package org.xbib.graphics.svg.util;
public interface ClipPathConstants {
int CP_USER_SPACE_ON_USE = 0;
int CP_OBJECT_BOUNDING_BOX = 1;
}

View file

@ -1,15 +1,20 @@
package org.xbib.graphics.svg.util; package org.xbib.graphics.svg.util;
import org.xbib.graphics.svg.element.Font; import org.xbib.graphics.svg.element.Font;
import org.xbib.graphics.svg.FontSystem; import org.xbib.graphics.svg.element.FontSystem;
import org.xbib.graphics.svg.SVGDiagram; import org.xbib.graphics.svg.SVGDiagram;
import org.xbib.graphics.svg.element.SVGElement; import org.xbib.graphics.svg.element.SVGElement;
import org.xbib.graphics.svg.SVGException; import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.Text; import org.xbib.graphics.svg.element.shape.Text;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.GraphicsEnvironment;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Locale;
import java.util.Objects; import java.util.Objects;
import java.util.Set;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -25,6 +30,8 @@ public final class FontUtil {
private static final int DEFAULT_FONT_WEIGHT = Text.TXWE_NORMAL; private static final int DEFAULT_FONT_WEIGHT = Text.TXWE_NORMAL;
private static final Set<String> sysFontNames = new HashSet<>();
private FontUtil() { private FontUtil() {
} }
@ -113,15 +120,42 @@ public final class FontUtil {
if (font != null) break; if (font != null) break;
} }
if (font == null) { if (font == null) {
font = FontSystem.createFont(families, fontStyle, fontWeight, fontSize); font = createFont(families, fontStyle, fontWeight, fontSize);
} }
if (font == null) { if (font == null) {
Logger.getLogger(FontSystem.class.getName()) Logger.getLogger(FontSystem.class.getName())
.log(Level.WARNING, "Could not create font " + Arrays.toString(families)); .log(Level.WARNING, "Could not create font " + Arrays.toString(families));
String[] defaultFont = new String[]{FontUtil.DEFAULT_FONT_FAMILY}; String[] defaultFont = new String[]{FontUtil.DEFAULT_FONT_FAMILY};
font = FontSystem.createFont(defaultFont, fontStyle, fontWeight, fontSize); font = createFont(defaultFont, fontStyle, fontWeight, fontSize);
} }
return font; return font;
} }
private static FontSystem createFont(String[] fontFamilies, int fontStyle, int fontWeight, float fontSize) {
for (String fontName : fontFamilies) {
String javaFontName = mapJavaFontName(fontName);
if (checkIfSystemFontExists(javaFontName)) {
return new FontSystem(javaFontName, fontStyle, fontWeight, fontSize);
}
}
return null;
}
private static boolean checkIfSystemFontExists(String fontName) {
if (sysFontNames.isEmpty()) {
Collections.addAll(sysFontNames, GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(Locale.ENGLISH));
}
return sysFontNames.contains(fontName);
}
private static String mapJavaFontName(String fontName) {
if ("serif".equals(fontName)) {
return java.awt.Font.SERIF;
} else if ("sans-serif".equals(fontName)) {
return java.awt.Font.SANS_SERIF;
} else if ("monospace".equals(fontName)) {
return java.awt.Font.MONOSPACED;
}
return fontName;
}
} }

View file

@ -1,4 +1,4 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.util;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.InputStream; import java.io.InputStream;

View file

@ -1,6 +1,4 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.util;
import org.xbib.graphics.svg.Handler;
import java.net.URLStreamHandler; import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory; import java.net.URLStreamHandlerFactory;

View file

@ -1,4 +1,6 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.util;
import org.xbib.graphics.svg.element.shape.Marker;
import java.awt.Shape; import java.awt.Shape;
import java.awt.geom.PathIterator; import java.awt.geom.PathIterator;
@ -86,7 +88,6 @@ public class MarkerLayout {
for (int i = 1; i < markerList.size(); ++i) { for (int i = 1; i < markerList.size(); ++i) {
MarkerPos prev = markerList.get(i - 1); MarkerPos prev = markerList.get(i - 1);
MarkerPos cur = markerList.get(i); MarkerPos cur = markerList.get(i);
if (cur.getType() == Marker.MARKER_START) { if (cur.getType() == Marker.MARKER_START) {
prev.setType(Marker.MARKER_END); prev.setType(Marker.MARKER_END);
} }

View file

@ -0,0 +1,62 @@
package org.xbib.graphics.svg.util;
public class MarkerPos {
private int type;
double x;
double y;
double dx;
double dy;
public MarkerPos(int type, double x, double y, double dx, double dy) {
this.type = type;
this.x = x;
this.y = y;
this.dx = dx;
this.dy = dy;
}
public void setType(int type) {
this.type = type;
}
public int getType() {
return type;
}
public void setDx(double dx) {
this.dx = dx;
}
public double getDx() {
return dx;
}
public void setDy(double dy) {
this.dy = dy;
}
public double getDy() {
return dy;
}
public void setX(double x) {
this.x = x;
}
public double getX() {
return x;
}
public void setY(double y) {
this.y = y;
}
public double getY() {
return y;
}
}

View file

@ -21,8 +21,8 @@ public class PaintUtil {
public static final boolean DEBUG_PAINT = false; public static final boolean DEBUG_PAINT = false;
public static void paintElement(Graphics2D g, RenderableElement element) throws SVGException, IOException { public static void paintElement(Graphics2D g, RenderableElement element) throws SVGException, IOException {
if (element.cachedMask != null if (element.getCachedMask() != null
|| (element.filter != null && !element.filter.filterEffects.isEmpty())) { || (element.getFilter() != null && !element.getFilter().getFilterEffects().isEmpty())) {
renderElement(g, element); renderElement(g, element);
} else { } else {
element.doRender(g); element.doRender(g);
@ -73,33 +73,33 @@ public class PaintUtil {
float xScale = getTransformScale(origin, testPoint, transform); float xScale = getTransformScale(origin, testPoint, transform);
testPoint.setLocation(0, 1); testPoint.setLocation(0, 1);
float yScale = getTransformScale(origin, testPoint, transform); float yScale = getTransformScale(origin, testPoint, transform);
List<FilterOp> filterOps = element.filter == null List<FilterOp> filterOps = element.getFilter() == null
? Collections.emptyList() ? Collections.emptyList()
: element.filter.filterEffects.stream() : element.getFilter().getFilterEffects().stream()
.flatMap(f -> f.getOperations(dstBounds, xScale, yScale).stream()) .flatMap(f -> f.getOperations(dstBounds, xScale, yScale).stream())
.filter(Objects::nonNull) .filter(Objects::nonNull)
.collect(Collectors.toList()); .collect(Collectors.toList());
for (FilterOp filterOp : filterOps) { for (FilterOp filterOp : filterOps) {
int right = Math.max(dstBounds.x + dstBounds.width, int right = Math.max(dstBounds.x + dstBounds.width,
filterOp.requiredImageBounds.x + filterOp.requiredImageBounds.width); filterOp.getRequiredImageBounds().x + filterOp.getRequiredImageBounds().width);
int bottom = Math.max(dstBounds.y + dstBounds.height, int bottom = Math.max(dstBounds.y + dstBounds.height,
filterOp.requiredImageBounds.y + filterOp.requiredImageBounds.height); filterOp.getRequiredImageBounds().y + filterOp.getRequiredImageBounds().height);
dstBounds.x = Math.min(dstBounds.x, filterOp.requiredImageBounds.x); dstBounds.x = Math.min(dstBounds.x, filterOp.getRequiredImageBounds().x);
dstBounds.y = Math.min(dstBounds.y, filterOp.requiredImageBounds.y); dstBounds.y = Math.min(dstBounds.y, filterOp.getRequiredImageBounds().y);
dstBounds.width = right - dstBounds.x; dstBounds.width = right - dstBounds.x;
dstBounds.height = bottom - dstBounds.y; dstBounds.height = bottom - dstBounds.y;
} }
BufferedImage elementImage = PaintUtil.paintToBuffer(gg, transform, dstBounds, transformedBounds, BufferedImage elementImage = PaintUtil.paintToBuffer(gg, transform, dstBounds, transformedBounds,
element, null, true); element, null, true);
for (FilterOp filterOp : filterOps) { for (FilterOp filterOp : filterOps) {
elementImage = filterOp.op.filter(elementImage, null); elementImage = filterOp.getOp().filter(elementImage, null);
} }
if (element.cachedMask != null) { if (element.getCachedMask() != null) {
BufferedImage maskImage = PaintUtil.paintToBuffer(gg, transform, dstBounds, transformedBounds, BufferedImage maskImage = PaintUtil.paintToBuffer(gg, transform, dstBounds, transformedBounds,
element.cachedMask, Color.BLACK, false); element.getCachedMask(), Color.BLACK, false);
Graphics2D elementGraphics = (Graphics2D) elementImage.getGraphics(); Graphics2D elementGraphics = (Graphics2D) elementImage.getGraphics();
elementGraphics.setRenderingHints(gg.getRenderingHints()); elementGraphics.setRenderingHints(gg.getRenderingHints());
elementGraphics.setComposite(element.cachedMask.createMaskComposite()); elementGraphics.setComposite(element.getCachedMask().createMaskComposite());
elementGraphics.drawImage(maskImage, 0, 0, null); elementGraphics.drawImage(maskImage, 0, 0, null);
elementGraphics.dispose(); elementGraphics.dispose();
} }

View file

@ -1,4 +1,4 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.util;
import java.awt.Paint; import java.awt.Paint;
import java.awt.PaintContext; import java.awt.PaintContext;

View file

@ -1,4 +1,4 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.util;
import java.awt.PaintContext; import java.awt.PaintContext;
import java.awt.Rectangle; import java.awt.Rectangle;

View file

@ -0,0 +1,41 @@
package org.xbib.graphics.svg.util;
public interface TextConst {
int TXAN_START = 0;
int TXAN_MIDDLE = 1;
int TXAN_END = 2;
int TXST_NORMAL = 0;
int TXST_ITALIC = 1;
int TXST_OBLIQUE = 2;
int TXWE_NORMAL = 0;
int TXWE_BOLD = 1;
int TXWE_BOLDER = 2;
int TXWE_LIGHTER = 3;
int TXWE_100 = 4;
int TXWE_200 = 5;
int TXWE_300 = 6;
int TXWE_400 = 7;
int TXWE_500 = 8;
int TXWE_600 = 9;
int TXWE_700 = 10;
int TXWE_800 = 11;
int TXWE_900 = 12;
}

View file

@ -0,0 +1,7 @@
package org.xbib.graphics.svg.util;
public interface VectorEffect {
int VECTOR_EFFECT_NONE = 0;
int VECTOR_EFFECT_NON_SCALING_STROKE = 1;
}

View file

@ -9,7 +9,7 @@ import java.util.regex.Pattern;
public class ColorTable { public class ColorTable {
static final Map<String, Color> colorTable; private static final Map<String, Color> colorTable;
static { static {
Map<String, Color> table = new HashMap<>(); Map<String, Color> table = new HashMap<>();

View file

@ -1,10 +1,10 @@
package org.xbib.graphics.svg.xml; package org.xbib.graphics.svg.xml;
import java.awt.Toolkit; import java.awt.Toolkit;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -194,7 +194,7 @@ public class XMLParseUtil {
return new NumberWithUnits(val); return new NumberWithUnits(val);
} }
public static HashMap<String, StyleAttribute> parseStyle(String styleString, HashMap<String, StyleAttribute> map) { public static Map<String, StyleAttribute> parseStyle(String styleString, Map<String, StyleAttribute> map) {
Pattern patSemi = Pattern.compile(";"); Pattern patSemi = Pattern.compile(";");
String[] styles = patSemi.split(styleString); String[] styles = patSemi.split(styleString);
for (String style : styles) { for (String style : styles) {

View file

@ -6,6 +6,7 @@ import org.xbib.graphics.svg.SVGUniverse;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.logging.Logger;
public class SimpleSVGLoadTest { public class SimpleSVGLoadTest {
@ -14,5 +15,6 @@ public class SimpleSVGLoadTest {
InputStream inputStream = getClass().getResourceAsStream("test.svg"); InputStream inputStream = getClass().getResourceAsStream("test.svg");
SVGUniverse svgUniverse = new SVGUniverse(); SVGUniverse svgUniverse = new SVGUniverse();
SVGDiagram diagram = svgUniverse.getDiagram(svgUniverse.loadSVG(inputStream, "test.svg")); SVGDiagram diagram = svgUniverse.getDiagram(svgUniverse.loadSVG(inputStream, "test.svg"));
Logger.getAnonymousLogger().info(diagram.toString());
} }
} }

View file

@ -2,32 +2,6 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- ========================================================================= -->
<!-- Illustrates how SVG can be used for high quality graphs. -->
<!-- -->
<!-- @author vincent.hardy@eng.sun.com -->
<!-- @author neeme.praks@one.lv -->
<!-- @version $Id$ -->
<!-- ========================================================================= -->
<?xml-stylesheet type="text/css" href="tests/resources/style/test.css" ?> <?xml-stylesheet type="text/css" href="tests/resources/style/test.css" ?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="body" width="450" height="500" xml:space="preserve" viewBox="0 0 450 500"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="body" width="450" height="500" xml:space="preserve" viewBox="0 0 450 500">
<title>Bar Chart</title> <title>Bar Chart</title>

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB