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 {
api "org.apache.pdfbox:pdfbox:${project.property('pdfbox.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.font.DefaultFontDrawer;
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.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.logging.Logger;
public class RenderSVGsTest extends PdfBoxGraphics2DTestBase {
@ -63,7 +69,19 @@ public class RenderSVGsTest extends PdfBoxGraphics2DTestBase {
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();
SAXSVGDocumentFactory f = new SAXSVGDocumentFactory();
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());
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);
protected boolean ignoreClipHeuristic = false;
final URI xmlBase;
private final URI xmlBase;
public SVGDiagram(URI xmlBase, SVGUniverse universe) {
this.universe = universe;

View file

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

View file

@ -1,23 +1,40 @@
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.Defs;
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.Font;
import org.xbib.graphics.svg.element.Group;
import org.xbib.graphics.svg.element.Line;
import org.xbib.graphics.svg.element.Mask;
import org.xbib.graphics.svg.element.FontFace;
import org.xbib.graphics.svg.element.shape.Group;
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.ShapeElement;
import org.xbib.graphics.svg.element.Style;
import org.xbib.graphics.svg.element.filtereffects.GaussianBlur;
import org.xbib.graphics.svg.element.glyph.Glyph;
import org.xbib.graphics.svg.element.glyph.MissingGlyph;
import org.xbib.graphics.svg.element.gradient.LinearGradient;
import org.xbib.graphics.svg.element.gradient.RadialGradient;
import org.xbib.graphics.svg.element.gradient.Linear;
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.SAXException;
import org.xml.sax.helpers.DefaultHandler;
@ -58,7 +75,7 @@ public class SVGLoader extends DefaultHandler {
nodeClasses.put("desc", Desc.class);
nodeClasses.put("ellipse", Ellipse.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-face", FontFace.class);
nodeClasses.put("g", Group.class);
@ -66,7 +83,7 @@ public class SVGLoader extends DefaultHandler {
nodeClasses.put("hkern", Hkern.class);
nodeClasses.put("image", ImageSVG.class);
nodeClasses.put("line", Line.class);
nodeClasses.put("lineargradient", LinearGradient.class);
nodeClasses.put("lineargradient", Linear.class);
nodeClasses.put("marker", Marker.class);
nodeClasses.put("mask", Mask.class);
nodeClasses.put("metadata", Metadata.class);
@ -75,7 +92,7 @@ public class SVGLoader extends DefaultHandler {
nodeClasses.put("pattern", PatternSVG.class);
nodeClasses.put("polygon", Polygon.class);
nodeClasses.put("polyline", Polyline.class);
nodeClasses.put("radialgradient", RadialGradient.class);
nodeClasses.put("radialgradient", Radial.class);
nodeClasses.put("rect", Rect.class);
nodeClasses.put("shape", ShapeElement.class);
nodeClasses.put("stop", Stop.class);

View file

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

View file

@ -1,7 +1,7 @@
package org.xbib.graphics.svg;
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.Style;
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());
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<>();
public static final String INPUTSTREAM_SCHEME = "svgXbib";
private final Map<URL, SoftReference<BufferedImage>> loadedImages = new HashMap<>();
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)) {
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);
if (ref == null) {
return null;
@ -202,12 +200,13 @@ public class SVGUniverse {
}
public SVGElement getElement(URI path, boolean loadIfAbsent) {
path = cleanUri(path);
try {
path = cleanUri(path);
URI xmlBase = new URI(path.getScheme(), path.getSchemeSpecificPart(), null);
SVGDiagram dia = loadedDocs.get(xmlBase);
if (dia == null && loadIfAbsent) {
URL url = xmlBase.toURL();
URL url;
url = xmlBase.toURL();
loadSVG(url, false);
dia = loadedDocs.get(xmlBase);
if (dia == null) {
@ -216,7 +215,7 @@ public class SVGUniverse {
}
String fragment = path.getFragment();
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);
return null;
}
@ -323,7 +322,7 @@ public class SVGUniverse {
name = '/' + name;
}
try {
return new URI(INPUTSTREAM_SCHEME, name, null);
return new URI("svg", name, null);
} catch (Exception e) {
logger.log(Level.SEVERE, "Could not parse", e);
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 java.io.IOException;
@ -8,18 +9,13 @@ import java.net.URI;
public class A extends Group {
public static final String TAG_NAME = "a";
private URI href;
URI href;
String title;
public A() {
}
private String title;
@Override
public String getTagName() {
return TAG_NAME;
return "a";
}
@Override

View file

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

View file

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

View file

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

View file

@ -14,38 +14,51 @@ import java.util.List;
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;
URL href = null;
public final List<FilterEffects> filterEffects = new ArrayList<>();
public Filter() {
}
private final List<FilterEffects> filterEffects = new ArrayList<>();
@Override
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
@ -71,11 +84,6 @@ public class Filter extends SVGElement {
}
if (getPres(sty.setName("primitiveUnits"))) {
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"))) {
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
public boolean updateTime(double curTime) throws SVGException {
StyleAttribute sty = new StyleAttribute();
@ -183,7 +175,6 @@ public class Filter extends SVGElement {
newVal = PU_OBJECT_BOUNDING_BOX;
}
if (newVal != filterUnits) {
primitiveUnits = newVal;
stateChange = true;
}
}

View file

@ -1,6 +1,5 @@
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.MissingGlyph;
import org.xbib.graphics.svg.SVGElementException;
@ -15,32 +14,27 @@ import java.util.Map;
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;
final Map<String, SVGElement> glyphs = new HashMap<>();
public Font() {
}
private final Map<String, SVGElement> glyphs = new HashMap<>();
@Override
public String getTagName() {
return TAG_NAME;
return "font";
}
@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.element.SVGElement;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.xml.StyleAttribute;
import java.io.IOException;
public class FontFace extends SVGElement {
public static final String TAG_NAME = "fontface";
String fontFamily;
private String fontFamily;
private int unitsPerEm = 1000;
@ -32,12 +29,9 @@ public class FontFace extends SVGElement {
private int overlineThickness = -1;
public FontFace() {
}
@Override
public String getTagName() {
return TAG_NAME;
return "fontface";
}
@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.MissingGlyph;
import org.xbib.graphics.svg.element.shape.Text;
import java.awt.GraphicsEnvironment;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphMetrics;
import java.awt.font.GlyphVector;
import java.awt.font.LineMetrics;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
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 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) {
public FontSystem(String fontFamily, int fontStyle, int fontWeight, float fontSize) {
int style;
if (fontStyle == Text.TXST_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.element.SVGElement;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.util.Handler;
import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.AlphaComposite;
@ -22,28 +22,23 @@ public class ImageSVG extends RenderableElement {
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;
Rectangle2D bounds;
public ImageSVG() {
}
private Rectangle2D bounds;
@Override
public String getTagName() {
return TAG_NAME;
return "image";
}
@Override
@ -223,7 +218,7 @@ public class ImageSVG extends RenderableElement {
logger.log(Level.SEVERE, "Image provided with illegal value for href: \""
+ sty.getStringValue() + '"', ie);
} 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) {
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.element.RenderableElement;
import org.xbib.graphics.svg.element.SVGElement;
import org.xbib.graphics.svg.util.PatternPaint;
import org.xbib.graphics.svg.SVGElementException;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.SVGLoaderHelper;
import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Graphics2D;
@ -18,34 +19,29 @@ import java.net.URI;
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_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;
public PatternSVG() {
}
private Paint texPaint;
@Override
public String getTagName() {
return TAG_NAME;
return "pattern";
}
@Override

View file

@ -1,8 +1,11 @@
package org.xbib.graphics.svg.element;
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.PaintUtil;
import org.xbib.graphics.svg.util.VectorEffect;
import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Graphics2D;
@ -15,19 +18,15 @@ import java.io.IOException;
import java.net.URI;
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;
public static final int VECTOR_EFFECT_NONE = 0;
public static final int VECTOR_EFFECT_NON_SCALING_STROKE = 1;
private Shape cachedClip;
protected int vectorEffect;
@ -40,6 +39,14 @@ public abstract class RenderableElement extends TransformableElement {
super(id, parent);
}
public Mask getCachedMask() {
return cachedMask;
}
public Filter getFilter() {
return filter;
}
public PaintCache getBufferCache() {
return bufferCache;
}
@ -100,7 +107,7 @@ public abstract class RenderableElement extends TransformableElement {
}
StyleAttribute styleAttrib = new StyleAttribute();
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)
&& !"none".equals(styleAttrib.getStringValue())) {
URI uri = styleAttrib.getURIValue(getXMLBase());
@ -111,7 +118,7 @@ public abstract class RenderableElement extends TransformableElement {
}
}
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();
AffineTransform at = new AffineTransform();
at.scale(rect.getWidth(), rect.getHeight());

View file

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

View file

@ -1,9 +1,9 @@
package org.xbib.graphics.svg.element;
import org.xbib.graphics.svg.Marker;
import org.xbib.graphics.svg.MarkerLayout;
import org.xbib.graphics.svg.MarkerPos;
import org.xbib.graphics.svg.util.MarkerLayout;
import org.xbib.graphics.svg.util.MarkerPos;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.element.shape.Marker;
import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.AlphaComposite;
@ -24,9 +24,6 @@ public abstract class ShapeElement extends RenderableElement {
protected float strokeWidthScalar = 1f;
public ShapeElement() {
}
@Override
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.xml.StyleAttribute;
@ -8,20 +9,30 @@ import java.io.IOException;
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;
public Color color = Color.black;
private Color color = Color.black;
public Stop() {
}
public float getOffset() {
return offset;
}
public float getOpacity() {
return opacity;
}
public Color getColor() {
return color;
}
@Override
public String getTagName() {
return TAG_NAME;
return "stop";
}
@Override

View file

@ -10,20 +10,13 @@ import java.io.IOException;
public class Style extends SVGElement {
public static final String TAG_NAME = "style";
private final StringBuilder text = new StringBuilder();
String type;
StringBuilder text = new StringBuilder();
StyleSheet styleSheet;
public Style() {
}
private StyleSheet styleSheet;
@Override
public String getTagName() {
return TAG_NAME;
return "style";
}
@Override
@ -37,7 +30,7 @@ public class Style extends SVGElement {
super.build();
StyleAttribute sty = new StyleAttribute();
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 java.awt.Graphics2D;
@ -12,18 +13,13 @@ import java.io.IOException;
public class Symbol extends Group {
public static final String TAG_NAME = "symbol";
private AffineTransform viewXform;
AffineTransform viewXform;
Rectangle2D viewBox;
public Symbol() {
}
private Rectangle2D viewBox;
@Override
public String getTagName() {
return TAG_NAME;
return "symbol";
}
@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 static final String TAG_NAME = "title";
StringBuilder text = new StringBuilder();
public Title() {
}
private final StringBuilder text = new StringBuilder();
@Override
public String getTagName() {
return TAG_NAME;
return "title";
}
@Override

View file

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

View file

@ -6,44 +6,26 @@ import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Rectangle;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.List;
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;
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() {
}
private URL href;
@Override
public String getTagName() {
return TAG_NAME;
return "filtereffects";
}
@Override
@ -103,17 +85,18 @@ public abstract class FilterEffects extends SVGElement {
stateChange = true;
}
}
try {
if (getPres(sty.setName("xlink:href"))) {
URI src = sty.getURIValue(getXMLBase());
URL newVal = src.toURL();
if (!newVal.equals(href)) {
href = newVal;
stateChange = true;
}
if (getPres(sty.setName("xlink:href"))) {
URI src = sty.getURIValue(getXMLBase());
URL newVal;
try {
newVal = src.toURL();
} catch (MalformedURLException e) {
throw new SVGException(e);
}
if (!newVal.equals(href)) {
href = newVal;
stateChange = true;
}
} catch (Exception e) {
throw new SVGException(e);
}
return stateChange;
}

View file

@ -5,12 +5,20 @@ import java.awt.image.BufferedImageOp;
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) {
this.op = op;
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 static final String TAG_NAME = "fegaussianblur";
private float[] stdDeviation;
private float xCurrent;
@ -26,7 +24,7 @@ public class GaussianBlur extends FilterEffects {
@Override
public String getTagName() {
return TAG_NAME;
return "fegaussianblur";
}
@Override
@ -45,14 +43,8 @@ public class GaussianBlur extends FilterEffects {
public List<FilterOp> getOperations(Rectangle inputBounds, float xScale, float yScale) {
float xSigma = xScale * stdDeviation[0];
float ySigma = yScale * stdDeviation[Math.min(stdDeviation.length - 1, 1)];
return Arrays.asList(
xSigma > 0
? getGaussianBlurFilter(inputBounds, xSigma, true)
: null,
ySigma > 0
? getGaussianBlurFilter(inputBounds, ySigma, false)
: null
);
return Arrays.asList(xSigma > 0 ? getGaussianBlurFilter(inputBounds, xSigma, true) : null,
ySigma > 0 ? getGaussianBlurFilter(inputBounds, ySigma, false) : null);
}
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++) {
float distance = middle - i;
distance *= distance;
data[i] = distance > radius2
? 0
data[i] = distance > radius2 ? 0
: (float) Math.exp(-distance / twoSigmaSquare) / sigmaRoot;
total += data[i];
}

View file

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

View file

@ -7,20 +7,15 @@ import java.io.IOException;
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;
float z = 0f;
public PointLight() {
}
private float z = 0f;
@Override
public String getTagName() {
return TAG_NAME;
return "fepointlight";
}
@Override

View file

@ -7,27 +7,25 @@ import java.io.IOException;
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;
float limitingConeAngle = 0f;
private float limitingConeAngle = 0f;
@Override
public String getTagName() {
return TAG_NAME;
return "fespotlight";
}
@Override

View file

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

View file

@ -20,8 +20,6 @@ import java.io.IOException;
public class MissingGlyph extends ShapeElement {
public static final String TAG_NAME = "missingglyph";
private Shape path = null;
private float horizAdvX = -1;
@ -32,12 +30,9 @@ public class MissingGlyph extends ShapeElement {
private float vertAdvY = -1;
public MissingGlyph() {
}
@Override
public String getTagName() {
return TAG_NAME;
return "missingglyph";
}
@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.SVGException;
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.SVGElement;
import org.xbib.graphics.svg.xml.StyleAttribute;
@ -17,38 +17,33 @@ import java.util.List;
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;
public static final int GU_USER_SPACE_ON_USE = 1;
protected static final int GU_USER_SPACE_ON_USE = 1;
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;
float[] stopFractions;
private float[] stopFractions;
Color[] stopColors;
public Gradient() {
}
private Color[] stopColors;
@Override
public String getTagName() {
return TAG_NAME;
return "gradient";
}
@Override
@ -100,9 +95,9 @@ public abstract class Gradient extends FillElement {
private void buildStops() {
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) {
if (stopList.get(i + 1).offset == stopList.get(i).offset) {
if (stopList.get(i + 1).getOffset() == stopList.get(i).getOffset()) {
stopList.remove(i + 1);
}
}
@ -110,10 +105,10 @@ public abstract class Gradient extends FillElement {
stopColors = new Color[stopList.size()];
int idx = 0;
for (Stop stop : stopList) {
int stopColorVal = stop.color.getRGB();
Color stopColor = new Color((stopColorVal >> 16) & 0xff, (stopColorVal >> 8) & 0xff, stopColorVal & 0xff, clamp((int) (stop.opacity * 255), 0, 255));
int stopColorVal = stop.getColor().getRGB();
Color stopColor = new Color((stopColorVal >> 16) & 0xff, (stopColorVal >> 8) & 0xff, stopColorVal & 0xff, clamp((int) (stop.getOpacity() * 255), 0, 255));
stopColors[idx] = stopColor;
stopFractions[idx] = stop.offset;
stopFractions[idx] = stop.getOffset();
idx++;
}
}

View file

@ -1,7 +1,6 @@
package org.xbib.graphics.svg.element.gradient;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.element.gradient.Gradient;
import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Color;
@ -13,24 +12,19 @@ import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
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;
float y2 = 0f;
public LinearGradient() {
}
private float y2 = 0f;
@Override
public String getTagName() {
return TAG_NAME;
return "lineargradient";
}
@Override

View file

@ -1,7 +1,6 @@
package org.xbib.graphics.svg.element.gradient;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.element.gradient.Gradient;
import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Color;
@ -13,28 +12,23 @@ import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
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;
float r = 0.5f;
public RadialGradient() {
}
private float r = 0.5f;
@Override
public String getTagName() {
return TAG_NAME;
return "radialgradient";
}
@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.element.ShapeElement;
import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Graphics2D;
@ -11,22 +12,17 @@ import java.io.IOException;
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;
Ellipse2D.Float circle = new Ellipse2D.Float();
public Circle() {
}
private final Ellipse2D.Float circle = new Ellipse2D.Float();
@Override
public String getTagName() {
return TAG_NAME;
return "circle";
}
@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.element.ShapeElement;
import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Graphics2D;
@ -11,24 +12,19 @@ import java.io.IOException;
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;
Ellipse2D.Float ellipse = new Ellipse2D.Float();
public Ellipse() {
}
private final Ellipse2D.Float ellipse = new Ellipse2D.Float();
@Override
public String getTagName() {
return TAG_NAME;
return "ellipse";
}
@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.SVGException;
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 java.awt.Graphics2D;
@ -18,18 +21,13 @@ import java.util.List;
public class Group extends ShapeElement {
public static final String TAG_NAME = "group";
private Rectangle2D boundingBox;
Rectangle2D boundingBox;
Shape cachedShape;
public Group() {
}
private Shape cachedShape;
@Override
public String getTagName() {
return TAG_NAME;
return "group";
}
@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.element.ShapeElement;
@ -12,24 +12,19 @@ import java.io.IOException;
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;
Line2D.Float line;
public Line() {
}
private Line2D.Float line;
@Override
public String getTagName() {
return TAG_NAME;
return "line";
}
@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 java.awt.Graphics2D;
@ -12,35 +13,29 @@ import java.io.IOException;
public class Marker extends Group {
public static final String TAG_NAME = "marker";
public static final int MARKER_START = 0;
public static final int MARKER_MID = 1;
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;
float orient = Float.NaN;
boolean markerUnitsStrokeWidth = true;
private boolean markerUnitsStrokeWidth = true;
@Override
public String getTagName() {
return TAG_NAME;
return "marker";
}
@Override
@ -59,14 +54,6 @@ public class Marker extends Group {
if (getPres(sty.setName("markerHeight"))) {
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"))) {
float[] dim = sty.getFloatList();
viewBox = new Rectangle2D.Float(dim[0], dim[1], dim[2], dim[3]);
@ -80,7 +67,7 @@ public class Marker extends Group {
markerUnitsStrokeWidth = false;
}
}
viewXform = new AffineTransform();
AffineTransform viewXform = new AffineTransform();
viewXform.scale(1.0 / viewBox.getWidth(), 1.0 / viewBox.getHeight());
viewXform.translate(-viewBox.getX(), -viewBox.getY());
markerXform = new AffineTransform();
@ -106,11 +93,11 @@ public class Marker extends Group {
public void render(Graphics2D g, MarkerPos pos, float strokeWidth) throws SVGException, IOException {
AffineTransform cacheXform = g.getTransform();
g.translate(pos.x, pos.y);
g.translate(pos.getX(), pos.getY());
if (markerUnitsStrokeWidth) {
g.scale(strokeWidth, strokeWidth);
}
g.rotate(Math.atan2(pos.dy, pos.dx));
g.rotate(Math.atan2(pos.getDy(), pos.getDx()));
g.transform(markerXform);
super.doRender(g);
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.element.Group;
import org.xbib.graphics.svg.element.RenderableElement;
import org.xbib.graphics.svg.element.SVGElement;
import org.xbib.graphics.svg.util.PaintUtil;
@ -25,11 +24,9 @@ import java.util.List;
public class Mask extends Group {
public static final String TAG_NAME = "mask";
@Override
public String getTagName() {
return TAG_NAME;
return "mask";
}
@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.xml.StyleAttribute;
@ -11,20 +12,15 @@ import java.io.IOException;
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 = "";
GeneralPath path;
public Path() {
}
private GeneralPath path;
@Override
public String getTagName() {
return TAG_NAME;
return "path";
}
@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.xml.StyleAttribute;
import org.xbib.graphics.svg.xml.XMLParseUtil;
@ -12,43 +13,32 @@ import java.io.IOException;
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;
String pointsStrn = "";
GeneralPath path;
private String pointsStrn = "";
/**
* Creates a new instance of Rect
*/
public Polygon() {
}
private GeneralPath path;
@Override
public String getTagName() {
return TAG_NAME;
return "polygon";
}
@Override
protected void build() throws SVGException, IOException {
super.build();
StyleAttribute sty = new StyleAttribute();
if (getPres(sty.setName("points"))) {
pointsStrn = sty.getStringValue();
}
String fillRuleStrn = getStyle(sty.setName("fill-rule")) ? sty.getStringValue() : "nonzero";
fillRule = fillRuleStrn.equals("evenodd") ? GeneralPath.WIND_EVEN_ODD : GeneralPath.WIND_NON_ZERO;
buildPath();
}
protected void buildPath() {
float[] points = XMLParseUtil.parseFloatList(pointsStrn);
path = new GeneralPath(fillRule, points.length / 2);
path.moveTo(points[0], points[1]);
for (int i = 2; i < points.length; i += 2) {
path.lineTo(points[i], points[i + 1]);
@ -73,22 +63,11 @@ public class Polygon extends ShapeElement {
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
public boolean updateTime(double curTime) throws SVGException, IOException {
// if (trackManager.getNumTracks() == 0) return false;
boolean changeState = super.updateTime(curTime);
//Get current values for parameters
StyleAttribute sty = new StyleAttribute();
boolean shapeChange = false;
if (getStyle(sty.setName("fill-rule"))) {
int newVal = sty.getStringValue().equals("evenodd")
? GeneralPath.WIND_EVEN_ODD
@ -98,7 +77,6 @@ public class Polygon extends ShapeElement {
shapeChange = true;
}
}
if (getPres(sty.setName("points"))) {
String newVal = sty.getStringValue();
if (!newVal.equals(pointsStrn)) {
@ -106,14 +84,9 @@ public class Polygon extends ShapeElement {
shapeChange = true;
}
}
if (shapeChange) {
build();
// buildPath();
// return true;
}
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.xml.StyleAttribute;
import org.xbib.graphics.svg.xml.XMLParseUtil;
@ -12,20 +13,15 @@ import java.io.IOException;
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 = "";
GeneralPath path;
public Polyline() {
}
private GeneralPath path;
@Override
public String getTagName() {
return TAG_NAME;
return "polyline";
}
@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.xml.StyleAttribute;
@ -12,22 +13,23 @@ import java.io.IOException;
public class Rect extends ShapeElement {
public static final String TAG_NAME = "rect";
private float x = 0f;
float x = 0f;
float y = 0f;
float width = 0f;
float height = 0f;
float rx = 0f;
float ry = 0f;
RectangularShape rect;
private float y = 0f;
public Rect() {
}
private float width = 0f;
private float height = 0f;
private float rx = 0f;
private float ry = 0f;
private RectangularShape rect;
@Override
public String getTagName() {
return TAG_NAME;
return "rect";
}
@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.TextConst;
import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.geom.AffineTransform;
@ -10,56 +12,13 @@ import java.io.IOException;
import java.util.Arrays;
import java.util.List;
public class Text extends Tspan {
public class Text extends Tspan implements TextConst {
public static final String TAG_NAME = "text";
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() {
}
private int textAnchor = TXAN_START;
@Override
public String getTagName() {
return TAG_NAME;
return "text";
}
public void rebuild() throws SVGException, IOException {
@ -138,16 +97,16 @@ public class Text extends Tspan {
public boolean updateTime(double curTime) throws SVGException {
boolean changeState = super.updateTime(curTime);
FontUtil.FontInfo fontInfoOld = fontInfo;
float[] xOld = x;
float[] yOld = y;
float[] dxOld = dx;
float[] dyOld = dy;
float[] xOld = getX();
float[] yOld = getY();
float[] dxOld = getDx();
float[] dyOld = getDy();
buildShapeInformation();
boolean shapeChange = !fontInfo.equals(fontInfoOld)
|| !Arrays.equals(xOld, x)
|| !Arrays.equals(yOld, y)
|| !Arrays.equals(dxOld, dx)
|| !Arrays.equals(dyOld, dy);
|| !Arrays.equals(xOld, getX())
|| !Arrays.equals(yOld, getY())
|| !Arrays.equals(dxOld, getDx())
|| !Arrays.equals(dyOld, getDy());
if (shapeChange) {
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.SVGElement;
import org.xbib.graphics.svg.element.ShapeElement;
@ -21,21 +24,15 @@ import java.util.regex.Pattern;
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;
float[] rotate = null;
float textLength = -1;
String lengthAdjust = "spacing";
private float[] rotate = null;
private final List<Object> content = new ArrayList<>();
@ -49,12 +46,25 @@ public class Tspan extends ShapeElement {
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
public String getTagName() {
return TAG_NAME;
return "tspan";
}
@Override
@ -107,16 +117,6 @@ public class Tspan extends ShapeElement {
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 {

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.SVGElement;
import org.xbib.graphics.svg.element.ShapeElement;
@ -14,26 +15,21 @@ import java.net.URI;
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;
AffineTransform refXform;
public Use() {
}
private AffineTransform refXform;
@Override
public String getTagName() {
return TAG_NAME;
return "use";
}
@Override

View file

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

View file

@ -4,22 +4,33 @@ import java.awt.geom.Point2D;
public class BuildHistory {
Point2D.Float startPoint = new Point2D.Float();
Point2D.Float lastPoint = new Point2D.Float();
Point2D.Float lastKnot = new Point2D.Float();
private final Point2D.Float startPoint = 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) {
startPoint.setLocation(x, y);
}
public Point2D.Float getStartPoint() {
return startPoint;
}
public void setLastPoint(float x, float y) {
lastPoint.setLocation(x, y);
}
public Point2D.Float getLastPoint() {
return lastPoint;
}
public void setLastKnot(float x, float 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 float k1x = 0f;
public float k1y = 0f;
public float k2x = 0f;
public float k2y = 0f;
public float x = 0f;
public float y = 0f;
private float k1x = 0f;
private float k1y = 0f;
private float k2x = 0f;
private float k2y = 0f;
private float x = 0f;
private float y = 0f;
public Cubic() {
}
@ -26,8 +31,8 @@ public class Cubic extends PathCommand {
@Override
public void appendPath(GeneralPath path, BuildHistory hist) {
float offx = isRelative ? hist.lastPoint.x : 0f;
float offy = isRelative ? hist.lastPoint.y : 0f;
float offx = isRelative() ? hist.getLastPoint().x : 0f;
float offy = isRelative() ? hist.getLastPoint().y : 0f;
path.curveTo(k1x + offx, k1y + offy,
k2x + offx, k2y + offy,
x + offx, y + offy);

View file

@ -4,13 +4,13 @@ import java.awt.geom.GeneralPath;
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() {
}
@ -25,12 +25,12 @@ public class CubicSmooth extends PathCommand {
@Override
public void appendPath(GeneralPath path, BuildHistory hist) {
float offx = isRelative ? hist.lastPoint.x : 0f;
float offy = isRelative ? hist.lastPoint.y : 0f;
float oldKx = hist.lastKnot.x;
float oldKy = hist.lastKnot.y;
float oldX = hist.lastPoint.x;
float oldY = hist.lastPoint.y;
float offx = isRelative() ? hist.getLastPoint().x : 0f;
float offy = isRelative() ? hist.getLastPoint().y : 0f;
float oldKx = hist.getLastKnot().x;
float oldKy = hist.getLastKnot().y;
float oldX = hist.getLastPoint().x;
float oldY = hist.getLastPoint().y;
float k1x = oldX * 2f - oldKx;
float k1y = oldY * 2f - oldKy;
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 float x = 0f;
public Horizontal() {
}
@Override
public String toString() {
return "H " + x;
}
private final float x;
public Horizontal(boolean isRelative, float x) {
super(isRelative);
@ -21,8 +13,8 @@ public class Horizontal extends PathCommand {
@Override
public void appendPath(GeneralPath path, BuildHistory hist) {
float offx = isRelative ? hist.lastPoint.x : 0f;
float offy = hist.lastPoint.y;
float offx = isRelative() ? hist.getLastPoint().x : 0f;
float offy = hist.getLastPoint().y;
path.lineTo(x + offx, offy);
hist.setLastPoint(x + offx, offy);
hist.setLastKnot(x + offx, offy);
@ -32,4 +24,9 @@ public class Horizontal extends PathCommand {
public int getNumKnotsAdded() {
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 float x = 0f;
public float y = 0f;
private final float x;
public LineTo() {
}
private final float y;
public LineTo(boolean isRelative, float x, float y) {
super(isRelative);
@ -18,8 +16,8 @@ public class LineTo extends PathCommand {
@Override
public void appendPath(GeneralPath path, BuildHistory hist) {
float offx = isRelative ? hist.lastPoint.x : 0f;
float offy = isRelative ? hist.lastPoint.y : 0f;
float offx = isRelative() ? hist.getLastPoint().x : 0f;
float offy = isRelative() ? hist.getLastPoint().y : 0f;
path.lineTo(x + offx, y + offy);
hist.setLastPoint(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 float x = 0f;
private final float x;
public float y = 0f;
public MoveTo() {
}
private final float y;
public MoveTo(boolean isRelative, float x, float y) {
super(isRelative);
@ -19,8 +16,8 @@ public class MoveTo extends PathCommand {
@Override
public void appendPath(GeneralPath path, BuildHistory hist) {
float offx = isRelative ? hist.lastPoint.x : 0f;
float offy = isRelative ? hist.lastPoint.y : 0f;
float offx = isRelative() ? hist.getLastPoint().x : 0f;
float offy = isRelative() ? hist.getLastPoint().y : 0f;
path.moveTo(x + offx, y + offy);
hist.setStartPoint(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 {
public boolean isRelative = false;
private final boolean isRelative;
public PathCommand() {
this(true);
}
public PathCommand(boolean isRelative) {
this.isRelative = isRelative;
}
public boolean isRelative() {
return isRelative;
}
abstract public void appendPath(GeneralPath path, BuildHistory hist);
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 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;
public Quadratic() {
}
private final float y;
public Quadratic(boolean isRelative, float kx, float ky, float x, float y) {
super(isRelative);
@ -25,8 +22,8 @@ public class Quadratic extends PathCommand {
@Override
public void appendPath(GeneralPath path, BuildHistory hist) {
float offx = isRelative ? hist.lastPoint.x : 0f;
float offy = isRelative ? hist.lastPoint.y : 0f;
float offx = isRelative() ? hist.getLastPoint().x : 0f;
float offy = isRelative() ? hist.getLastPoint().y : 0f;
path.quadTo(kx + offx, ky + offy, x + offx, y + offy);
hist.setLastPoint(x + offx, y + offy);
hist.setLastKnot(kx + offx, ky + offy);

View file

@ -4,17 +4,9 @@ import java.awt.geom.GeneralPath;
public class QuadraticSmooth extends PathCommand {
public float x = 0f;
private final float x;
public float y = 0f;
public QuadraticSmooth() {
}
@Override
public String toString() {
return "T " + x + " " + y;
}
private final float y;
public QuadraticSmooth(boolean isRelative, float x, float y) {
super(isRelative);
@ -24,12 +16,12 @@ public class QuadraticSmooth extends PathCommand {
@Override
public void appendPath(GeneralPath path, BuildHistory hist) {
float offx = isRelative ? hist.lastPoint.x : 0f;
float offy = isRelative ? hist.lastPoint.y : 0f;
float oldKx = hist.lastKnot.x;
float oldKy = hist.lastKnot.y;
float oldX = hist.lastPoint.x;
float oldY = hist.lastPoint.y;
float offx = isRelative() ? hist.getLastPoint().x : 0f;
float offy = isRelative() ? hist.getLastPoint().y : 0f;
float oldKx = hist.getLastKnot().x;
float oldKy = hist.getLastKnot().y;
float oldX = hist.getLastPoint().x;
float oldY = hist.getLastPoint().y;
float kx = oldX * 2f - oldKx;
float ky = oldY * 2f - oldKy;
path.quadTo(kx, ky, x + offx, y + offy);
@ -41,4 +33,9 @@ public class QuadraticSmooth extends PathCommand {
public int getNumKnotsAdded() {
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 Terminal() {
}
@Override
public String toString() {
return "Z";
}
@Override
public void appendPath(GeneralPath path, BuildHistory hist) {
path.closePath();
hist.setLastPoint(hist.startPoint.x, hist.startPoint.y);
hist.setLastKnot(hist.startPoint.x, hist.startPoint.y);
hist.setLastPoint(hist.getStartPoint().x, hist.getStartPoint().y);
hist.setLastKnot(hist.getStartPoint().x, hist.getStartPoint().y);
}
@Override
public int getNumKnotsAdded() {
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 float y = 0f;
public Vertical() {
}
@Override
public String toString() {
return "V " + y;
}
private final float y;
public Vertical(boolean isRelative, float y) {
super(isRelative);
@ -21,8 +13,8 @@ public class Vertical extends PathCommand {
@Override
public void appendPath(GeneralPath path, BuildHistory hist) {
float offx = hist.lastPoint.x;
float offy = isRelative ? hist.lastPoint.y : 0f;
float offx = hist.getLastPoint().x;
float offy = isRelative() ? hist.getLastPoint().y : 0f;
path.lineTo(offx, y + offy);
hist.setLastPoint(offx, y + offy);
hist.setLastKnot(offx, y + offy);
@ -32,4 +24,9 @@ public class Vertical extends PathCommand {
public int getNumKnotsAdded() {
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.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.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;
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.element.SVGElement;
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 java.awt.GraphicsEnvironment;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Locale;
import java.util.Objects;
import java.util.Set;
import java.util.logging.Level;
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 Set<String> sysFontNames = new HashSet<>();
private FontUtil() {
}
@ -113,15 +120,42 @@ public final class FontUtil {
if (font != null) break;
}
if (font == null) {
font = FontSystem.createFont(families, fontStyle, fontWeight, fontSize);
font = createFont(families, fontStyle, fontWeight, fontSize);
}
if (font == null) {
Logger.getLogger(FontSystem.class.getName())
.log(Level.WARNING, "Could not create font " + Arrays.toString(families));
String[] defaultFont = new String[]{FontUtil.DEFAULT_FONT_FAMILY};
font = FontSystem.createFont(defaultFont, fontStyle, fontWeight, fontSize);
font = createFont(defaultFont, fontStyle, fontWeight, fontSize);
}
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.InputStream;

View file

@ -1,6 +1,4 @@
package org.xbib.graphics.svg;
import org.xbib.graphics.svg.Handler;
package org.xbib.graphics.svg.util;
import java.net.URLStreamHandler;
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.geom.PathIterator;
@ -86,7 +88,6 @@ public class MarkerLayout {
for (int i = 1; i < markerList.size(); ++i) {
MarkerPos prev = markerList.get(i - 1);
MarkerPos cur = markerList.get(i);
if (cur.getType() == Marker.MARKER_START) {
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 void paintElement(Graphics2D g, RenderableElement element) throws SVGException, IOException {
if (element.cachedMask != null
|| (element.filter != null && !element.filter.filterEffects.isEmpty())) {
if (element.getCachedMask() != null
|| (element.getFilter() != null && !element.getFilter().getFilterEffects().isEmpty())) {
renderElement(g, element);
} else {
element.doRender(g);
@ -73,33 +73,33 @@ public class PaintUtil {
float xScale = getTransformScale(origin, testPoint, transform);
testPoint.setLocation(0, 1);
float yScale = getTransformScale(origin, testPoint, transform);
List<FilterOp> filterOps = element.filter == null
List<FilterOp> filterOps = element.getFilter() == null
? Collections.emptyList()
: element.filter.filterEffects.stream()
: element.getFilter().getFilterEffects().stream()
.flatMap(f -> f.getOperations(dstBounds, xScale, yScale).stream())
.filter(Objects::nonNull)
.collect(Collectors.toList());
for (FilterOp filterOp : filterOps) {
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,
filterOp.requiredImageBounds.y + filterOp.requiredImageBounds.height);
dstBounds.x = Math.min(dstBounds.x, filterOp.requiredImageBounds.x);
dstBounds.y = Math.min(dstBounds.y, filterOp.requiredImageBounds.y);
filterOp.getRequiredImageBounds().y + filterOp.getRequiredImageBounds().height);
dstBounds.x = Math.min(dstBounds.x, filterOp.getRequiredImageBounds().x);
dstBounds.y = Math.min(dstBounds.y, filterOp.getRequiredImageBounds().y);
dstBounds.width = right - dstBounds.x;
dstBounds.height = bottom - dstBounds.y;
}
BufferedImage elementImage = PaintUtil.paintToBuffer(gg, transform, dstBounds, transformedBounds,
element, null, true);
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,
element.cachedMask, Color.BLACK, false);
element.getCachedMask(), Color.BLACK, false);
Graphics2D elementGraphics = (Graphics2D) elementImage.getGraphics();
elementGraphics.setRenderingHints(gg.getRenderingHints());
elementGraphics.setComposite(element.cachedMask.createMaskComposite());
elementGraphics.setComposite(element.getCachedMask().createMaskComposite());
elementGraphics.drawImage(maskImage, 0, 0, null);
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.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.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 {
static final Map<String, Color> colorTable;
private static final Map<String, Color> colorTable;
static {
Map<String, Color> table = new HashMap<>();

View file

@ -1,10 +1,10 @@
package org.xbib.graphics.svg.xml;
import java.awt.Toolkit;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
@ -194,7 +194,7 @@ public class XMLParseUtil {
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(";");
String[] styles = patSemi.split(styleString);
for (String style : styles) {

View file

@ -6,6 +6,7 @@ import org.xbib.graphics.svg.SVGUniverse;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Logger;
public class SimpleSVGLoadTest {
@ -14,5 +15,6 @@ public class SimpleSVGLoadTest {
InputStream inputStream = getClass().getResourceAsStream("test.svg");
SVGUniverse svgUniverse = new SVGUniverse();
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"
"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" ?>
<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>

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB