working on salamander svg cleanup

This commit is contained in:
Jörg Prante 2021-12-17 09:59:30 +01:00
parent 1e639a73b4
commit 958b6eae64
113 changed files with 1584 additions and 26462 deletions

View file

@ -1,5 +1,6 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg;
import org.xbib.graphics.svg.element.Group;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.io.IOException; import java.io.IOException;

View file

@ -0,0 +1,39 @@
package org.xbib.graphics.svg;
import java.awt.Composite;
import java.awt.CompositeContext;
import java.awt.RenderingHints;
import java.awt.image.ColorModel;
public class AdobeComposite implements Composite {
public static final int CT_NORMAL = 0;
public static final int CT_MULTIPLY = 1;
public static final int CT_LAST = 2;
final int compositeType;
final float extraAlpha;
public AdobeComposite(int compositeType, float extraAlpha) {
this.compositeType = compositeType;
this.extraAlpha = extraAlpha;
if (compositeType < 0 || compositeType >= CT_LAST) {
throw new IllegalArgumentException("Invalid composite type");
}
if (extraAlpha < 0f || extraAlpha > 1f) {
throw new IllegalArgumentException("Invalid alpha");
}
}
public int getCompositeType() {
return compositeType;
}
@Override
public CompositeContext createContext(ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints) {
return new AdobeCompositeContext(compositeType, extraAlpha);
}
}

View file

@ -0,0 +1,57 @@
package org.xbib.graphics.svg;
import java.awt.CompositeContext;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
public class AdobeCompositeContext implements CompositeContext {
final int compositeType;
final float extraAlpha;
float[] rgba_src = new float[4];
float[] rgba_dstIn = new float[4];
float[] rgba_dstOut = new float[4];
public AdobeCompositeContext(int compositeType, float extraAlpha) {
this.compositeType = compositeType;
this.extraAlpha = extraAlpha;
rgba_dstOut[3] = 1f;
}
@Override
public void compose(Raster src, Raster dstIn, WritableRaster dstOut) {
int width = src.getWidth();
int height = src.getHeight();
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
src.getPixel(i, j, rgba_src);
dstIn.getPixel(i, j, rgba_dstIn);
if (rgba_src[3] == 0) {
continue;
}
float alpha = rgba_src[3];
switch (compositeType) {
default:
case AdobeComposite.CT_NORMAL:
rgba_dstOut[0] = rgba_src[0] * alpha + rgba_dstIn[0] * (1f - alpha);
rgba_dstOut[1] = rgba_src[1] * alpha + rgba_dstIn[1] * (1f - alpha);
rgba_dstOut[2] = rgba_src[2] * alpha + rgba_dstIn[2] * (1f - alpha);
break;
case AdobeComposite.CT_MULTIPLY:
rgba_dstOut[0] = rgba_src[0] * rgba_dstIn[0] * alpha + rgba_dstIn[0] * (1f - alpha);
rgba_dstOut[1] = rgba_src[1] * rgba_dstIn[1] * alpha + rgba_dstIn[1] * (1f - alpha);
rgba_dstOut[2] = rgba_src[2] * rgba_dstIn[2] * alpha + rgba_dstIn[2] * (1f - alpha);
break;
}
}
}
}
@Override
public void dispose() {
}
}

View file

@ -1,159 +0,0 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on January 26, 2004, 1:56 AM
*/
package org.xbib.graphics.svg;
import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Shape;
import java.awt.geom.Area;
import java.io.IOException;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class ClipPath extends SVGElement {
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;
/**
* Creates a new instance of Stop
*/
public ClipPath() {
}
@Override
public String getTagName() {
return TAG_NAME;
}
/**
* Called after the start element but before the end element to indicate
* each child tag that has been processed
*/
@Override
public void loaderAddChild(SVGLoaderHelper helper, SVGElement child) throws SVGElementException {
super.loaderAddChild(helper, child);
}
@Override
protected void build() throws SVGException, IOException {
super.build();
StyleAttribute sty = new StyleAttribute();
clipPathUnits = (getPres(sty.setName("clipPathUnits"))
&& sty.getStringValue().equals("objectBoundingBox"))
? CP_OBJECT_BOUNDING_BOX
: CP_USER_SPACE_ON_USE;
}
public int getClipPathUnits() {
return clipPathUnits;
}
public Shape getClipPathShape() {
if (children.isEmpty()) {
return null;
}
if (children.size() == 1) {
return ((ShapeElement) children.get(0)).getShape();
}
Area clipArea = null;
for (SVGElement svgElement : children) {
ShapeElement se = (ShapeElement) svgElement;
if (clipArea == null) {
Shape shape = se.getShape();
if (shape != null) {
clipArea = new Area(se.getShape());
}
continue;
}
Shape shape = se.getShape();
if (shape != null) {
clipArea.intersect(new Area(shape));
}
}
return clipArea;
}
/**
* Updates all attributes in this diagram associated with a time event. Ie,
* all attributes with track information.
*
* @param curTime Time at which to evaluate node
* @return - true if this node has changed state as a result of the time
* update
* @throws SVGException
*/
@Override
public boolean updateTime(double curTime) throws SVGException, IOException {
//Get current values for parameters
StyleAttribute sty = new StyleAttribute();
boolean shapeChange = false;
if (getPres(sty.setName("clipPathUnits"))) {
String newUnitsStrn = sty.getStringValue();
int newUnits = newUnitsStrn.equals("objectBoundingBox")
? CP_OBJECT_BOUNDING_BOX
: CP_USER_SPACE_ON_USE;
if (newUnits != clipPathUnits) {
clipPathUnits = newUnits;
shapeChange = true;
}
}
if (shapeChange) {
build();
}
for (int i = 0; i < children.size(); ++i) {
SVGElement ele = children.get(i);
ele.updateTime(curTime);
}
return shapeChange;
}
}

View file

@ -1,91 +0,0 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on January 26, 2004, 1:56 AM
*/
package org.xbib.graphics.svg;
import org.xbib.graphics.svg.xml.StyleSheet;
import java.io.IOException;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class Defs extends TransformableElement {
public static final String TAG_NAME = "defs";
/**
* Creates a new instance of Stop
*/
public Defs() {
}
@Override
public String getTagName() {
return TAG_NAME;
}
/**
* Called after the start element but before the end element to indicate
* each child tag that has been processed
*/
@Override
public void loaderAddChild(SVGLoaderHelper helper, SVGElement child) throws SVGElementException {
super.loaderAddChild(helper, child);
// members.add(child);
}
@Override
public boolean updateTime(double curTime) throws SVGException, IOException {
boolean stateChange = false;
for (SVGElement ele : children) {
stateChange = stateChange || ele.updateTime(curTime);
}
return super.updateTime(curTime) || stateChange;
}
public StyleSheet getStyleSheet() {
for (int i = 0; i < getNumChildren(); ++i) {
SVGElement ele = getChild(i);
if (ele instanceof Style) {
return ((Style) ele).getStyleSheet();
}
}
return null;
}
}

View file

@ -1,76 +0,0 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on September 19, 2004, 1:56 AM
*/
package org.xbib.graphics.svg;
/**
* Holds title textual information within tree
*
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class Desc extends SVGElement {
public static final String TAG_NAME = "desc";
StringBuffer text = new StringBuffer();
/**
* Creates a new instance of Stop
*/
public Desc() {
}
@Override
public String getTagName() {
return TAG_NAME;
}
/**
* Called during load process to add text scanned within a tag
*/
@Override
public void loaderAddText(SVGLoaderHelper helper, String text) {
this.text.append(text);
}
public String getText() {
return text.toString();
}
@Override
public boolean updateTime(double curTime) {
return false;
}
}

View file

@ -1,112 +0,0 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on March 18, 2004, 6:52 AM
*/
package org.xbib.graphics.svg;
import org.xbib.graphics.svg.xml.StyleAttribute;
import java.io.IOException;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class FeDistantLight extends FeLight {
public static final String TAG_NAME = "fedistantlight";
float azimuth = 0f;
float elevation = 0f;
/**
* Creates a new instance of FillElement
*/
public FeDistantLight() {
}
@Override
public String getTagName() {
return TAG_NAME;
}
@Override
protected void build() throws SVGException, IOException {
super.build();
StyleAttribute sty = new StyleAttribute();
if (getPres(sty.setName("azimuth"))) {
azimuth = sty.getFloatValueWithUnits();
}
if (getPres(sty.setName("elevation"))) {
elevation = sty.getFloatValueWithUnits();
}
}
public float getAzimuth() {
return azimuth;
}
public float getElevation() {
return elevation;
}
@Override
public boolean updateTime(double curTime) throws SVGException {
// if (trackManager.getNumTracks() == 0) return false;
//Get current values for parameters
StyleAttribute sty = new StyleAttribute();
boolean stateChange = false;
if (getPres(sty.setName("azimuth"))) {
float newVal = sty.getFloatValueWithUnits();
if (newVal != azimuth) {
azimuth = newVal;
stateChange = true;
}
}
if (getPres(sty.setName("elevation"))) {
float newVal = sty.getFloatValueWithUnits();
if (newVal != elevation) {
elevation = newVal;
stateChange = true;
}
}
return stateChange;
}
}

View file

@ -1,56 +0,0 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on March 18, 2004, 6:52 AM
*/
package org.xbib.graphics.svg;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
abstract public class FeLight extends FilterEffects {
public static final String TAG_NAME = "feLight";
/**
* Creates a new instance of FillElement
*/
public FeLight() {
}
@Override
public String getTagName() {
return TAG_NAME;
}
}

View file

@ -1,131 +0,0 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on March 18, 2004, 6:52 AM
*/
package org.xbib.graphics.svg;
import org.xbib.graphics.svg.xml.StyleAttribute;
import java.io.IOException;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class FePointLight extends FeLight {
public static final String TAG_NAME = "fepointlight";
float x = 0f;
float y = 0f;
float z = 0f;
/**
* Creates a new instance of FillElement
*/
public FePointLight() {
}
@Override
public String getTagName() {
return TAG_NAME;
}
@Override
protected void build() throws SVGException, IOException {
super.build();
StyleAttribute sty = new StyleAttribute();
if (getPres(sty.setName("x"))) {
x = sty.getFloatValueWithUnits();
}
if (getPres(sty.setName("y"))) {
y = sty.getFloatValueWithUnits();
}
if (getPres(sty.setName("z"))) {
z = sty.getFloatValueWithUnits();
}
}
@Override
public float getX() {
return x;
}
@Override
public float getY() {
return y;
}
public float getZ() {
return z;
}
@Override
public boolean updateTime(double curTime) throws SVGException {
// if (trackManager.getNumTracks() == 0) return false;
//Get current values for parameters
StyleAttribute sty = new StyleAttribute();
boolean stateChange = false;
if (getPres(sty.setName("x"))) {
float newVal = sty.getFloatValueWithUnits();
if (newVal != x) {
x = newVal;
stateChange = true;
}
}
if (getPres(sty.setName("y"))) {
float newVal = sty.getFloatValueWithUnits();
if (newVal != y) {
y = newVal;
stateChange = true;
}
}
if (getPres(sty.setName("z"))) {
float newVal = sty.getFloatValueWithUnits();
if (newVal != z) {
z = newVal;
stateChange = true;
}
}
return stateChange;
}
}

View file

@ -1,63 +0,0 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on March 18, 2004, 6:52 AM
*/
package org.xbib.graphics.svg;
import java.awt.Paint;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
abstract public class FillElement extends SVGElement {
/**
* Creates a new instance of FillElement
*/
public FillElement() {
}
/**
* Requests the paint defined by this element. Passes in information to
* allow paint to be customized
*
* @param bounds - bounding box of shape being rendered
* @param xform - The current transformation that the shape is being
* rendered under.
* @return paint object
*/
abstract public Paint getPaint(Rectangle2D bounds, AffineTransform xform);
}

View file

@ -1,251 +0,0 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on March 18, 2004, 6:52 AM
*/
package org.xbib.graphics.svg;
import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Rectangle;
import java.awt.image.BufferedImageOp;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.util.List;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public abstract class FilterEffects extends SVGElement {
public static final String TAG_NAME = "filtereffects";
public static final int FP_SOURCE_GRAPHIC = 0;
public static final int FP_SOURCE_ALPHA = 1;
public static final int FP_BACKGROUND_IMAGE = 2;
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;
private int filterPrimitiveTypeIn;
private String filterPrimitiveRefIn;
float x = 0f;
float y = 0f;
float width = 1f;
float height = 1f;
URL href = null;
/**
* Creates a new instance of FillElement
*/
public FilterEffects() {
}
@Override
public String getTagName() {
return TAG_NAME;
}
/**
* Called after the start element but before the end element to indicate
* each child tag that has been processed
*/
@Override
public void loaderAddChild(SVGLoaderHelper helper, SVGElement child) throws SVGElementException {
super.loaderAddChild(helper, child);
if (child instanceof FilterEffects) {
// filterEffects.add(child);
}
}
@Override
protected void build() throws SVGException, IOException {
super.build();
/*StyleAttribute sty = new StyleAttribute();
String strn;
if (getPres(sty.setName("filterUnits")))
{
strn = sty.getStringValue().toLowerCase();
if (strn.equals("userspaceonuse")) filterUnits = FU_USER_SPACE_ON_USE;
else filterUnits = FU_OBJECT_BOUNDING_BOX;
}
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.getFloatValue();
if (getPres(sty.setName("y"))) y = sty.getFloatValue();
if (getPres(sty.setName("width"))) width = sty.getFloatValue();
if (getPres(sty.setName("height"))) height = sty.getFloatValue();
try {
if (getPres(sty.setName("xlink:href")))
{
URI src = sty.getURIValue(getXMLBase());
href = src.toURL();
}
}
catch (Exception e)
{
throw new SVGException(e);
}
*/
}
public List<FilterOp> getOperations(Rectangle bounds, float xScale, float yScale) {
return null;
}
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 {
// if (trackManager.getNumTracks() == 0) return false;
//Get current values for parameters
StyleAttribute sty = new StyleAttribute();
boolean stateChange = false;
if (getPres(sty.setName("x"))) {
float newVal = sty.getFloatValueWithUnits();
if (newVal != x) {
x = newVal;
stateChange = true;
}
}
if (getPres(sty.setName("y"))) {
float newVal = sty.getFloatValueWithUnits();
if (newVal != y) {
y = newVal;
stateChange = true;
}
}
if (getPres(sty.setName("width"))) {
float newVal = sty.getFloatValueWithUnits();
if (newVal != width) {
width = newVal;
stateChange = true;
}
}
if (getPres(sty.setName("height"))) {
float newVal = sty.getFloatValueWithUnits();
if (newVal != height) {
height = newVal;
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;
}
}
} catch (Exception e) {
throw new SVGException(e);
}
/*
if (getPres(sty.setName("filterUnits")))
{
int newVal;
String strn = sty.getStringValue().toLowerCase();
if (strn.equals("userspaceonuse")) newVal = FU_USER_SPACE_ON_USE;
else newVal = FU_OBJECT_BOUNDING_BOX;
if (newVal != filterUnits)
{
filterUnits = newVal;
stateChange = true;
}
}
if (getPres(sty.setName("primitiveUnits")))
{
int newVal;
String strn = sty.getStringValue().toLowerCase();
if (strn.equals("userspaceonuse")) newVal = PU_USER_SPACE_ON_USE;
else newVal = PU_OBJECT_BOUNDING_BOX;
if (newVal != filterUnits)
{
primitiveUnits = newVal;
stateChange = true;
}
}
*/
return stateChange;
}
public static class FilterOp {
public final BufferedImageOp op;
public final Rectangle requiredImageBounds;
public FilterOp(BufferedImageOp op, Rectangle requiredImageBounds) {
this.op = op;
this.requiredImageBounds = requiredImageBounds;
}
}
}

View file

@ -1,5 +1,7 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg;
import org.xbib.graphics.svg.element.Font;
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;

View file

@ -1,70 +1,32 @@
/* package org.xbib.graphics.svg;
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on April 24, 2015
*/
package org.xbib.graphics.svg.util;
import org.xbib.graphics.svg.Font; import org.xbib.graphics.svg.element.Font;
import org.xbib.graphics.svg.FontFace; import org.xbib.graphics.svg.element.glyph.Glyph;
import org.xbib.graphics.svg.Glyph; import org.xbib.graphics.svg.element.glyph.MissingGlyph;
import org.xbib.graphics.svg.MissingGlyph;
import org.xbib.graphics.svg.Text;
import java.awt.GraphicsEnvironment; 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.HashSet;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
import java.util.Set;
/**
* @author kitfox
*/
public class FontSystem extends Font { public class FontSystem extends Font {
java.awt.Font sysFont; java.awt.Font sysFont;
HashMap<String, Glyph> glyphCache = new HashMap<>(); Map<String, Glyph> glyphCache = new HashMap<>();
static HashSet<String> sysFontNames = new HashSet<>(); static Set<String> sysFontNames = new HashSet<>();
public static boolean checkIfSystemFontExists(String fontName) { public static boolean checkIfSystemFontExists(String fontName) {
if (sysFontNames.isEmpty()) { if (sysFontNames.isEmpty()) {
for (String name : GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(Locale.ENGLISH)) { Collections.addAll(sysFontNames, GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(Locale.ENGLISH));
sysFontNames.add(name);
}
} }
return sysFontNames.contains(fontName); return sysFontNames.contains(fontName);
@ -94,15 +56,11 @@ public class FontSystem extends Font {
private FontSystem(String fontFamily, int fontStyle, int fontWeight, float fontSize) { private FontSystem(String fontFamily, int fontStyle, int fontWeight, float fontSize) {
int style; int style;
switch (fontStyle) { if (fontStyle == Text.TXST_ITALIC) {
case Text.TXST_ITALIC: style = java.awt.Font.ITALIC;
style = java.awt.Font.ITALIC; } else {
break; style = java.awt.Font.PLAIN;
default:
style = java.awt.Font.PLAIN;
break;
} }
int weight; int weight;
switch (fontWeight) { switch (fontWeight) {
case Text.TXWE_BOLD: case Text.TXWE_BOLD:
@ -113,12 +71,9 @@ public class FontSystem extends Font {
weight = java.awt.Font.PLAIN; weight = java.awt.Font.PLAIN;
break; break;
} }
sysFont = new java.awt.Font(fontFamily, style | weight, 1).deriveFont(fontSize); sysFont = new java.awt.Font(fontFamily, style | weight, 1).deriveFont(fontSize);
FontRenderContext fontRenderContext = new FontRenderContext(null, true, true); FontRenderContext fontRenderContext = new FontRenderContext(null, true, true);
LineMetrics lineMetrics = sysFont.getLineMetrics("M", fontRenderContext); LineMetrics lineMetrics = sysFont.getLineMetrics("M", fontRenderContext);
FontFace face = new FontFace(); FontFace face = new FontFace();
face.setAscent((int) lineMetrics.getAscent()); face.setAscent((int) lineMetrics.getAscent());
face.setDescent((int) lineMetrics.getDescent()); face.setDescent((int) lineMetrics.getDescent());
@ -130,23 +85,17 @@ public class FontSystem extends Font {
public MissingGlyph getGlyph(String unicode) { public MissingGlyph getGlyph(String unicode) {
FontRenderContext frc = new FontRenderContext(null, true, true); FontRenderContext frc = new FontRenderContext(null, true, true);
GlyphVector vec = sysFont.createGlyphVector(frc, unicode); GlyphVector vec = sysFont.createGlyphVector(frc, unicode);
Glyph glyph = glyphCache.get(unicode); Glyph glyph = glyphCache.get(unicode);
if (glyph == null) { if (glyph == null) {
glyph = new Glyph(); glyph = new Glyph();
glyph.setPath(vec.getGlyphOutline(0)); glyph.setPath(vec.getGlyphOutline(0));
GlyphMetrics gm = vec.getGlyphMetrics(0); GlyphMetrics gm = vec.getGlyphMetrics(0);
glyph.setHorizAdvX(gm.getAdvanceX()); glyph.setHorizAdvX(gm.getAdvanceX());
glyph.setVertAdvY(gm.getAdvanceY()); glyph.setVertAdvY(gm.getAdvanceY());
glyph.setVertOriginX(0); glyph.setVertOriginX(0);
glyph.setVertOriginY(0); glyph.setVertOriginY(0);
glyphCache.put(unicode, glyph); glyphCache.put(unicode, glyph);
} }
return glyph; return glyph;
} }
} }

View file

@ -1,97 +0,0 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on February 20, 2004, 10:00 PM
*/
package org.xbib.graphics.svg;
import org.xbib.graphics.svg.xml.StyleAttribute;
import java.io.IOException;
/**
* Implements an embedded font.
* <p>
* SVG specification: http://www.w3.org/TR/SVG/fonts.html
*
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class Glyph extends MissingGlyph {
public static final String TAG_NAME = "missingglyph";
/**
* One or more characters indicating the unicode sequence that denotes this
* glyph.
*/
String unicode;
/**
* Creates a new instance of Font
*/
public Glyph() {
}
@Override
public String getTagName() {
return TAG_NAME;
}
@Override
protected void build() throws SVGException, IOException {
super.build();
StyleAttribute sty = new StyleAttribute();
if (getPres(sty.setName("unicode"))) {
unicode = sty.getStringValue();
}
}
public String getUnicode() {
return unicode;
}
/**
* 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 {
//Fonts can't change
return false;
}
}

View file

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

View file

@ -1,4 +1,6 @@
package org.xbib.graphics.svg.app.data; package org.xbib.graphics.svg;
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,52 +1,18 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on February 20, 2004, 10:00 PM
*/
package org.xbib.graphics.svg; package org.xbib.graphics.svg;
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;
/**
* @author kitfox
*/
public class Hkern extends SVGElement { public class Hkern extends SVGElement {
public static final String TAG_NAME = "hkern"; public static final String TAG_NAME = "hkern";
String u1; String u1;
String u2; String u2;
int k; int k;
@Override @Override
@ -57,19 +23,13 @@ public class Hkern extends SVGElement {
@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("u1"))) {
//Read glyph spacing info
if (getPres(sty.setName("u1"))) {
u1 = sty.getStringValue(); u1 = sty.getStringValue();
} }
if (getPres(sty.setName("u2"))) { if (getPres(sty.setName("u2"))) {
u2 = sty.getStringValue(); u2 = sty.getStringValue();
} }
if (getPres(sty.setName("k"))) { if (getPres(sty.setName("k"))) {
k = sty.getIntValue(); k = sty.getIntValue();
} }
@ -77,7 +37,6 @@ public class Hkern extends SVGElement {
@Override @Override
public boolean updateTime(double curTime) throws SVGException { public boolean updateTime(double curTime) throws SVGException {
//Fonts can't change
return false; return false;
} }
} }

View file

@ -1,6 +1,7 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg;
import org.xbib.graphics.svg.app.data.Handler; import org.xbib.graphics.svg.element.RenderableElement;
import org.xbib.graphics.svg.element.SVGElement;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.AlphaComposite; import java.awt.AlphaComposite;
@ -19,6 +20,8 @@ import java.util.logging.Logger;
public class ImageSVG extends RenderableElement { public class ImageSVG extends RenderableElement {
private static final Logger logger = Logger.getLogger(ImageSVG.class.getName());
public static final String TAG_NAME = "image"; public static final String TAG_NAME = "image";
float x = 0f; float x = 0f;
@ -67,8 +70,7 @@ public class ImageSVG extends RenderableElement {
try { try {
imageSrc = src.toURL(); imageSrc = src.toURL();
} catch (Exception e) { } catch (Exception e) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, logger.log(Level.SEVERE, "Could not parse xlink:href " + src, e);
"Could not parse xlink:href " + src, e);
imageSrc = null; imageSrc = null;
} }
} }
@ -111,21 +113,21 @@ public class ImageSVG extends RenderableElement {
} }
@Override @Override
protected void doPick(Point2D point, boolean boundingBox, List<List<SVGElement>> retVec) { public void doPick(Point2D point, boolean boundingBox, List<List<SVGElement>> retVec) {
if (getBoundingBox().contains(point)) { if (getBoundingBox().contains(point)) {
retVec.add(getPath(null)); retVec.add(getPath(null));
} }
} }
@Override @Override
protected void doPick(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List<List<SVGElement>> retVec) { public void doPick(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List<List<SVGElement>> retVec) {
if (ltw.createTransformedShape(getBoundingBox()).intersects(pickArea)) { if (ltw.createTransformedShape(getBoundingBox()).intersects(pickArea)) {
retVec.add(getPath(null)); retVec.add(getPath(null));
} }
} }
@Override @Override
protected void doRender(Graphics2D g) throws SVGException, IOException { public void doRender(Graphics2D g) throws SVGException, IOException {
StyleAttribute styleAttrib = new StyleAttribute(); StyleAttribute styleAttrib = new StyleAttribute();
if (getStyle(styleAttrib.setName("visibility"))) { if (getStyle(styleAttrib.setName("visibility"))) {
if (!styleAttrib.getStringValue().equals("visible")) { if (!styleAttrib.getStringValue().equals("visible")) {
@ -218,12 +220,10 @@ public class ImageSVG extends RenderableElement {
} }
} }
} catch (IllegalArgumentException ie) { } catch (IllegalArgumentException ie) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, logger.log(Level.SEVERE, "Image provided with illegal value for href: \""
"Image provided with illegal value for href: \""
+ sty.getStringValue() + '"', ie); + sty.getStringValue() + '"', ie);
} catch (Exception e) { } catch (Exception e) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, logger.log(Level.WARNING, "Could not parse xlink:href", e);
"Could not parse xlink:href", e);
} }
if (shapeChange) { if (shapeChange) {
build(); build();

View file

@ -1,21 +1,25 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg;
import org.xbib.graphics.svg.element.Group;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.Shape; import java.awt.Shape;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
import java.awt.geom.PathIterator;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class Marker extends Group { public class Marker extends Group {
public static final String TAG_NAME = "marker"; 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; AffineTransform viewXform;
AffineTransform markerXform; AffineTransform markerXform;
@ -93,7 +97,7 @@ public class Marker extends Group {
} }
@Override @Override
protected void doRender(Graphics2D g) throws SVGException, IOException { public void doRender(Graphics2D g) throws SVGException, IOException {
AffineTransform oldXform = g.getTransform(); AffineTransform oldXform = g.getTransform();
g.transform(markerXform); g.transform(markerXform);
super.doRender(g); super.doRender(g);
@ -130,137 +134,4 @@ public class Marker extends Group {
build(); build();
return changeState; return changeState;
} }
public static final int MARKER_START = 0;
public static final int MARKER_MID = 1;
public static final int MARKER_END = 2;
public static class MarkerPos {
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 static class MarkerLayout {
private final List<MarkerPos> markerList = new ArrayList<>();
boolean started = false;
public void layout(Shape shape) {
double px = 0;
double py = 0;
double[] coords = new double[6];
for (PathIterator it = shape.getPathIterator(null);
!it.isDone(); it.next()) {
switch (it.currentSegment(coords)) {
case PathIterator.SEG_MOVETO:
px = coords[0];
py = coords[1];
started = false;
break;
case PathIterator.SEG_CLOSE:
started = false;
break;
case PathIterator.SEG_LINETO: {
double x = coords[0];
double y = coords[1];
markerIn(px, py, x - px, y - py);
markerOut(x, y, x - px, y - py);
px = x;
py = y;
break;
}
case PathIterator.SEG_QUADTO: {
double k0x = coords[0];
double k0y = coords[1];
double x = coords[2];
double y = coords[3];
if (px != k0x || py != k0y) {
markerIn(px, py, k0x - px, k0y - py);
} else {
markerIn(px, py, x - px, y - py);
}
if (x != k0x || y != k0y) {
markerOut(x, y, x - k0x, y - k0y);
} else {
markerOut(x, y, x - px, y - py);
}
markerIn(px, py, k0x - px, k0y - py);
markerOut(x, y, x - k0x, y - k0y);
px = x;
py = y;
break;
}
case PathIterator.SEG_CUBICTO: {
double k0x = coords[0];
double k0y = coords[1];
double k1x = coords[2];
double k1y = coords[3];
double x = coords[4];
double y = coords[5];
if (px != k0x || py != k0y) {
markerIn(px, py, k0x - px, k0y - py);
} else if (px != k1x || py != k1y) {
markerIn(px, py, k1x - px, k1y - py);
} else {
markerIn(px, py, x - px, y - py);
}
if (x != k1x || y != k1y) {
markerOut(x, y, x - k1x, y - k1y);
} else if (x != k0x || y != k0y) {
markerOut(x, y, x - k0x, y - k0y);
} else {
markerOut(x, y, x - px, y - py);
}
px = x;
py = y;
break;
}
}
}
for (int i = 1; i < markerList.size(); ++i) {
MarkerPos prev = markerList.get(i - 1);
MarkerPos cur = markerList.get(i);
if (cur.type == MARKER_START) {
prev.type = MARKER_END;
}
}
MarkerPos last = markerList.get(markerList.size() - 1);
last.type = MARKER_END;
}
private void markerIn(double x, double y, double dx, double dy) {
if (!started) {
started = true;
markerList.add(new MarkerPos(MARKER_START, x, y, dx, dy));
}
}
private void markerOut(double x, double y, double dx, double dy) {
markerList.add(new MarkerPos(MARKER_MID, x, y, dx, dy));
}
public List<MarkerPos> getMarkerList() {
return markerList;
}
}
} }

View file

@ -0,0 +1,112 @@
package org.xbib.graphics.svg;
import java.awt.Shape;
import java.awt.geom.PathIterator;
import java.util.ArrayList;
import java.util.List;
public class MarkerLayout {
private final List<MarkerPos> markerList = new ArrayList<>();
boolean started = false;
public void layout(Shape shape) {
double px = 0;
double py = 0;
double[] coords = new double[6];
for (PathIterator it = shape.getPathIterator(null);
!it.isDone(); it.next()) {
switch (it.currentSegment(coords)) {
case PathIterator.SEG_MOVETO:
px = coords[0];
py = coords[1];
started = false;
break;
case PathIterator.SEG_CLOSE:
started = false;
break;
case PathIterator.SEG_LINETO: {
double x = coords[0];
double y = coords[1];
markerIn(px, py, x - px, y - py);
markerOut(x, y, x - px, y - py);
px = x;
py = y;
break;
}
case PathIterator.SEG_QUADTO: {
double k0x = coords[0];
double k0y = coords[1];
double x = coords[2];
double y = coords[3];
if (px != k0x || py != k0y) {
markerIn(px, py, k0x - px, k0y - py);
} else {
markerIn(px, py, x - px, y - py);
}
if (x != k0x || y != k0y) {
markerOut(x, y, x - k0x, y - k0y);
} else {
markerOut(x, y, x - px, y - py);
}
markerIn(px, py, k0x - px, k0y - py);
markerOut(x, y, x - k0x, y - k0y);
px = x;
py = y;
break;
}
case PathIterator.SEG_CUBICTO: {
double k0x = coords[0];
double k0y = coords[1];
double k1x = coords[2];
double k1y = coords[3];
double x = coords[4];
double y = coords[5];
if (px != k0x || py != k0y) {
markerIn(px, py, k0x - px, k0y - py);
} else if (px != k1x || py != k1y) {
markerIn(px, py, k1x - px, k1y - py);
} else {
markerIn(px, py, x - px, y - py);
}
if (x != k1x || y != k1y) {
markerOut(x, y, x - k1x, y - k1y);
} else if (x != k0x || y != k0y) {
markerOut(x, y, x - k0x, y - k0y);
} else {
markerOut(x, y, x - px, y - py);
}
px = x;
py = y;
break;
}
}
}
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);
}
}
MarkerPos last = markerList.get(markerList.size() - 1);
last.setType(Marker.MARKER_END);
}
private void markerIn(double x, double y, double dx, double dy) {
if (!started) {
started = true;
markerList.add(new MarkerPos(Marker.MARKER_START, x, y, dx, dy));
}
}
private void markerOut(double x, double y, double dx, double dy) {
markerList.add(new MarkerPos(Marker.MARKER_MID, x, y, dx, dy));
}
public List<MarkerPos> getMarkerList() {
return markerList;
}
}

View file

@ -0,0 +1,30 @@
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,52 +1,11 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on September 19, 2004, 1:56 AM
*/
package org.xbib.graphics.svg; package org.xbib.graphics.svg;
/** import org.xbib.graphics.svg.element.SVGElement;
* Does not hold any information. Included to allow metadata tag to be parsed.
*
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class Metadata extends SVGElement { public class Metadata extends SVGElement {
public static final String TAG_NAME = "metadata"; public static final String TAG_NAME = "metadata";
/**
* Creates a new instance of Stop
*/
public Metadata() { public Metadata() {
} }

View file

@ -1,40 +1,6 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on January 26, 2004, 5:25 PM
*/
package org.xbib.graphics.svg; package org.xbib.graphics.svg;
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;
@ -43,22 +9,16 @@ import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.io.IOException; import java.io.IOException;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class Path extends ShapeElement { public class Path extends ShapeElement {
public static final String TAG_NAME = "path"; public static final String TAG_NAME = "path";
// PathCommand[] commands = null;
int fillRule = GeneralPath.WIND_NON_ZERO; int fillRule = GeneralPath.WIND_NON_ZERO;
String d = ""; String d = "";
// ExtendedGeneralPath path;
GeneralPath path; GeneralPath path;
/**
* Creates a new instance of Rect
*/
public Path() { public Path() {
} }
@ -70,22 +30,17 @@ public class Path extends ShapeElement {
@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();
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;
if (getPres(sty.setName("d"))) { if (getPres(sty.setName("d"))) {
d = sty.getStringValue(); d = sty.getStringValue();
} }
path = buildPath(d, fillRule); path = buildPath(d, fillRule);
} }
@Override @Override
protected void doRender(Graphics2D g) throws SVGException, IOException { public void doRender(Graphics2D g) throws SVGException, IOException {
beginLayer(g); beginLayer(g);
renderShape(g, path); renderShape(g, path);
finishLayer(g); finishLayer(g);
@ -101,22 +56,11 @@ public class Path 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
@ -126,7 +70,6 @@ public class Path extends ShapeElement {
changeState = true; changeState = true;
} }
} }
if (getPres(sty.setName("d"))) { if (getPres(sty.setName("d"))) {
String newVal = sty.getStringValue(); String newVal = sty.getStringValue();
if (!newVal.equals(d)) { if (!newVal.equals(d)) {
@ -134,13 +77,9 @@ public class Path extends ShapeElement {
shapeChange = true; shapeChange = true;
} }
} }
if (shapeChange) { if (shapeChange) {
build(); build();
// path = buildPath(d, fillRule);
// return true;
} }
return changeState || shapeChange; return changeState || shapeChange;
} }
} }

View file

@ -0,0 +1,37 @@
package org.xbib.graphics.svg;
import java.awt.Paint;
import java.awt.PaintContext;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
public class PatternPaint implements Paint {
BufferedImage source;
AffineTransform xform;
public PatternPaint(BufferedImage source, AffineTransform xform) {
this.source = source;
this.xform = xform;
}
@Override
public PaintContext createContext(ColorModel cm, Rectangle deviceBounds, Rectangle2D userBounds, AffineTransform xform, RenderingHints hints) {
try {
return new PatternPaintContext(source, deviceBounds, xform, this.xform);
} catch (NoninvertibleTransformException e) {
throw new RuntimeException(e);
}
}
public int getTransparency() {
return source.getColorModel().getTransparency();
}
}

View file

@ -0,0 +1,63 @@
package org.xbib.graphics.svg;
import java.awt.PaintContext;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
public class PatternPaintContext implements PaintContext {
BufferedImage source;
Rectangle deviceBounds;
AffineTransform xform;
int sourceWidth;
int sourceHeight;
BufferedImage buf;
public PatternPaintContext(BufferedImage source, Rectangle deviceBounds, AffineTransform userXform, AffineTransform distortXform) throws NoninvertibleTransformException {
this.source = source;
this.deviceBounds = deviceBounds;
xform = distortXform.createInverse();
xform.concatenate(userXform.createInverse());
sourceWidth = source.getWidth();
sourceHeight = source.getHeight();
}
@Override
public void dispose() {
}
@Override
public ColorModel getColorModel() {
return source.getColorModel();
}
@Override
public Raster getRaster(int x, int y, int w, int h) {
if (buf == null || buf.getWidth() != w || buf.getHeight() != h) {
buf = new BufferedImage(w, h, source.getType());
}
Point2D.Float srcPt = new Point2D.Float(), destPt = new Point2D.Float();
for (int j = 0; j < h; j++) {
for (int i = 0; i < w; i++) {
destPt.setLocation(i + x, j + y);
xform.transform(destPt, srcPt);
int ii = ((int) srcPt.x) % sourceWidth;
if (ii < 0) ii += sourceWidth;
int jj = ((int) srcPt.y) % sourceHeight;
if (jj < 0) jj += sourceHeight;
buf.setRGB(i, j, source.getRGB(ii, jj));
}
}
return buf.getData();
}
}

View file

@ -1,41 +1,8 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on January 26, 2004, 3:25 AM
*/
package org.xbib.graphics.svg; package org.xbib.graphics.svg;
import org.xbib.graphics.svg.pattern.PatternPaint; 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.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Graphics2D; import java.awt.Graphics2D;
@ -48,30 +15,31 @@ import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class PatternSVG extends FillElement { public class PatternSVG extends FillElement {
public static final String TAG_NAME = "pattern"; 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; int gradientUnits = GU_OBJECT_BOUNDING_BOX;
float x; float x;
float y; float y;
float width; float width;
float height; float height;
AffineTransform patternXform = new AffineTransform(); AffineTransform patternXform = new AffineTransform();
Rectangle2D.Float viewBox; Rectangle2D.Float viewBox;
Paint texPaint; Paint texPaint;
/**
* Creates a new instance of Gradient
*/
public PatternSVG() { public PatternSVG() {
} }
@ -80,10 +48,6 @@ public class PatternSVG extends FillElement {
return TAG_NAME; return TAG_NAME;
} }
/**
* Called after the start element but before the end element to indicate
* each child tag that has been processed
*/
@Override @Override
public void loaderAddChild(SVGLoaderHelper helper, SVGElement child) throws SVGElementException { public void loaderAddChild(SVGLoaderHelper helper, SVGElement child) throws SVGElementException {
super.loaderAddChild(helper, child); super.loaderAddChild(helper, child);
@ -92,36 +56,23 @@ public class PatternSVG extends FillElement {
@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();
//Load style string
String href = null; String href = null;
if (getPres(sty.setName("xlink:href"))) { if (getPres(sty.setName("xlink:href"))) {
href = sty.getStringValue(); href = sty.getStringValue();
} }
//String href = attrs.getValue("xlink:href");
//If we have a link to another pattern, initialize ourselves with it's values
if (href != null) { if (href != null) {
//System.err.println("Gradient.loaderStartElement() href '" + href + "'"); URI src = getXMLBase().resolve(href);
try { PatternSVG patSrc = (PatternSVG) diagram.getUniverse().getElement(src);
URI src = getXMLBase().resolve(href); gradientUnits = patSrc.gradientUnits;
PatternSVG patSrc = (PatternSVG) diagram.getUniverse().getElement(src); x = patSrc.x;
y = patSrc.y;
gradientUnits = patSrc.gradientUnits; width = patSrc.width;
x = patSrc.x; height = patSrc.height;
y = patSrc.y; viewBox = patSrc.viewBox;
width = patSrc.width; patternXform.setTransform(patSrc.patternXform);
height = patSrc.height; children.addAll(patSrc.children);
viewBox = patSrc.viewBox;
patternXform.setTransform(patSrc.patternXform);
children.addAll(patSrc.children);
} catch (Exception e) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING,
"Could not parse xlink:href", e);
}
} }
String gradientUnits = ""; String gradientUnits = "";
if (getPres(sty.setName("gradientUnits"))) { if (getPres(sty.setName("gradientUnits"))) {
gradientUnits = sty.getStringValue().toLowerCase(); gradientUnits = sty.getStringValue().toLowerCase();
@ -131,106 +82,72 @@ public class PatternSVG extends FillElement {
} else { } else {
this.gradientUnits = GU_OBJECT_BOUNDING_BOX; this.gradientUnits = GU_OBJECT_BOUNDING_BOX;
} }
String patternTransform = ""; String patternTransform = "";
if (getPres(sty.setName("patternTransform"))) { if (getPres(sty.setName("patternTransform"))) {
patternTransform = sty.getStringValue(); patternTransform = sty.getStringValue();
} }
patternXform = parseTransform(patternTransform); patternXform = parseTransform(patternTransform);
if (getPres(sty.setName("x"))) { if (getPres(sty.setName("x"))) {
x = sty.getFloatValueWithUnits(); x = sty.getFloatValueWithUnits();
} }
if (getPres(sty.setName("y"))) { if (getPres(sty.setName("y"))) {
y = sty.getFloatValueWithUnits(); y = sty.getFloatValueWithUnits();
} }
if (getPres(sty.setName("width"))) { if (getPres(sty.setName("width"))) {
width = sty.getFloatValueWithUnits(); width = sty.getFloatValueWithUnits();
} }
if (getPres(sty.setName("height"))) { if (getPres(sty.setName("height"))) {
height = sty.getFloatValueWithUnits(); height = sty.getFloatValueWithUnits();
} }
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]);
} }
preparePattern(); preparePattern();
} }
/*
public void loaderEndElement(SVGLoaderHelper helper)
{
build();
}
*/
protected void preparePattern() throws SVGException, IOException { protected void preparePattern() throws SVGException, IOException {
//For now, treat all fills as UserSpaceOnUse. Otherwise, we'll need
// a different paint for every object.
int tileWidth = (int) width; int tileWidth = (int) width;
int tileHeight = (int) height; int tileHeight = (int) height;
float stretchX = 1f, stretchY = 1f; float stretchX = 1f, stretchY = 1f;
if (!patternXform.isIdentity()) { if (!patternXform.isIdentity()) {
//Scale our source tile so that we can have nice sampling from it.
float xlateX = (float) patternXform.getTranslateX(); float xlateX = (float) patternXform.getTranslateX();
float xlateY = (float) patternXform.getTranslateY(); float xlateY = (float) patternXform.getTranslateY();
Point2D.Float pt = new Point2D.Float(), pt2 = new Point2D.Float(); Point2D.Float pt = new Point2D.Float(), pt2 = new Point2D.Float();
pt.setLocation(width, 0); pt.setLocation(width, 0);
patternXform.transform(pt, pt2); patternXform.transform(pt, pt2);
pt2.x -= xlateX; pt2.x -= xlateX;
pt2.y -= xlateY; pt2.y -= xlateY;
stretchX = (float) Math.sqrt(pt2.x * pt2.x + pt2.y * pt2.y) * 1.5f / width; stretchX = (float) Math.sqrt(pt2.x * pt2.x + pt2.y * pt2.y) * 1.5f / width;
pt.setLocation(height, 0); pt.setLocation(height, 0);
patternXform.transform(pt, pt2); patternXform.transform(pt, pt2);
pt2.x -= xlateX; pt2.x -= xlateX;
pt2.y -= xlateY; pt2.y -= xlateY;
stretchY = (float) Math.sqrt(pt2.x * pt2.x + pt2.y * pt2.y) * 1.5f / height; stretchY = (float) Math.sqrt(pt2.x * pt2.x + pt2.y * pt2.y) * 1.5f / height;
tileWidth *= stretchX; tileWidth *= stretchX;
tileHeight *= stretchY; tileHeight *= stretchY;
} }
if (tileWidth == 0 || tileHeight == 0) { if (tileWidth == 0 || tileHeight == 0) {
//Use defaults if tile has degenerate size
return; return;
} }
BufferedImage buf = new BufferedImage(tileWidth, tileHeight, BufferedImage.TYPE_INT_ARGB); BufferedImage buf = new BufferedImage(tileWidth, tileHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = buf.createGraphics(); Graphics2D g = buf.createGraphics();
g.setClip(0, 0, tileWidth, tileHeight); g.setClip(0, 0, tileWidth, tileHeight);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for (SVGElement ele : children) { for (SVGElement ele : children) {
if (ele instanceof RenderableElement) { if (ele instanceof RenderableElement) {
AffineTransform xform = new AffineTransform(); AffineTransform xform = new AffineTransform();
if (viewBox == null) { if (viewBox == null) {
xform.translate(-x, -y); xform.translate(-x, -y);
} else { } else {
xform.scale(tileWidth / viewBox.width, tileHeight / viewBox.height); xform.scale(tileWidth / viewBox.width, tileHeight / viewBox.height);
xform.translate(-viewBox.x, -viewBox.y); xform.translate(-viewBox.x, -viewBox.y);
} }
g.setTransform(xform); g.setTransform(xform);
((RenderableElement) ele).render(g); ((RenderableElement) ele).render(g);
} }
} }
g.dispose(); g.dispose();
//try {
//javax.imageio.ImageIO.write(buf, "png", new java.io.File("c:\\tmp\\texPaint.png"));
//} catch (Exception e ) {}
if (patternXform.isIdentity()) { if (patternXform.isIdentity()) {
texPaint = new TexturePaint(buf, new Rectangle2D.Float(x, y, width, height)); texPaint = new TexturePaint(buf, new Rectangle2D.Float(x, y, width, height));
} else { } else {
@ -244,16 +161,8 @@ public class PatternSVG extends FillElement {
return texPaint; return texPaint;
} }
/**
* 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 { public boolean updateTime(double curTime) throws SVGException {
//Patterns don't change state
return false; return false;
} }
} }

View file

@ -1,40 +1,6 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on January 26, 2004, 5:25 PM
*/
package org.xbib.graphics.svg; package org.xbib.graphics.svg;
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;
@ -44,11 +10,8 @@ import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.io.IOException; import java.io.IOException;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class Polygon extends ShapeElement { public class Polygon extends ShapeElement {
public static final String TAG_NAME = "polygon"; public static final String TAG_NAME = "polygon";
int fillRule = GeneralPath.WIND_NON_ZERO; int fillRule = GeneralPath.WIND_NON_ZERO;
@ -94,7 +57,7 @@ public class Polygon extends ShapeElement {
} }
@Override @Override
protected void doRender(Graphics2D g) throws SVGException, IOException { public void doRender(Graphics2D g) throws SVGException, IOException {
beginLayer(g); beginLayer(g);
renderShape(g, path); renderShape(g, path);
finishLayer(g); finishLayer(g);

View file

@ -1,5 +1,6 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg;
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;
@ -49,7 +50,7 @@ public class Polyline extends ShapeElement {
} }
@Override @Override
protected void doRender(Graphics2D g) throws SVGException, IOException { public void doRender(Graphics2D g) throws SVGException, IOException {
beginLayer(g); beginLayer(g);
renderShape(g, path); renderShape(g, path);
finishLayer(g); finishLayer(g);

View file

@ -1,5 +1,6 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg;
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;
@ -69,7 +70,7 @@ public class Rect extends ShapeElement {
} }
@Override @Override
protected void doRender(Graphics2D g) throws SVGException, IOException { public void doRender(Graphics2D g) throws SVGException, IOException {
beginLayer(g); beginLayer(g);
renderShape(g, rect); renderShape(g, rect);
finishLayer(g); finishLayer(g);

View file

@ -1,57 +0,0 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on April 2, 2005, 1:54 AM
*/
package org.xbib.graphics.svg;
/**
* A convienience singleton for allowing all classes to access a common SVG universe.
*
* @author kitfox
*/
public class SVGCache {
private static final SVGUniverse svgUniverse = new SVGUniverse();
/**
* Creates a new instance of SVGUniverseSingleton
*/
private SVGCache() {
}
public static SVGUniverse getSVGUniverse() {
return svgUniverse;
}
}

View file

@ -1,12 +0,0 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.xbib.graphics.svg;
/**
* @author kitfox
*/
public interface SVGConst {
String SVG_LOGGER = "svgSalamandeLogger";
}

View file

@ -1,5 +1,7 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg;
import org.xbib.graphics.svg.element.SVGElement;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
@ -16,6 +18,8 @@ import java.util.logging.Logger;
public class SVGDiagram { public class SVGDiagram {
private static final Logger logger = Logger.getLogger(SVGDiagram.class.getName());
final Map<String, SVGElement> idMap = new HashMap<>(); final Map<String, SVGElement> idMap = new HashMap<>();
SVGRoot root; SVGRoot root;
@ -132,7 +136,7 @@ public class SVGDiagram {
try { try {
root.build(); root.build();
} catch (SVGException | IOException ex) { } catch (SVGException | IOException ex) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, "Could not build document", ex); logger.log(Level.SEVERE, "Could not build document", ex);
} }
} }
} }

View file

@ -1,65 +1,12 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on May 12, 2005, 11:32 PM
*/
package org.xbib.graphics.svg; package org.xbib.graphics.svg;
/** import org.xbib.graphics.svg.element.SVGElement;
* @author kitfox
*/ @SuppressWarnings("serial")
public class SVGElementException extends SVGException { public class SVGElementException extends SVGException {
public static final long serialVersionUID = 0;
private final SVGElement element; private final SVGElement element;
/**
* Creates a new instance of <code>SVGException</code> without detail message.
*
* @param element
*/
public SVGElementException(SVGElement element) {
this(element, null, null);
}
/**
* Constructs an instance of <code>SVGException</code> with the specified detail message.
*
* @param element
* @param msg the detail message.
*/
public SVGElementException(SVGElement element, String msg) { public SVGElementException(SVGElement element, String msg) {
this(element, msg, null); this(element, msg, null);
} }
@ -69,10 +16,6 @@ public class SVGElementException extends SVGException {
this.element = element; this.element = element;
} }
public SVGElementException(SVGElement element, Throwable cause) {
this(element, null, cause);
}
public SVGElement getElement() { public SVGElement getElement() {
return element; return element;
} }

View file

@ -1,10 +1,6 @@
package org.xbib.graphics.svg.app.beans; package org.xbib.graphics.svg;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import org.xbib.graphics.svg.SVGCache;
import org.xbib.graphics.svg.SVGDiagram;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.SVGUniverse;
import java.awt.Component; import java.awt.Component;
import java.awt.Dimension; import java.awt.Dimension;
@ -28,7 +24,7 @@ public class SVGIcon extends ImageIcon {
private final PropertyChangeSupport changes = new PropertyChangeSupport(this); private final PropertyChangeSupport changes = new PropertyChangeSupport(this);
SVGUniverse svgUniverse = SVGCache.getSVGUniverse(); SVGUniverse svgUniverse = new SVGUniverse();
public static final int INTERP_NEAREST_NEIGHBOR = 0; public static final int INTERP_NEAREST_NEIGHBOR = 0;

View file

@ -1,5 +1,23 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg;
import org.xbib.graphics.svg.element.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.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.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.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;
@ -15,6 +33,8 @@ import java.util.logging.Logger;
public class SVGLoader extends DefaultHandler { public class SVGLoader extends DefaultHandler {
private static final Logger logger = Logger.getLogger(SVGLoader.class.getName());
final Map<String, Class<?>> nodeClasses = new HashMap<>(); final Map<String, Class<?>> nodeClasses = new HashMap<>();
final LinkedList<SVGElement> buildStack = new LinkedList<>(); final LinkedList<SVGElement> buildStack = new LinkedList<>();
@ -38,7 +58,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(FeGaussianBlur.TAG_NAME, FeGaussianBlur.class); nodeClasses.put(GaussianBlur.TAG_NAME, 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);
@ -98,8 +118,7 @@ public class SVGLoader extends DefaultHandler {
svgEle.loaderStartElement(helper, attrs, parent); svgEle.loaderStartElement(helper, attrs, parent);
buildStack.addLast(svgEle); buildStack.addLast(svgEle);
} catch (Exception e) { } catch (Exception e) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, logger.log(Level.SEVERE, "Could not load", e);
"Could not load", e);
throw new SAXException(e); throw new SAXException(e);
} }
@ -130,7 +149,7 @@ public class SVGLoader extends DefaultHandler {
diagram.setRoot((SVGRoot) svgEle); diagram.setRoot((SVGRoot) svgEle);
} }
} catch (Exception e) { } catch (Exception e) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, "Could not parse", e); logger.log(Level.WARNING, "Could not parse", e);
throw new SAXException(e); throw new SAXException(e);
} }
} }

View file

@ -1,59 +1,11 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on May 12, 2005, 11:32 PM
*/
package org.xbib.graphics.svg; package org.xbib.graphics.svg;
/** @SuppressWarnings("serial")
* @author kitfox public class SVGParseException extends Exception {
*/
public class SVGParseException extends java.lang.Exception {
public static final long serialVersionUID = 0;
/**
* Creates a new instance of <code>SVGException</code> without detail message.
*/
public SVGParseException() { public SVGParseException() {
} }
/**
* Constructs an instance of <code>SVGException</code> with the specified detail message.
*
* @param msg the detail message.
*/
public SVGParseException(String msg) { public SVGParseException(String msg) {
super(msg); super(msg);
} }

View file

@ -1,5 +1,9 @@
package org.xbib.graphics.svg; 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.SVGElement;
import org.xbib.graphics.svg.element.Style;
import org.xbib.graphics.svg.xml.NumberWithUnits; import org.xbib.graphics.svg.xml.NumberWithUnits;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import org.xbib.graphics.svg.xml.StyleSheet; import org.xbib.graphics.svg.xml.StyleSheet;
@ -194,7 +198,7 @@ public class SVGRoot extends Group {
} }
@Override @Override
protected void doRender(Graphics2D g) throws SVGException, IOException { public void doRender(Graphics2D g) throws SVGException, IOException {
prepareViewport(); prepareViewport();
Rectangle targetViewport; Rectangle targetViewport;
Rectangle deviceViewport = diagram.getDeviceViewport(); Rectangle deviceViewport = diagram.getDeviceViewport();

View file

@ -4,7 +4,9 @@ import javax.imageio.ImageIO;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.SAXParserFactory;
import org.xbib.graphics.svg.app.beans.SVGIcon;
import org.xbib.graphics.svg.element.Font;
import org.xbib.graphics.svg.element.SVGElement;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException; import org.xml.sax.SAXParseException;
@ -26,19 +28,22 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Base64; import java.util.Base64;
import java.util.HashMap; import java.util.HashMap;
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.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
public class SVGUniverse { public class SVGUniverse {
final HashMap<URI, SVGDiagram> loadedDocs = new HashMap<URI, SVGDiagram>(); private static final Logger logger = Logger.getLogger(SVGUniverse.class.getName());
final HashMap<String, Font> loadedFonts = new HashMap<String, Font>(); final Map<URI, SVGDiagram> loadedDocs = new HashMap<>();
final HashMap<URL, SoftReference<BufferedImage>> loadedImages = new HashMap<URL, SoftReference<BufferedImage>>(); final Map<String, Font> loadedFonts = new HashMap<>();
public static final String INPUTSTREAM_SCHEME = "svgSalamander"; 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;
@ -70,7 +75,7 @@ public class SVGUniverse {
} }
} }
void registerFont(Font font) { public void registerFont(Font font) {
loadedFonts.put(font.getFontFace().getFontFamily(), font); loadedFonts.put(font.getFontFace().getFontFamily(), font);
} }
@ -110,8 +115,7 @@ public class SVGUniverse {
loadedImages.put(url, ref); loadedImages.put(url, ref);
return url; return url;
} catch (IOException ex) { } catch (IOException ex) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, logger.log(Level.SEVERE, "Could not decode inline image", ex);
"Could not decode inline image", ex);
} }
} }
return null; return null;
@ -121,8 +125,7 @@ public class SVGUniverse {
registerImage(url); registerImage(url);
return url; return url;
} catch (MalformedURLException ex) { } catch (MalformedURLException ex) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, logger.log(Level.SEVERE, "Bad url", ex);
"Bad url", ex);
} }
return null; return null;
} }
@ -149,8 +152,7 @@ public class SVGUniverse {
} }
loadedImages.put(imageURL, ref); loadedImages.put(imageURL, ref);
} catch (Exception e) { } catch (Exception e) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, logger.log(Level.SEVERE, "Could not load image: " + imageURL, e);
"Could not load image: " + imageURL, e);
} }
} }
@ -177,8 +179,7 @@ public class SVGUniverse {
URI uri = new URI(path.toString()); URI uri = new URI(path.toString());
return getElement(uri, true); return getElement(uri, true);
} catch (Exception e) { } catch (Exception e) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, logger.log(Level.SEVERE, "Could not parse url " + path, e);
"Could not parse url " + path, e);
} }
return null; return null;
} }
@ -216,8 +217,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 (Exception e) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, logger.log(Level.SEVERE, "Could not parse path " + path, e);
"Could not parse path " + path, e);
return null; return null;
} }
} }
@ -245,8 +245,7 @@ public class SVGUniverse {
dia = loadedDocs.get(xmlBase); dia = loadedDocs.get(xmlBase);
return dia; return dia;
} catch (Exception e) { } catch (Exception e) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, logger.log(Level.SEVERE, "Could not parse", e);
"Could not parse", e);
} }
return null; return null;
} }
@ -259,32 +258,10 @@ public class SVGUniverse {
if ((b1 << 8 | b0) == GZIPInputStream.GZIP_MAGIC) { if ((b1 << 8 | b0) == GZIPInputStream.GZIP_MAGIC) {
return new GZIPInputStream(bin); return new GZIPInputStream(bin);
} else { } else {
//Plain text
return bin; return bin;
} }
} }
public URI loadSVG(URL docRoot) {
return loadSVG(docRoot, false);
}
public URI loadSVG(URL docRoot, boolean forceLoad) {
try {
URI uri = new URI(docRoot.toString());
if (loadedDocs.containsKey(uri) && !forceLoad) {
return uri;
}
InputStream is = docRoot.openStream();
URI result = loadSVG(uri, new InputSource(createDocumentInputStream(is)));
is.close();
return result;
} catch (URISyntaxException | IOException ex) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING,
"Could not parse", ex);
}
return null;
}
public URI loadSVG(InputStream is, String name) throws IOException { public URI loadSVG(InputStream is, String name) throws IOException {
return loadSVG(is, name, false); return loadSVG(is, name, false);
} }
@ -301,6 +278,28 @@ public class SVGUniverse {
return loadSVG(uri, new InputSource(createDocumentInputStream(is))); return loadSVG(uri, new InputSource(createDocumentInputStream(is)));
} }
public URI loadSVG(URL docRoot) {
return loadSVG(docRoot, false);
}
public URI loadSVG(URL docRoot, boolean forceLoad) {
try {
URI uri = new URI(docRoot.toString());
if (loadedDocs.containsKey(uri) && !forceLoad) {
return uri;
}
InputStream is = docRoot.openStream();
URI result = loadSVG(uri, new InputSource(createDocumentInputStream(is)));
is.close();
return result;
} catch (URISyntaxException | IOException ex) {
logger.log(Level.SEVERE, "Could not parse", ex);
}
return null;
}
public URI loadSVG(Reader reader, String name) { public URI loadSVG(Reader reader, String name) {
return loadSVG(reader, name, false); return loadSVG(reader, name, false);
} }
@ -326,8 +325,7 @@ public class SVGUniverse {
try { try {
return new URI(INPUTSTREAM_SCHEME, name, null); return new URI(INPUTSTREAM_SCHEME, name, null);
} catch (Exception e) { } catch (Exception e) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, logger.log(Level.SEVERE, "Could not parse", e);
"Could not parse", e);
return null; return null;
} }
} }
@ -357,13 +355,11 @@ public class SVGUniverse {
handler.getLoadedDiagram().updateTime(curTime); handler.getLoadedDiagram().updateTime(curTime);
return xmlBase; return xmlBase;
} catch (SAXParseException sex) { } catch (SAXParseException sex) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, logger.log(Level.SEVERE, "Error processing " + xmlBase, sex);
"Error processing " + xmlBase, sex);
loadedDocs.remove(xmlBase); loadedDocs.remove(xmlBase);
return null; return null;
} catch (Throwable e) { } catch (Throwable e) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, logger.log(Level.SEVERE, "Could not load SVG " + xmlBase, e);
"Could not load SVG " + xmlBase, e);
} }
return null; return null;
} }

View file

@ -1,59 +1,21 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on January 26, 2004, 1:56 AM
*/
package org.xbib.graphics.svg; package org.xbib.graphics.svg;
import org.xbib.graphics.svg.element.SVGElement;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Color; import java.awt.Color;
import java.io.IOException; import java.io.IOException;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class Stop extends SVGElement { public class Stop extends SVGElement {
public static final String TAG_NAME = "stop"; public static final String TAG_NAME = "stop";
float offset = 0f;
float opacity = 1f;
Color color = Color.black;
/** public float offset = 0f;
* Creates a new instance of Stop
*/ public float opacity = 1f;
public Color color = Color.black;
public Stop() { public Stop() {
} }
@ -65,9 +27,7 @@ public class Stop extends SVGElement {
@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("offset"))) { if (getPres(sty.setName("offset"))) {
offset = sty.getFloatValue(); offset = sty.getFloatValue();
String units = sty.getUnits(); String units = sty.getUnits();
@ -81,31 +41,18 @@ public class Stop extends SVGElement {
offset = 0; offset = 0;
} }
} }
if (getStyle(sty.setName("stop-color"))) { if (getStyle(sty.setName("stop-color"))) {
color = sty.getColorValue(); color = sty.getColorValue();
} }
if (getStyle(sty.setName("stop-opacity"))) { if (getStyle(sty.setName("stop-opacity"))) {
opacity = sty.getRatioValue(); opacity = sty.getRatioValue();
} }
} }
/**
* 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 { public boolean updateTime(double curTime) throws SVGException {
// if (trackManager.getNumTracks() == 0) return false;
//Get current values for parameters
StyleAttribute sty = new StyleAttribute(); StyleAttribute sty = new StyleAttribute();
boolean shapeChange = false; boolean shapeChange = false;
if (getPres(sty.setName("offset"))) { if (getPres(sty.setName("offset"))) {
float newVal = sty.getFloatValue(); float newVal = sty.getFloatValue();
if (newVal != offset) { if (newVal != offset) {
@ -113,7 +60,6 @@ public class Stop extends SVGElement {
shapeChange = true; shapeChange = true;
} }
} }
if (getStyle(sty.setName("stop-color"))) { if (getStyle(sty.setName("stop-color"))) {
Color newVal = sty.getColorValue(); Color newVal = sty.getColorValue();
if (newVal != color) { if (newVal != color) {
@ -121,7 +67,6 @@ public class Stop extends SVGElement {
shapeChange = true; shapeChange = true;
} }
} }
if (getStyle(sty.setName("stop-opacity"))) { if (getStyle(sty.setName("stop-opacity"))) {
float newVal = sty.getFloatValue(); float newVal = sty.getFloatValue();
if (newVal != opacity) { if (newVal != opacity) {
@ -129,7 +74,6 @@ public class Stop extends SVGElement {
shapeChange = true; shapeChange = true;
} }
} }
return shapeChange; return shapeChange;
} }
} }

View file

@ -1,5 +1,6 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg;
import org.xbib.graphics.svg.element.Group;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Graphics2D; import java.awt.Graphics2D;
@ -49,7 +50,7 @@ public class Symbol extends Group {
} }
@Override @Override
protected void doRender(Graphics2D g) throws SVGException, IOException { public void doRender(Graphics2D g) throws SVGException, IOException {
AffineTransform oldXform = g.getTransform(); AffineTransform oldXform = g.getTransform();
g.transform(viewXform); g.transform(viewXform);
super.doRender(g); super.doRender(g);

View file

@ -1,54 +1,13 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on September 19, 2004, 1:56 AM
*/
package org.xbib.graphics.svg; package org.xbib.graphics.svg;
/** import org.xbib.graphics.svg.element.SVGElement;
* Holds title textual information within tree
*
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class Title extends SVGElement { public class Title extends SVGElement {
public static final String TAG_NAME = "title"; public static final String TAG_NAME = "title";
StringBuffer text = new StringBuffer(); StringBuilder text = new StringBuilder();
/**
* Creates a new instance of Stop
*/
public Title() { public Title() {
} }
@ -57,9 +16,6 @@ public class Title extends SVGElement {
return TAG_NAME; return TAG_NAME;
} }
/**
* Called during load process to add text scanned within a tag
*/
@Override @Override
public void loaderAddText(SVGLoaderHelper helper, String text) { public void loaderAddText(SVGLoaderHelper helper, String text) {
this.text.append(text); this.text.append(text);
@ -69,16 +25,8 @@ public class Title extends SVGElement {
return text.toString(); return text.toString();
} }
/**
* 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 { public boolean updateTime(double curTime) throws SVGException {
//Title does not change
return false; return false;
} }
} }

View file

@ -1,133 +0,0 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on January 26, 2004, 9:00 AM
*/
package org.xbib.graphics.svg;
import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
/**
* Maintains bounding box for this element
*
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
abstract public class TransformableElement extends SVGElement {
AffineTransform xform = null;
/**
* Creates a new instance of BoundedElement
*/
public TransformableElement() {
}
public TransformableElement(String id, SVGElement parent) {
super(id, parent);
}
/**
* Fetches a copy of the cached AffineTransform. Note that this value will
* only be valid after the node has been updated.
*
* @return
*/
public AffineTransform getXForm() {
return xform == null ? null : new AffineTransform(xform);
}
/*
public void loaderStartElement(SVGLoaderHelper helper, Attributes attrs, SVGElement parent)
{
//Load style string
super.loaderStartElement(helper, attrs, parent);
String transform = attrs.getValue("transform");
if (transform != null)
{
xform = parseTransform(transform);
}
}
*/
@Override
protected void build() throws SVGException, IOException {
super.build();
StyleAttribute sty = new StyleAttribute();
if (getPres(sty.setName("transform"))) {
xform = parseTransform(sty.getStringValue());
}
}
protected Shape shapeToParent(Shape shape) {
if (xform == null) {
return shape;
}
return xform.createTransformedShape(shape);
}
protected Rectangle2D boundsToParent(Rectangle2D rect) {
if (xform == null || rect == null) {
return rect;
}
return xform.createTransformedShape(rect).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 {
StyleAttribute sty = new StyleAttribute();
if (getPres(sty.setName("transform"))) {
AffineTransform newXform = parseTransform(sty.getStringValue());
if (!newXform.equals(xform)) {
xform = newXform;
return true;
}
}
return false;
}
}

View file

@ -1,5 +1,9 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg;
import org.xbib.graphics.svg.element.Font;
import org.xbib.graphics.svg.element.SVGElement;
import org.xbib.graphics.svg.element.ShapeElement;
import org.xbib.graphics.svg.element.glyph.MissingGlyph;
import org.xbib.graphics.svg.util.FontUtil; import org.xbib.graphics.svg.util.FontUtil;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
@ -200,7 +204,7 @@ public class Tspan extends ShapeElement {
} }
@Override @Override
protected void doRender(Graphics2D g) throws SVGException, IOException { public void doRender(Graphics2D g) throws SVGException, IOException {
beginLayer(g); beginLayer(g);
for (TextSegment segment : segments) { for (TextSegment segment : segments) {
if (segment.textPath != null) { if (segment.textPath != null) {

View file

@ -1,5 +1,8 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg;
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;
@ -57,7 +60,7 @@ public class Use extends ShapeElement {
} }
@Override @Override
protected void doRender(Graphics2D g) throws SVGException, IOException { public void doRender(Graphics2D g) throws SVGException, IOException {
beginLayer(g); beginLayer(g);
AffineTransform oldXform = g.getTransform(); AffineTransform oldXform = g.getTransform();
g.transform(refXform); g.transform(refXform);

View file

@ -1,87 +0,0 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on April 1, 2004, 6:40 AM
*/
package org.xbib.graphics.svg.composite;
import org.xbib.graphics.svg.SVGConst;
import java.awt.Composite;
import java.awt.CompositeContext;
import java.awt.RenderingHints;
import java.awt.image.ColorModel;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class AdobeComposite implements Composite {
public static final int CT_NORMAL = 0;
public static final int CT_MULTIPLY = 1;
public static final int CT_LAST = 2;
final int compositeType;
final float extraAlpha;
/**
* Creates a new instance of AdobeComposite
*
* @param compositeType
* @param extraAlpha
*/
public AdobeComposite(int compositeType, float extraAlpha) {
this.compositeType = compositeType;
this.extraAlpha = extraAlpha;
if (compositeType < 0 || compositeType >= CT_LAST) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, "Invalid composite type");
}
if (extraAlpha < 0f || extraAlpha > 1f) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, "Invalid alpha");
}
}
public int getCompositeType() {
return compositeType;
}
public CompositeContext createContext(ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints) {
return new AdobeCompositeContext(compositeType, extraAlpha);
}
}

View file

@ -1,105 +0,0 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on April 1, 2004, 6:41 AM
*/
package org.xbib.graphics.svg.composite;
import java.awt.CompositeContext;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class AdobeCompositeContext implements CompositeContext {
final int compositeType;
final float extraAlpha;
float[] rgba_src = new float[4];
float[] rgba_dstIn = new float[4];
float[] rgba_dstOut = new float[4];
/**
* Creates a new instance of AdobeCompositeContext
*
* @param compositeType
* @param extraAlpha
*/
public AdobeCompositeContext(int compositeType, float extraAlpha) {
this.compositeType = compositeType;
this.extraAlpha = extraAlpha;
rgba_dstOut[3] = 1f;
}
public void compose(Raster src, Raster dstIn, WritableRaster dstOut) {
int width = src.getWidth();
int height = src.getHeight();
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
src.getPixel(i, j, rgba_src);
dstIn.getPixel(i, j, rgba_dstIn);
//Ignore transparent pixels
if (rgba_src[3] == 0) {
// dstOut.setPixel(i, j, rgba_dstIn);
continue;
}
float alpha = rgba_src[3];
switch (compositeType) {
default:
case AdobeComposite.CT_NORMAL:
rgba_dstOut[0] = rgba_src[0] * alpha + rgba_dstIn[0] * (1f - alpha);
rgba_dstOut[1] = rgba_src[1] * alpha + rgba_dstIn[1] * (1f - alpha);
rgba_dstOut[2] = rgba_src[2] * alpha + rgba_dstIn[2] * (1f - alpha);
break;
case AdobeComposite.CT_MULTIPLY:
rgba_dstOut[0] = rgba_src[0] * rgba_dstIn[0] * alpha + rgba_dstIn[0] * (1f - alpha);
rgba_dstOut[1] = rgba_src[1] * rgba_dstIn[1] * alpha + rgba_dstIn[1] * (1f - alpha);
rgba_dstOut[2] = rgba_src[2] * rgba_dstIn[2] * alpha + rgba_dstIn[2] * (1f - alpha);
break;
}
}
}
}
public void dispose() {
}
}

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.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Graphics2D; import java.awt.Graphics2D;
@ -11,14 +12,15 @@ import java.io.IOException;
public class Circle extends ShapeElement { public class Circle extends ShapeElement {
public static final String TAG_NAME = "circle"; public static final String TAG_NAME = "circle";
float cx = 0f; float cx = 0f;
float cy = 0f; float cy = 0f;
float r = 0f; float r = 0f;
Ellipse2D.Float circle = new Ellipse2D.Float(); Ellipse2D.Float circle = new Ellipse2D.Float();
/**
* Creates a new instance of Rect
*/
public Circle() { public Circle() {
} }
@ -30,26 +32,21 @@ public class Circle extends ShapeElement {
@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("cx"))) { if (getPres(sty.setName("cx"))) {
cx = sty.getFloatValueWithUnits(); cx = sty.getFloatValueWithUnits();
} }
if (getPres(sty.setName("cy"))) { if (getPres(sty.setName("cy"))) {
cy = sty.getFloatValueWithUnits(); cy = sty.getFloatValueWithUnits();
} }
if (getPres(sty.setName("r"))) { if (getPres(sty.setName("r"))) {
r = sty.getFloatValueWithUnits(); r = sty.getFloatValueWithUnits();
} }
circle.setFrame(cx - r, cy - r, r * 2f, r * 2f); circle.setFrame(cx - r, cy - r, r * 2f, r * 2f);
} }
@Override @Override
protected void doRender(Graphics2D g) throws SVGException, IOException { public void doRender(Graphics2D g) throws SVGException, IOException {
beginLayer(g); beginLayer(g);
renderShape(g, circle); renderShape(g, circle);
finishLayer(g); finishLayer(g);
@ -65,22 +62,11 @@ public class Circle extends ShapeElement {
return boundsToParent(includeStrokeInBounds(circle.getBounds2D())); return boundsToParent(includeStrokeInBounds(circle.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 (getPres(sty.setName("cx"))) { if (getPres(sty.setName("cx"))) {
float newVal = sty.getFloatValueWithUnits(); float newVal = sty.getFloatValueWithUnits();
if (newVal != cx) { if (newVal != cx) {
@ -88,7 +74,6 @@ public class Circle extends ShapeElement {
shapeChange = true; shapeChange = true;
} }
} }
if (getPres(sty.setName("cy"))) { if (getPres(sty.setName("cy"))) {
float newVal = sty.getFloatValueWithUnits(); float newVal = sty.getFloatValueWithUnits();
if (newVal != cy) { if (newVal != cy) {
@ -96,7 +81,6 @@ public class Circle extends ShapeElement {
shapeChange = true; shapeChange = true;
} }
} }
if (getPres(sty.setName("r"))) { if (getPres(sty.setName("r"))) {
float newVal = sty.getFloatValueWithUnits(); float newVal = sty.getFloatValueWithUnits();
if (newVal != r) { if (newVal != r) {
@ -104,13 +88,9 @@ public class Circle extends ShapeElement {
shapeChange = true; shapeChange = true;
} }
} }
if (shapeChange) { if (shapeChange) {
build(); build();
// circle.setFrame(cx - r, cy - r, r * 2f, r * 2f);
// return true;
} }
return changeState || shapeChange; return changeState || shapeChange;
} }
} }

View file

@ -0,0 +1,89 @@
package org.xbib.graphics.svg.element;
import org.xbib.graphics.svg.SVGException;
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 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() {
}
@Override
public String getTagName() {
return TAG_NAME;
}
@Override
protected void build() throws SVGException, IOException {
super.build();
StyleAttribute sty = new StyleAttribute();
clipPathUnits = (getPres(sty.setName("clipPathUnits"))
&& sty.getStringValue().equals("objectBoundingBox"))
? CP_OBJECT_BOUNDING_BOX
: CP_USER_SPACE_ON_USE;
}
public int getClipPathUnits() {
return clipPathUnits;
}
public Shape getClipPathShape() {
if (children.isEmpty()) {
return null;
}
if (children.size() == 1) {
return ((ShapeElement) children.get(0)).getShape();
}
Area clipArea = null;
for (SVGElement svgElement : children) {
ShapeElement se = (ShapeElement) svgElement;
if (clipArea == null) {
Shape shape = se.getShape();
if (shape != null) {
clipArea = new Area(se.getShape());
}
continue;
}
Shape shape = se.getShape();
if (shape != null) {
clipArea.intersect(new Area(shape));
}
}
return clipArea;
}
@Override
public boolean updateTime(double curTime) throws SVGException, IOException {
StyleAttribute sty = new StyleAttribute();
boolean shapeChange = false;
if (getPres(sty.setName("clipPathUnits"))) {
String newUnitsStrn = sty.getStringValue();
int newUnits = newUnitsStrn.equals("objectBoundingBox")
? CP_OBJECT_BOUNDING_BOX
: CP_USER_SPACE_ON_USE;
if (newUnits != clipPathUnits) {
clipPathUnits = newUnits;
shapeChange = true;
}
}
if (shapeChange) {
build();
}
for (SVGElement ele : children) {
ele.updateTime(curTime);
}
return shapeChange;
}
}

View file

@ -0,0 +1,38 @@
package org.xbib.graphics.svg.element;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.xml.StyleSheet;
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;
}
@Override
public boolean updateTime(double curTime) throws SVGException, IOException {
boolean stateChange = false;
for (SVGElement ele : children) {
stateChange = stateChange || ele.updateTime(curTime);
}
return super.updateTime(curTime) || stateChange;
}
public StyleSheet getStyleSheet() {
for (int i = 0; i < getNumChildren(); ++i) {
SVGElement ele = getChild(i);
if (ele instanceof Style) {
return ((Style) ele).getStyleSheet();
}
}
return null;
}
}

View file

@ -0,0 +1,29 @@
package org.xbib.graphics.svg.element;
import org.xbib.graphics.svg.SVGLoaderHelper;
public class Desc extends SVGElement {
public static final String TAG_NAME = "desc";
StringBuilder text = new StringBuilder();
@Override
public String getTagName() {
return TAG_NAME;
}
@Override
public void loaderAddText(SVGLoaderHelper helper, String text) {
this.text.append(text);
}
public String getText() {
return text.toString();
}
@Override
public boolean updateTime(double curTime) {
return false;
}
}

View file

@ -1,40 +1,6 @@
/* package org.xbib.graphics.svg.element;
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on January 26, 2004, 5:25 PM
*/
package org.xbib.graphics.svg;
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;
@ -43,22 +9,20 @@ import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.io.IOException; import java.io.IOException;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class Ellipse extends ShapeElement { public class Ellipse extends ShapeElement {
public static final String TAG_NAME = "ellipse"; public static final String TAG_NAME = "ellipse";
float cx = 0.0f; float cx = 0.0f;
float cy = 0.0f; float cy = 0.0f;
float rx = 0.0f; float rx = 0.0f;
float ry = 0.0f; float ry = 0.0f;
Ellipse2D.Float ellipse = new Ellipse2D.Float(); Ellipse2D.Float ellipse = new Ellipse2D.Float();
/**
* Creates a new instance of Rect
*/
public Ellipse() { public Ellipse() {
} }
@ -70,30 +34,24 @@ public class Ellipse extends ShapeElement {
@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("cx"))) { if (getPres(sty.setName("cx"))) {
cx = sty.getFloatValueWithUnits(); cx = sty.getFloatValueWithUnits();
} }
if (getPres(sty.setName("cy"))) { if (getPres(sty.setName("cy"))) {
cy = sty.getFloatValueWithUnits(); cy = sty.getFloatValueWithUnits();
} }
if (getPres(sty.setName("rx"))) { if (getPres(sty.setName("rx"))) {
rx = sty.getFloatValueWithUnits(); rx = sty.getFloatValueWithUnits();
} }
if (getPres(sty.setName("ry"))) { if (getPres(sty.setName("ry"))) {
ry = sty.getFloatValueWithUnits(); ry = sty.getFloatValueWithUnits();
} }
ellipse.setFrame(cx - rx, cy - ry, rx * 2f, ry * 2f); ellipse.setFrame(cx - rx, cy - ry, rx * 2f, ry * 2f);
} }
@Override @Override
protected void doRender(Graphics2D g) throws SVGException, IOException { public void doRender(Graphics2D g) throws SVGException, IOException {
beginLayer(g); beginLayer(g);
renderShape(g, ellipse); renderShape(g, ellipse);
finishLayer(g); finishLayer(g);
@ -109,22 +67,11 @@ public class Ellipse extends ShapeElement {
return boundsToParent(includeStrokeInBounds(ellipse.getBounds2D())); return boundsToParent(includeStrokeInBounds(ellipse.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 (getPres(sty.setName("cx"))) { if (getPres(sty.setName("cx"))) {
float newCx = sty.getFloatValueWithUnits(); float newCx = sty.getFloatValueWithUnits();
if (newCx != cx) { if (newCx != cx) {
@ -132,7 +79,6 @@ public class Ellipse extends ShapeElement {
shapeChange = true; shapeChange = true;
} }
} }
if (getPres(sty.setName("cy"))) { if (getPres(sty.setName("cy"))) {
float newCy = sty.getFloatValueWithUnits(); float newCy = sty.getFloatValueWithUnits();
if (newCy != cy) { if (newCy != cy) {
@ -140,7 +86,6 @@ public class Ellipse extends ShapeElement {
shapeChange = true; shapeChange = true;
} }
} }
if (getPres(sty.setName("rx"))) { if (getPres(sty.setName("rx"))) {
float newRx = sty.getFloatValueWithUnits(); float newRx = sty.getFloatValueWithUnits();
if (newRx != rx) { if (newRx != rx) {
@ -148,7 +93,6 @@ public class Ellipse extends ShapeElement {
shapeChange = true; shapeChange = true;
} }
} }
if (getPres(sty.setName("ry"))) { if (getPres(sty.setName("ry"))) {
float newRy = sty.getFloatValueWithUnits(); float newRy = sty.getFloatValueWithUnits();
if (newRy != ry) { if (newRy != ry) {
@ -156,13 +100,9 @@ public class Ellipse extends ShapeElement {
shapeChange = true; shapeChange = true;
} }
} }
if (shapeChange) { if (shapeChange) {
build(); build();
// ellipse.setFrame(cx - rx, cy - ry, rx * 2f, ry * 2f);
// return true;
} }
return changeState || shapeChange; return changeState || shapeChange;
} }
} }

View file

@ -0,0 +1,10 @@
package org.xbib.graphics.svg.element;
import java.awt.Paint;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
public abstract class FillElement extends SVGElement {
public abstract Paint getPaint(Rectangle2D bounds, AffineTransform xform);
}

View file

@ -1,33 +1,45 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.element;
import org.xbib.graphics.svg.element.filtereffects.FilterEffects;
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 org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.geom.Point2D;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
public class Filter extends SVGElement { public class Filter extends SVGElement {
public static final String TAG_NAME = "filter"; public static final String TAG_NAME = "filter";
public static final int FU_OBJECT_BOUNDING_BOX = 0;
public static final int FU_USER_SPACE_ON_USE = 1;
protected int filterUnits = FU_OBJECT_BOUNDING_BOX;
public static final int PU_OBJECT_BOUNDING_BOX = 0;
public static final int PU_USER_SPACE_ON_USE = 1;
protected int primitiveUnits = PU_OBJECT_BOUNDING_BOX;
float x = 0f;
float y = 0f;
float width = 1f;
float height = 1f;
Point2D filterRes = new Point2D.Double();
URL href = null;
final ArrayList<FilterEffects> filterEffects = new ArrayList<>();
/** public static final int FU_OBJECT_BOUNDING_BOX = 0;
* Creates a new instance of FillElement
*/ public static final int FU_USER_SPACE_ON_USE = 1;
public int filterUnits = FU_OBJECT_BOUNDING_BOX;
public static final int PU_OBJECT_BOUNDING_BOX = 0;
public static final int PU_USER_SPACE_ON_USE = 1;
protected int primitiveUnits = PU_OBJECT_BOUNDING_BOX;
float x = 0f;
float y = 0f;
float width = 1f;
float height = 1f;
URL href = null;
public final List<FilterEffects> filterEffects = new ArrayList<>();
public Filter() { public Filter() {
} }
@ -36,14 +48,9 @@ public class Filter extends SVGElement {
return TAG_NAME; return TAG_NAME;
} }
/**
* Called after the start element but before the end element to indicate
* each child tag that has been processed
*/
@Override @Override
public void loaderAddChild(SVGLoaderHelper helper, SVGElement child) throws SVGElementException { public void loaderAddChild(SVGLoaderHelper helper, SVGElement child) throws SVGElementException {
super.loaderAddChild(helper, child); super.loaderAddChild(helper, child);
if (child instanceof FilterEffects) { if (child instanceof FilterEffects) {
filterEffects.add((FilterEffects) child); filterEffects.add((FilterEffects) child);
} }
@ -52,10 +59,8 @@ public class Filter extends SVGElement {
@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();
String strn; String strn;
if (getPres(sty.setName("filterUnits"))) { if (getPres(sty.setName("filterUnits"))) {
strn = sty.getStringValue().toLowerCase(); strn = sty.getStringValue().toLowerCase();
if (strn.equals("userspaceonuse")) { if (strn.equals("userspaceonuse")) {
@ -64,7 +69,6 @@ public class Filter extends SVGElement {
filterUnits = FU_OBJECT_BOUNDING_BOX; filterUnits = FU_OBJECT_BOUNDING_BOX;
} }
} }
if (getPres(sty.setName("primitiveUnits"))) { if (getPres(sty.setName("primitiveUnits"))) {
strn = sty.getStringValue().toLowerCase(); strn = sty.getStringValue().toLowerCase();
if (strn.equals("userspaceonuse")) { if (strn.equals("userspaceonuse")) {
@ -73,23 +77,18 @@ public class Filter extends SVGElement {
primitiveUnits = PU_OBJECT_BOUNDING_BOX; primitiveUnits = PU_OBJECT_BOUNDING_BOX;
} }
} }
if (getPres(sty.setName("x"))) { if (getPres(sty.setName("x"))) {
x = sty.getFloatValueWithUnits(); x = sty.getFloatValueWithUnits();
} }
if (getPres(sty.setName("y"))) { if (getPres(sty.setName("y"))) {
y = sty.getFloatValueWithUnits(); y = sty.getFloatValueWithUnits();
} }
if (getPres(sty.setName("width"))) { if (getPres(sty.setName("width"))) {
width = sty.getFloatValueWithUnits(); width = sty.getFloatValueWithUnits();
} }
if (getPres(sty.setName("height"))) { if (getPres(sty.setName("height"))) {
height = sty.getFloatValueWithUnits(); height = sty.getFloatValueWithUnits();
} }
try { try {
if (getPres(sty.setName("xlink:href"))) { if (getPres(sty.setName("xlink:href"))) {
URI src = sty.getURIValue(getXMLBase()); URI src = sty.getURIValue(getXMLBase());
@ -119,12 +118,8 @@ public class Filter extends SVGElement {
@Override @Override
public boolean updateTime(double curTime) throws SVGException { public boolean updateTime(double curTime) throws SVGException {
// if (trackManager.getNumTracks() == 0) return false;
//Get current values for parameters
StyleAttribute sty = new StyleAttribute(); StyleAttribute sty = new StyleAttribute();
boolean stateChange = false; boolean stateChange = false;
if (getPres(sty.setName("x"))) { if (getPres(sty.setName("x"))) {
float newVal = sty.getFloatValueWithUnits(); float newVal = sty.getFloatValueWithUnits();
if (newVal != x) { if (newVal != x) {
@ -132,7 +127,6 @@ public class Filter extends SVGElement {
stateChange = true; stateChange = true;
} }
} }
if (getPres(sty.setName("y"))) { if (getPres(sty.setName("y"))) {
float newVal = sty.getFloatValueWithUnits(); float newVal = sty.getFloatValueWithUnits();
if (newVal != y) { if (newVal != y) {
@ -140,7 +134,6 @@ public class Filter extends SVGElement {
stateChange = true; stateChange = true;
} }
} }
if (getPres(sty.setName("width"))) { if (getPres(sty.setName("width"))) {
float newVal = sty.getFloatValueWithUnits(); float newVal = sty.getFloatValueWithUnits();
if (newVal != width) { if (newVal != width) {
@ -148,7 +141,6 @@ public class Filter extends SVGElement {
stateChange = true; stateChange = true;
} }
} }
if (getPres(sty.setName("height"))) { if (getPres(sty.setName("height"))) {
float newVal = sty.getFloatValueWithUnits(); float newVal = sty.getFloatValueWithUnits();
if (newVal != height) { if (newVal != height) {
@ -156,7 +148,6 @@ public class Filter extends SVGElement {
stateChange = true; stateChange = true;
} }
} }
try { try {
if (getPres(sty.setName("xlink:href"))) { if (getPres(sty.setName("xlink:href"))) {
URI src = sty.getURIValue(getXMLBase()); URI src = sty.getURIValue(getXMLBase());
@ -170,7 +161,6 @@ public class Filter extends SVGElement {
} catch (Exception e) { } catch (Exception e) {
throw new SVGException(e); throw new SVGException(e);
} }
if (getPres(sty.setName("filterUnits"))) { if (getPres(sty.setName("filterUnits"))) {
int newVal; int newVal;
String strn = sty.getStringValue().toLowerCase(); String strn = sty.getStringValue().toLowerCase();
@ -184,7 +174,6 @@ public class Filter extends SVGElement {
stateChange = true; stateChange = true;
} }
} }
if (getPres(sty.setName("primitiveUnits"))) { if (getPres(sty.setName("primitiveUnits"))) {
int newVal; int newVal;
String strn = sty.getStringValue().toLowerCase(); String strn = sty.getStringValue().toLowerCase();
@ -198,8 +187,6 @@ public class Filter extends SVGElement {
stateChange = true; stateChange = true;
} }
} }
return stateChange; return stateChange;
} }
} }

View file

@ -1,5 +1,12 @@
package org.xbib.graphics.svg; 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;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.SVGLoaderHelper;
import org.xbib.graphics.svg.SVGParseException;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.io.IOException; import java.io.IOException;

View file

@ -1,5 +1,8 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.element;
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 org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Graphics2D; import java.awt.Graphics2D;
@ -18,6 +21,7 @@ public class Group extends ShapeElement {
public static final String TAG_NAME = "group"; public static final String TAG_NAME = "group";
Rectangle2D boundingBox; Rectangle2D boundingBox;
Shape cachedShape; Shape cachedShape;
public Group() { public Group() {
@ -43,7 +47,7 @@ public class Group extends ShapeElement {
} }
@Override @Override
protected void doPick(Point2D point, boolean boundingBox, List<List<SVGElement>> retVec) throws SVGException, IOException { public void doPick(Point2D point, boolean boundingBox, List<List<SVGElement>> retVec) throws SVGException, IOException {
Point2D xPoint = new Point2D.Double(point.getX(), point.getY()); Point2D xPoint = new Point2D.Double(point.getX(), point.getY());
if (xform != null) { if (xform != null) {
try { try {
@ -61,7 +65,7 @@ public class Group extends ShapeElement {
} }
@Override @Override
protected void doPick(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List<List<SVGElement>> retVec) throws SVGException, IOException { public void doPick(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List<List<SVGElement>> retVec) throws SVGException, IOException {
if (xform != null) { if (xform != null) {
ltw = new AffineTransform(ltw); ltw = new AffineTransform(ltw);
ltw.concatenate(xform); ltw.concatenate(xform);
@ -75,7 +79,7 @@ public class Group extends ShapeElement {
} }
@Override @Override
protected void doRender(Graphics2D g) throws SVGException, IOException { public void doRender(Graphics2D g) throws SVGException, IOException {
StyleAttribute styleAttrib = new StyleAttribute(); StyleAttribute styleAttrib = new StyleAttribute();
if (getStyle(styleAttrib.setName("display"))) { if (getStyle(styleAttrib.setName("display"))) {
if (styleAttrib.getStringValue().equals("none")) { if (styleAttrib.getStringValue().equals("none")) {

View file

@ -1,40 +1,7 @@
/* package org.xbib.graphics.svg.element;
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on January 26, 2004, 5:25 PM
*/
package org.xbib.graphics.svg;
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;
@ -43,22 +10,20 @@ import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.io.IOException; import java.io.IOException;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class Line extends ShapeElement { public class Line extends ShapeElement {
public static final String TAG_NAME = "line"; public static final String TAG_NAME = "line";
float x1 = 0f; float x1 = 0f;
float y1 = 0f; float y1 = 0f;
float x2 = 0f; float x2 = 0f;
float y2 = 0f; float y2 = 0f;
Line2D.Float line; Line2D.Float line;
/**
* Creates a new instance of Rect
*/
public Line() { public Line() {
} }
@ -70,30 +35,24 @@ public class Line extends ShapeElement {
@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("x1"))) { if (getPres(sty.setName("x1"))) {
x1 = sty.getFloatValueWithUnits(); x1 = sty.getFloatValueWithUnits();
} }
if (getPres(sty.setName("y1"))) { if (getPres(sty.setName("y1"))) {
y1 = sty.getFloatValueWithUnits(); y1 = sty.getFloatValueWithUnits();
} }
if (getPres(sty.setName("x2"))) { if (getPres(sty.setName("x2"))) {
x2 = sty.getFloatValueWithUnits(); x2 = sty.getFloatValueWithUnits();
} }
if (getPres(sty.setName("y2"))) { if (getPres(sty.setName("y2"))) {
y2 = sty.getFloatValueWithUnits(); y2 = sty.getFloatValueWithUnits();
} }
line = new Line2D.Float(x1, y1, x2, y2); line = new Line2D.Float(x1, y1, x2, y2);
} }
@Override @Override
protected void doRender(Graphics2D g) throws SVGException, IOException { public void doRender(Graphics2D g) throws SVGException, IOException {
beginLayer(g); beginLayer(g);
renderShape(g, line); renderShape(g, line);
finishLayer(g); finishLayer(g);
@ -109,22 +68,11 @@ public class Line extends ShapeElement {
return boundsToParent(includeStrokeInBounds(line.getBounds2D())); return boundsToParent(includeStrokeInBounds(line.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 (getPres(sty.setName("x1"))) { if (getPres(sty.setName("x1"))) {
float newVal = sty.getFloatValueWithUnits(); float newVal = sty.getFloatValueWithUnits();
if (newVal != x1) { if (newVal != x1) {
@ -132,7 +80,6 @@ public class Line extends ShapeElement {
shapeChange = true; shapeChange = true;
} }
} }
if (getPres(sty.setName("y1"))) { if (getPres(sty.setName("y1"))) {
float newVal = sty.getFloatValueWithUnits(); float newVal = sty.getFloatValueWithUnits();
if (newVal != y1) { if (newVal != y1) {
@ -140,7 +87,6 @@ public class Line extends ShapeElement {
shapeChange = true; shapeChange = true;
} }
} }
if (getPres(sty.setName("x2"))) { if (getPres(sty.setName("x2"))) {
float newVal = sty.getFloatValueWithUnits(); float newVal = sty.getFloatValueWithUnits();
if (newVal != x2) { if (newVal != x2) {
@ -148,7 +94,6 @@ public class Line extends ShapeElement {
shapeChange = true; shapeChange = true;
} }
} }
if (getPres(sty.setName("y2"))) { if (getPres(sty.setName("y2"))) {
float newVal = sty.getFloatValueWithUnits(); float newVal = sty.getFloatValueWithUnits();
if (newVal != y2) { if (newVal != y2) {
@ -156,11 +101,9 @@ public class Line extends ShapeElement {
shapeChange = true; shapeChange = true;
} }
} }
if (shapeChange) { if (shapeChange) {
build(); build();
} }
return changeState || shapeChange; return changeState || shapeChange;
} }
} }

View file

@ -1,37 +1,10 @@
/* package org.xbib.graphics.svg.element;
* SVG Salamander
* Copyright (c) 2004, Mark McKay import org.xbib.graphics.svg.SVGException;
* All rights reserved. import org.xbib.graphics.svg.element.Group;
* import org.xbib.graphics.svg.element.RenderableElement;
* Redistribution and use in source and binary forms, with or import org.xbib.graphics.svg.element.SVGElement;
* without modification, are permitted provided that the following import org.xbib.graphics.svg.util.PaintUtil;
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*/
package org.xbib.graphics.svg;
import java.awt.Color; import java.awt.Color;
import java.awt.Composite; import java.awt.Composite;
@ -50,12 +23,8 @@ import java.awt.image.WritableRaster;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
/**
* Implements the mask element.
*
* @author Jannis Weis
*/
public class Mask extends Group { public class Mask extends Group {
public static final String TAG_NAME = "mask"; public static final String TAG_NAME = "mask";
@Override @Override
@ -72,11 +41,11 @@ public class Mask extends Group {
} }
@Override @Override
void pick(Point2D point, boolean boundingBox, List<List<SVGElement>> retVec) { public void pick(Point2D point, boolean boundingBox, List<List<SVGElement>> retVec) {
} }
@Override @Override
void pick(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List<List<SVGElement>> retVec) { public void pick(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List<List<SVGElement>> retVec) {
} }
public void pickElement(Point2D point, boolean boundingBox, public void pickElement(Point2D point, boolean boundingBox,
@ -85,8 +54,7 @@ public class Mask extends Group {
element.doPick(point, true, retVec); element.doPick(point, true, retVec);
} else { } else {
Rectangle pickPoint = new Rectangle((int) point.getX(), (int) point.getY(), 1, 1); Rectangle pickPoint = new Rectangle((int) point.getX(), (int) point.getY(), 1, 1);
BufferedImage img = BufferPainter.paintToBuffer(null, new AffineTransform(), pickPoint, this, Color.BLACK); BufferedImage img = PaintUtil.paintToBuffer(null, new AffineTransform(), pickPoint, this, Color.BLACK);
// Only try picking the element if the picked point is visible.
if (luminanceToAlpha(img.getRGB(0, 0)) > 0) { if (luminanceToAlpha(img.getRGB(0, 0)) > 0) {
element.doPick(point, false, retVec); element.doPick(point, false, retVec);
} }
@ -95,22 +63,22 @@ public class Mask extends Group {
public void pickElement(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, public void pickElement(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox,
List<List<SVGElement>> retVec, RenderableElement element) throws SVGException, IOException { List<List<SVGElement>> retVec, RenderableElement element) throws SVGException, IOException {
// If at any point the considered picking area becomes empty we break out early. if (pickArea.isEmpty()) {
if (pickArea.isEmpty()) return; return;
}
if (boundingBox) { if (boundingBox) {
element.doPick(pickArea, ltw, true, retVec); element.doPick(pickArea, ltw, true, retVec);
} else { } else {
// Clip with the element bounds to avoid creating a larger buffer than needed.
Area transformedBounds = new Area(ltw.createTransformedShape(element.getBoundingBox())); Area transformedBounds = new Area(ltw.createTransformedShape(element.getBoundingBox()));
transformedBounds.intersect(new Area(pickArea)); transformedBounds.intersect(new Area(pickArea));
if (transformedBounds.isEmpty()) return; if (transformedBounds.isEmpty()) {
return;
}
Rectangle pickRect = transformedBounds.getBounds(); Rectangle pickRect = transformedBounds.getBounds();
if (pickRect.isEmpty()) return; if (pickRect.isEmpty()) {
return;
BufferedImage maskArea = BufferPainter.paintToBuffer(null, ltw, pickRect, this, Color.BLACK); }
BufferedImage maskArea = PaintUtil.paintToBuffer(null, ltw, pickRect, this, Color.BLACK);
// Pick if any pixel in the pick area is visible.
if (hasVisiblePixel(maskArea)) { if (hasVisiblePixel(maskArea)) {
element.doPick(pickArea, ltw, false, retVec); element.doPick(pickArea, ltw, false, retVec);
} }
@ -142,7 +110,6 @@ public class Mask extends Group {
} }
private static double luminanceToAlpha(int r, int g, int b) { private static double luminanceToAlpha(int r, int g, int b) {
// Assuming 'linearRGB' as the 'color-interpolation' value of the mask.
return 0.2125 * r + 0.7154 * g + 0.0721 * b; return 0.2125 * r + 0.7154 * g + 0.0721 * b;
} }
@ -176,7 +143,6 @@ public class Mask extends Group {
public void compose(Raster src, Raster dstIn, WritableRaster dstOut) { public void compose(Raster src, Raster dstIn, WritableRaster dstOut) {
assert dstIn == dstOut; assert dstIn == dstOut;
assert src.getNumBands() == dstIn.getNumBands(); assert src.getNumBands() == dstIn.getNumBands();
int x = dstOut.getMinX(); int x = dstOut.getMinX();
int w = dstOut.getWidth(); int w = dstOut.getWidth();
int y = dstOut.getMinY(); int y = dstOut.getMinY();

View file

@ -1,5 +1,8 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.element;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.util.PaintCache;
import org.xbib.graphics.svg.util.PaintUtil;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Graphics2D; import java.awt.Graphics2D;
@ -12,23 +15,23 @@ import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.util.List; import java.util.List;
abstract public class RenderableElement extends TransformableElement { public abstract class RenderableElement extends TransformableElement {
AffineTransform cachedXform = null; protected AffineTransform cachedXform = null;
Mask cachedMask; public Mask cachedMask;
Filter filter; public Filter filter;
Shape cachedClip = null; protected Shape cachedClip = null;
public static final int VECTOR_EFFECT_NONE = 0; public static final int VECTOR_EFFECT_NONE = 0;
public static final int VECTOR_EFFECT_NON_SCALING_STROKE = 1; public static final int VECTOR_EFFECT_NON_SCALING_STROKE = 1;
int vectorEffect; protected int vectorEffect;
private BufferPainter.Cache bufferCache; private PaintCache bufferCache;
public RenderableElement() { public RenderableElement() {
} }
@ -37,11 +40,11 @@ abstract public class RenderableElement extends TransformableElement {
super(id, parent); super(id, parent);
} }
BufferPainter.Cache getBufferCache() { public PaintCache getBufferCache() {
return bufferCache; return bufferCache;
} }
void setBufferImage(BufferPainter.Cache bufferCache) { public void setBufferImage(PaintCache bufferCache) {
this.bufferCache = bufferCache; this.bufferCache = bufferCache;
} }
@ -63,36 +66,12 @@ abstract public class RenderableElement extends TransformableElement {
} }
public void render(Graphics2D g) throws SVGException, IOException { public void render(Graphics2D g) throws SVGException, IOException {
BufferPainter.paintElement(g, this); PaintUtil.paintElement(g, this);
} }
private Mask getMask(StyleAttribute styleAttrib) throws SVGException { public abstract void doRender(Graphics2D g) throws SVGException, IOException;
if (getStyle(styleAttrib.setName("mask"), false)
&& !"none".equals(styleAttrib.getStringValue())) {
URI uri = styleAttrib.getURIValue(getXMLBase());
if (uri == null) {
return null;
}
return (Mask) diagram.getUniverse().getElement(uri);
}
return null;
}
private Filter getFilter(StyleAttribute styleAttrib) throws SVGException { public void pick(Point2D point, boolean boundingBox, List<List<SVGElement>> retVec) throws SVGException, IOException {
if (getStyle(styleAttrib.setName("filter"), false)
&& !"none".equals(styleAttrib.getStringValue())) {
URI uri = styleAttrib.getURIValue(getXMLBase());
if (uri == null) {
return null;
}
return (Filter) diagram.getUniverse().getElement(uri);
}
return null;
}
abstract protected void doRender(Graphics2D g) throws SVGException, IOException;
void pick(Point2D point, boolean boundingBox, List<List<SVGElement>> retVec) throws SVGException, IOException {
if (cachedMask != null) { if (cachedMask != null) {
cachedMask.pickElement(point, boundingBox, retVec, this); cachedMask.pickElement(point, boundingBox, retVec, this);
} else { } else {
@ -100,9 +79,9 @@ abstract public class RenderableElement extends TransformableElement {
} }
} }
protected abstract void doPick(Point2D point, boolean boundingBox, List<List<SVGElement>> retVec) throws SVGException, IOException; public abstract void doPick(Point2D point, boolean boundingBox, List<List<SVGElement>> retVec) throws SVGException, IOException;
void pick(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List<List<SVGElement>> retVec) throws SVGException, IOException { public void pick(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List<List<SVGElement>> retVec) throws SVGException, IOException {
if (cachedMask != null) { if (cachedMask != null) {
cachedMask.pickElement(pickArea, ltw, boundingBox, retVec, this); cachedMask.pickElement(pickArea, ltw, boundingBox, retVec, this);
} else { } else {
@ -110,9 +89,9 @@ abstract public class RenderableElement extends TransformableElement {
} }
} }
protected abstract void doPick(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List<List<SVGElement>> retVec) throws SVGException, IOException; public abstract void doPick(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List<List<SVGElement>> retVec) throws SVGException, IOException;
abstract public Rectangle2D getBoundingBox() throws SVGException; public abstract Rectangle2D getBoundingBox() throws SVGException;
protected void beginLayer(Graphics2D g) throws SVGException { protected void beginLayer(Graphics2D g) throws SVGException {
if (xform != null) { if (xform != null) {
@ -157,4 +136,28 @@ abstract public class RenderableElement extends TransformableElement {
g.setTransform(cachedXform); g.setTransform(cachedXform);
} }
} }
private Mask getMask(StyleAttribute styleAttrib) throws SVGException {
if (getStyle(styleAttrib.setName("mask"), false)
&& !"none".equals(styleAttrib.getStringValue())) {
URI uri = styleAttrib.getURIValue(getXMLBase());
if (uri == null) {
return null;
}
return (Mask) diagram.getUniverse().getElement(uri);
}
return null;
}
private Filter getFilter(StyleAttribute styleAttrib) throws SVGException {
if (getStyle(styleAttrib.setName("filter"), false)
&& !"none".equals(styleAttrib.getStringValue())) {
URI uri = styleAttrib.getURIValue(getXMLBase());
if (uri == null) {
return null;
}
return (Filter) diagram.getUniverse().getElement(uri);
}
return null;
}
} }

View file

@ -1,5 +1,11 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.element;
import org.xbib.graphics.svg.SVGDiagram;
import org.xbib.graphics.svg.SVGElementException;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.SVGLoaderHelper;
import org.xbib.graphics.svg.SVGParseException;
import org.xbib.graphics.svg.SVGRoot;
import org.xbib.graphics.svg.pathcmd.BuildHistory; import org.xbib.graphics.svg.pathcmd.BuildHistory;
import org.xbib.graphics.svg.pathcmd.PathCommand; import org.xbib.graphics.svg.pathcmd.PathCommand;
import org.xbib.graphics.svg.pathcmd.PathParser; import org.xbib.graphics.svg.pathcmd.PathParser;
@ -22,10 +28,12 @@ import java.util.Set;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
abstract public class SVGElement { 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<>();
protected SVGElement parent; protected SVGElement parent;
protected final ArrayList<SVGElement> children = new ArrayList<>(); protected final ArrayList<SVGElement> children = new ArrayList<>();
@ -58,7 +66,7 @@ abstract public class SVGElement {
this.parent = parent; this.parent = parent;
} }
abstract public String getTagName(); public abstract String getTagName();
public SVGElement getParent() { public SVGElement getParent() {
return parent; return parent;
@ -81,11 +89,9 @@ abstract public class SVGElement {
public List<SVGElement> getChildren(List<SVGElement> retVec) { public List<SVGElement> getChildren(List<SVGElement> retVec) {
if (retVec == null) { if (retVec == null) {
retVec = new ArrayList<SVGElement>(); retVec = new ArrayList<>();
} }
retVec.addAll(children); retVec.addAll(children);
return retVec; return retVec;
} }
@ -157,7 +163,7 @@ abstract public class SVGElement {
child.setDiagram(diagram); child.setDiagram(diagram);
} }
protected void setDiagram(SVGDiagram diagram) { public void setDiagram(SVGDiagram diagram) {
this.diagram = diagram; this.diagram = diagram;
diagram.setElement(id, this); diagram.setElement(id, this);
for (SVGElement ele : children) { for (SVGElement ele : children) {
@ -207,17 +213,15 @@ abstract public class SVGElement {
return id; return id;
} }
LinkedList<SVGElement> contexts = new LinkedList<>(); public void pushParentContext(SVGElement context) {
protected void pushParentContext(SVGElement context) {
contexts.addLast(context); contexts.addLast(context);
} }
protected SVGElement popParentContext() { public SVGElement popParentContext() {
return contexts.removeLast(); return contexts.removeLast();
} }
protected SVGElement getParentContext() { public SVGElement getParentContext() {
return contexts.isEmpty() ? null : contexts.getLast(); return contexts.isEmpty() ? null : contexts.getLast();
} }

View file

@ -1,7 +1,9 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.element;
import org.xbib.graphics.svg.Marker.MarkerLayout; import org.xbib.graphics.svg.Marker;
import org.xbib.graphics.svg.Marker.MarkerPos; import org.xbib.graphics.svg.MarkerLayout;
import org.xbib.graphics.svg.MarkerPos;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.AlphaComposite; import java.awt.AlphaComposite;
@ -18,7 +20,7 @@ import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.util.List; import java.util.List;
abstract public class ShapeElement extends RenderableElement { public abstract class ShapeElement extends RenderableElement {
protected float strokeWidthScalar = 1f; protected float strokeWidthScalar = 1f;
@ -26,36 +28,22 @@ abstract public class ShapeElement extends RenderableElement {
} }
@Override @Override
abstract protected void doRender(Graphics2D g) throws SVGException, IOException; public abstract void doRender(Graphics2D g) throws SVGException, IOException;
@Override @Override
protected void doPick(Point2D point, boolean boundingBox, List<List<SVGElement>> retVec) throws SVGException, IOException { public void doPick(Point2D point, boolean boundingBox, List<List<SVGElement>> retVec) throws SVGException, IOException {
if ((boundingBox ? getBoundingBox() : getShape()).contains(point)) { if ((boundingBox ? getBoundingBox() : getShape()).contains(point)) {
retVec.add(getPath(null)); retVec.add(getPath(null));
} }
} }
@Override @Override
protected void doPick(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List<List<SVGElement>> retVec) throws SVGException, IOException { public void doPick(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List<List<SVGElement>> retVec) throws SVGException, IOException {
if (ltw.createTransformedShape((boundingBox ? getBoundingBox() : getShape())).intersects(pickArea)) { if (ltw.createTransformedShape((boundingBox ? getBoundingBox() : getShape())).intersects(pickArea)) {
retVec.add(getPath(null)); retVec.add(getPath(null));
} }
} }
private Paint handleCurrentColor(StyleAttribute styleAttrib) throws SVGException {
if (styleAttrib.getStringValue().equals("currentColor")) {
StyleAttribute currentColorAttrib = new StyleAttribute();
if (getStyle(currentColorAttrib.setName("color"))) {
if (!currentColorAttrib.getStringValue().equals("none")) {
return currentColorAttrib.getColorValue();
}
}
return null;
} else {
return styleAttrib.getColorValue();
}
}
protected void renderShape(Graphics2D g, Shape shape) throws SVGException, IOException { protected void renderShape(Graphics2D g, Shape shape) throws SVGException, IOException {
StyleAttribute styleAttrib = new StyleAttribute(); StyleAttribute styleAttrib = new StyleAttribute();
if (getStyle(styleAttrib.setName("visibility"))) { if (getStyle(styleAttrib.setName("visibility"))) {
@ -229,7 +217,7 @@ abstract public class ShapeElement extends RenderableElement {
layout.layout(shape); layout.layout(shape);
List<MarkerPos> list = layout.getMarkerList(); List<MarkerPos> list = layout.getMarkerList();
for (MarkerPos pos : list) { for (MarkerPos pos : list) {
switch (pos.type) { switch (pos.getType()) {
case Marker.MARKER_START: case Marker.MARKER_START:
if (markerStart != null) { if (markerStart != null) {
markerStart.render(g, pos, strokeWidth); markerStart.render(g, pos, strokeWidth);
@ -250,7 +238,7 @@ abstract public class ShapeElement extends RenderableElement {
} }
} }
abstract public Shape getShape(); public abstract Shape getShape();
protected Rectangle2D includeStrokeInBounds(Rectangle2D rect) throws SVGException { protected Rectangle2D includeStrokeInBounds(Rectangle2D rect) throws SVGException {
StyleAttribute styleAttrib = new StyleAttribute(); StyleAttribute styleAttrib = new StyleAttribute();
@ -267,4 +255,18 @@ abstract public class ShapeElement extends RenderableElement {
rect.getHeight() + strokeWidth); rect.getHeight() + strokeWidth);
return rect; return rect;
} }
private Paint handleCurrentColor(StyleAttribute styleAttrib) throws SVGException {
if (styleAttrib.getStringValue().equals("currentColor")) {
StyleAttribute currentColorAttrib = new StyleAttribute();
if (getStyle(currentColorAttrib.setName("color"))) {
if (!currentColorAttrib.getStringValue().equals("none")) {
return currentColorAttrib.getColorValue();
}
}
return null;
} else {
return styleAttrib.getColorValue();
}
}
} }

View file

@ -1,5 +1,8 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.element;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.SVGLoaderHelper;
import org.xbib.graphics.svg.element.SVGElement;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import org.xbib.graphics.svg.xml.StyleSheet; import org.xbib.graphics.svg.xml.StyleSheet;

View file

@ -0,0 +1,57 @@
package org.xbib.graphics.svg.element;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
public abstract class TransformableElement extends SVGElement {
protected AffineTransform xform = null;
public TransformableElement() {
}
public TransformableElement(String id, SVGElement parent) {
super(id, parent);
}
@Override
public boolean updateTime(double curTime) throws SVGException, IOException {
StyleAttribute sty = new StyleAttribute();
if (getPres(sty.setName("transform"))) {
AffineTransform newXform = parseTransform(sty.getStringValue());
if (!newXform.equals(xform)) {
xform = newXform;
return true;
}
}
return false;
}
@Override
protected void build() throws SVGException, IOException {
super.build();
StyleAttribute sty = new StyleAttribute();
if (getPres(sty.setName("transform"))) {
xform = parseTransform(sty.getStringValue());
}
}
protected Shape shapeToParent(Shape shape) {
if (xform == null) {
return shape;
}
return xform.createTransformedShape(shape);
}
protected Rectangle2D boundsToParent(Rectangle2D rect) {
if (xform == null || rect == null) {
return rect;
}
return xform.createTransformedShape(rect).getBounds2D();
}
}

View file

@ -0,0 +1,61 @@
package org.xbib.graphics.svg.element.filtereffects;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.xml.StyleAttribute;
import java.io.IOException;
public class DistantLight extends Light {
public static final String TAG_NAME = "fedistantlight";
float azimuth = 0f;
float elevation = 0f;
@Override
public String getTagName() {
return TAG_NAME;
}
@Override
protected void build() throws SVGException, IOException {
super.build();
StyleAttribute sty = new StyleAttribute();
if (getPres(sty.setName("azimuth"))) {
azimuth = sty.getFloatValueWithUnits();
}
if (getPres(sty.setName("elevation"))) {
elevation = sty.getFloatValueWithUnits();
}
}
public float getAzimuth() {
return azimuth;
}
public float getElevation() {
return elevation;
}
@Override
public boolean updateTime(double curTime) throws SVGException {
StyleAttribute sty = new StyleAttribute();
boolean stateChange = false;
if (getPres(sty.setName("azimuth"))) {
float newVal = sty.getFloatValueWithUnits();
if (newVal != azimuth) {
azimuth = newVal;
stateChange = true;
}
}
if (getPres(sty.setName("elevation"))) {
float newVal = sty.getFloatValueWithUnits();
if (newVal != elevation) {
elevation = newVal;
stateChange = true;
}
}
return stateChange;
}
}

View file

@ -0,0 +1,120 @@
package org.xbib.graphics.svg.element.filtereffects;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.element.SVGElement;
import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Rectangle;
import java.io.IOException;
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";
public static final int FP_SOURCE_GRAPHIC = 0;
public static final int FP_SOURCE_ALPHA = 1;
public static final int FP_BACKGROUND_IMAGE = 2;
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() {
}
@Override
public String getTagName() {
return TAG_NAME;
}
@Override
protected void build() throws SVGException, IOException {
super.build();
}
public List<FilterOp> getOperations(Rectangle bounds, float xScale, float yScale) {
return null;
}
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();
boolean stateChange = false;
if (getPres(sty.setName("x"))) {
float newVal = sty.getFloatValueWithUnits();
if (newVal != x) {
x = newVal;
stateChange = true;
}
}
if (getPres(sty.setName("y"))) {
float newVal = sty.getFloatValueWithUnits();
if (newVal != y) {
y = newVal;
stateChange = true;
}
}
if (getPres(sty.setName("width"))) {
float newVal = sty.getFloatValueWithUnits();
if (newVal != width) {
width = newVal;
stateChange = true;
}
}
if (getPres(sty.setName("height"))) {
float newVal = sty.getFloatValueWithUnits();
if (newVal != height) {
height = newVal;
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;
}
}
} catch (Exception e) {
throw new SVGException(e);
}
return stateChange;
}
}

View file

@ -0,0 +1,16 @@
package org.xbib.graphics.svg.element.filtereffects;
import java.awt.Rectangle;
import java.awt.image.BufferedImageOp;
public class FilterOp {
public final BufferedImageOp op;
public final Rectangle requiredImageBounds;
public FilterOp(BufferedImageOp op, Rectangle requiredImageBounds) {
this.op = op;
this.requiredImageBounds = requiredImageBounds;
}
}

View file

@ -1,5 +1,6 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.element.filtereffects;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Rectangle; import java.awt.Rectangle;
@ -9,13 +10,18 @@ import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
public class FeGaussianBlur extends FilterEffects { public class GaussianBlur extends FilterEffects {
public static final String TAG_NAME = "fegaussianblur"; public static final String TAG_NAME = "fegaussianblur";
private float[] stdDeviation; private float[] stdDeviation;
private float xCurrent; private float xCurrent;
private float yCurrent; private float yCurrent;
private ConvolveOp xBlur; private ConvolveOp xBlur;
private ConvolveOp yBlur; private ConvolveOp yBlur;
@Override @Override
@ -27,7 +33,6 @@ public class FeGaussianBlur extends FilterEffects {
protected void build() throws SVGException, IOException { protected void build() throws SVGException, IOException {
super.build(); super.build();
StyleAttribute sty = new StyleAttribute(); StyleAttribute sty = new StyleAttribute();
stdDeviation = new float[]{0f}; stdDeviation = new float[]{0f};
if (getPres(sty.setName("stdDeviation"))) { if (getPres(sty.setName("stdDeviation"))) {
stdDeviation = sty.getFloatList(); stdDeviation = sty.getFloatList();
@ -40,7 +45,6 @@ public class FeGaussianBlur 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 xSigma > 0
? getGaussianBlurFilter(inputBounds, xSigma, true) ? getGaussianBlurFilter(inputBounds, xSigma, true)
@ -63,41 +67,34 @@ public class FeGaussianBlur extends FilterEffects {
yCurrent = sigma; yCurrent = sigma;
} }
float[] data = new float[size]; float[] data = new float[size];
float radius2 = radius * radius; float radius2 = radius * radius;
float twoSigmaSquare = 2.0f * sigma * sigma; float twoSigmaSquare = 2.0f * sigma * sigma;
float sigmaRoot = (float) Math.sqrt(twoSigmaSquare * Math.PI); float sigmaRoot = (float) Math.sqrt(twoSigmaSquare * Math.PI);
float total = 0.0f; float total = 0.0f;
float middle = size / 2f; float middle = size / 2f;
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];
} }
for (int i = 0; i < data.length; i++) { for (int i = 0; i < data.length; i++) {
data[i] /= total; data[i] /= total;
} }
if (horizontal) { if (horizontal) {
xBlur = new ConvolveOp(new Kernel(size, 1, data), ConvolveOp.EDGE_NO_OP, null); xBlur = new ConvolveOp(new Kernel(size, 1, data), ConvolveOp.EDGE_NO_OP, null);
} else { } else {
yBlur = new ConvolveOp(new Kernel(1, size, data), ConvolveOp.EDGE_NO_OP, null); yBlur = new ConvolveOp(new Kernel(1, size, data), ConvolveOp.EDGE_NO_OP, null);
} }
} }
Rectangle dstBounds = new Rectangle(inputBounds); Rectangle dstBounds = new Rectangle(inputBounds);
if (horizontal) { if (horizontal) {
dstBounds.grow(size, 0); dstBounds.grow(size, 0);
} else { } else {
dstBounds.grow(0, size); dstBounds.grow(0, size);
} }
return new FilterOp(horizontal ? xBlur : yBlur, dstBounds); return new FilterOp(horizontal ? xBlur : yBlur, dstBounds);
} }
} }

View file

@ -0,0 +1,11 @@
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;
}
}

View file

@ -0,0 +1,82 @@
package org.xbib.graphics.svg.element.filtereffects;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.xml.StyleAttribute;
import java.io.IOException;
public class PointLight extends Light {
public static final String TAG_NAME = "fepointlight";
float x = 0f;
float y = 0f;
float z = 0f;
public PointLight() {
}
@Override
public String getTagName() {
return TAG_NAME;
}
@Override
protected void build() throws SVGException, IOException {
super.build();
StyleAttribute sty = new StyleAttribute();
if (getPres(sty.setName("x"))) {
x = sty.getFloatValueWithUnits();
}
if (getPres(sty.setName("y"))) {
y = sty.getFloatValueWithUnits();
}
if (getPres(sty.setName("z"))) {
z = sty.getFloatValueWithUnits();
}
}
@Override
public float getX() {
return x;
}
@Override
public float getY() {
return y;
}
public float getZ() {
return z;
}
@Override
public boolean updateTime(double curTime) throws SVGException {
StyleAttribute sty = new StyleAttribute();
boolean stateChange = false;
if (getPres(sty.setName("x"))) {
float newVal = sty.getFloatValueWithUnits();
if (newVal != x) {
x = newVal;
stateChange = true;
}
}
if (getPres(sty.setName("y"))) {
float newVal = sty.getFloatValueWithUnits();
if (newVal != y) {
y = newVal;
stateChange = true;
}
}
if (getPres(sty.setName("z"))) {
float newVal = sty.getFloatValueWithUnits();
if (newVal != z) {
z = newVal;
stateChange = true;
}
}
return stateChange;
}
}

View file

@ -1,65 +1,29 @@
/* package org.xbib.graphics.svg.element.filtereffects;
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on March 18, 2004, 6:52 AM
*/
package org.xbib.graphics.svg;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.io.IOException; import java.io.IOException;
/** public class SpotLight extends Light {
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class FeSpotLight extends FeLight {
public static final String TAG_NAME = "fespotlight"; public static final String TAG_NAME = "fespotlight";
float x = 0f;
float y = 0f;
float z = 0f;
float pointsAtX = 0f;
float pointsAtY = 0f;
float pointsAtZ = 0f;
float specularComponent = 0f;
float limitingConeAngle = 0f;
/** float x = 0f;
* Creates a new instance of FillElement
*/ float y = 0f;
public FeSpotLight() {
} float z = 0f;
float pointsAtX = 0f;
float pointsAtY = 0f;
float pointsAtZ = 0f;
float specularComponent = 0f;
float limitingConeAngle = 0f;
@Override @Override
public String getTagName() { public String getTagName() {
@ -69,9 +33,7 @@ public class FeSpotLight extends FeLight {
@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("x"))) { if (getPres(sty.setName("x"))) {
x = sty.getFloatValueWithUnits(); x = sty.getFloatValueWithUnits();
} }
@ -134,12 +96,8 @@ public class FeSpotLight extends FeLight {
@Override @Override
public boolean updateTime(double curTime) throws SVGException { public boolean updateTime(double curTime) throws SVGException {
// if (trackManager.getNumTracks() == 0) return false;
//Get current values for parameters
StyleAttribute sty = new StyleAttribute(); StyleAttribute sty = new StyleAttribute();
boolean stateChange = false; boolean stateChange = false;
if (getPres(sty.setName("x"))) { if (getPres(sty.setName("x"))) {
float newVal = sty.getFloatValueWithUnits(); float newVal = sty.getFloatValueWithUnits();
if (newVal != x) { if (newVal != x) {
@ -147,7 +105,6 @@ public class FeSpotLight extends FeLight {
stateChange = true; stateChange = true;
} }
} }
if (getPres(sty.setName("y"))) { if (getPres(sty.setName("y"))) {
float newVal = sty.getFloatValueWithUnits(); float newVal = sty.getFloatValueWithUnits();
if (newVal != y) { if (newVal != y) {
@ -155,7 +112,6 @@ public class FeSpotLight extends FeLight {
stateChange = true; stateChange = true;
} }
} }
if (getPres(sty.setName("z"))) { if (getPres(sty.setName("z"))) {
float newVal = sty.getFloatValueWithUnits(); float newVal = sty.getFloatValueWithUnits();
if (newVal != z) { if (newVal != z) {
@ -163,7 +119,6 @@ public class FeSpotLight extends FeLight {
stateChange = true; stateChange = true;
} }
} }
if (getPres(sty.setName("pointsAtX"))) { if (getPres(sty.setName("pointsAtX"))) {
float newVal = sty.getFloatValueWithUnits(); float newVal = sty.getFloatValueWithUnits();
if (newVal != pointsAtX) { if (newVal != pointsAtX) {
@ -171,7 +126,6 @@ public class FeSpotLight extends FeLight {
stateChange = true; stateChange = true;
} }
} }
if (getPres(sty.setName("pointsAtY"))) { if (getPres(sty.setName("pointsAtY"))) {
float newVal = sty.getFloatValueWithUnits(); float newVal = sty.getFloatValueWithUnits();
if (newVal != pointsAtY) { if (newVal != pointsAtY) {
@ -179,7 +133,6 @@ public class FeSpotLight extends FeLight {
stateChange = true; stateChange = true;
} }
} }
if (getPres(sty.setName("pointsAtZ"))) { if (getPres(sty.setName("pointsAtZ"))) {
float newVal = sty.getFloatValueWithUnits(); float newVal = sty.getFloatValueWithUnits();
if (newVal != pointsAtZ) { if (newVal != pointsAtZ) {
@ -187,7 +140,6 @@ public class FeSpotLight extends FeLight {
stateChange = true; stateChange = true;
} }
} }
if (getPres(sty.setName("specularComponent"))) { if (getPres(sty.setName("specularComponent"))) {
float newVal = sty.getFloatValueWithUnits(); float newVal = sty.getFloatValueWithUnits();
if (newVal != specularComponent) { if (newVal != specularComponent) {
@ -195,7 +147,6 @@ public class FeSpotLight extends FeLight {
stateChange = true; stateChange = true;
} }
} }
if (getPres(sty.setName("limitingConeAngle"))) { if (getPres(sty.setName("limitingConeAngle"))) {
float newVal = sty.getFloatValueWithUnits(); float newVal = sty.getFloatValueWithUnits();
if (newVal != limitingConeAngle) { if (newVal != limitingConeAngle) {
@ -203,7 +154,6 @@ public class FeSpotLight extends FeLight {
stateChange = true; stateChange = true;
} }
} }
return stateChange; return stateChange;
} }
} }

View file

@ -0,0 +1,39 @@
package org.xbib.graphics.svg.element.glyph;
import org.xbib.graphics.svg.SVGException;
import org.xbib.graphics.svg.xml.StyleAttribute;
import java.io.IOException;
public class Glyph extends MissingGlyph {
public static final String TAG_NAME = "missingglyph";
String unicode;
public Glyph() {
}
@Override
public String getTagName() {
return TAG_NAME;
}
@Override
protected void build() throws SVGException, IOException {
super.build();
StyleAttribute sty = new StyleAttribute();
if (getPres(sty.setName("unicode"))) {
unicode = sty.getStringValue();
}
}
public String getUnicode() {
return unicode;
}
@Override
public boolean updateTime(double curTime) throws SVGException {
return false;
}
}

View file

@ -1,5 +1,12 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.element.glyph;
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.RenderableElement;
import org.xbib.graphics.svg.element.SVGElement;
import org.xbib.graphics.svg.element.ShapeElement;
import org.xbib.graphics.svg.pathcmd.BuildHistory; import org.xbib.graphics.svg.pathcmd.BuildHistory;
import org.xbib.graphics.svg.pathcmd.PathCommand; import org.xbib.graphics.svg.pathcmd.PathCommand;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
@ -18,8 +25,11 @@ public class MissingGlyph extends ShapeElement {
private Shape path = null; private Shape path = null;
private float horizAdvX = -1; private float horizAdvX = -1;
private float vertOriginX = -1; private float vertOriginX = -1;
private float vertOriginY = -1; private float vertOriginY = -1;
private float vertAdvY = -1; private float vertAdvY = -1;
public MissingGlyph() { public MissingGlyph() {
@ -78,7 +88,7 @@ public class MissingGlyph extends ShapeElement {
} }
@Override @Override
protected void doRender(Graphics2D g) throws SVGException, IOException { public void doRender(Graphics2D g) throws SVGException, IOException {
if (path != null) { if (path != null) {
renderShape(g, path); renderShape(g, path);
} }

View file

@ -1,40 +1,11 @@
/* package org.xbib.graphics.svg.element.gradient;
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on January 26, 2004, 3:25 AM
*/
package org.xbib.graphics.svg;
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.FillElement;
import org.xbib.graphics.svg.element.SVGElement;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Color; import java.awt.Color;
@ -42,37 +13,36 @@ import java.awt.geom.AffineTransform;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator; import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger; public abstract class Gradient extends FillElement {
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
abstract public class Gradient extends FillElement {
public static final String TAG_NAME = "gradient"; public static final String TAG_NAME = "gradient";
public static final int SM_PAD = 0; public static final int SM_PAD = 0;
public static final int SM_REPEAT = 1; public static final int SM_REPEAT = 1;
public static final int SM_REFLECT = 2; public static final int SM_REFLECT = 2;
int spreadMethod = SM_PAD;
public int spreadMethod = SM_PAD;
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;
protected int gradientUnits = GU_OBJECT_BOUNDING_BOX; protected int gradientUnits = GU_OBJECT_BOUNDING_BOX;
//Either this gradient contains a list of stops, or it will take it's
// stops from the referenced gradient List<Stop> stops = new ArrayList<>();
ArrayList<Stop> stops = new ArrayList<Stop>();
URI stopRef = null; URI stopRef = null;
protected AffineTransform gradientTransform = null; protected AffineTransform gradientTransform = null;
//Cache arrays of stop values here
float[] stopFractions; float[] stopFractions;
Color[] stopColors; Color[] stopColors;
/**
* Creates a new instance of Gradient
*/
public Gradient() { public Gradient() {
} }
@ -81,14 +51,9 @@ abstract public class Gradient extends FillElement {
return TAG_NAME; return TAG_NAME;
} }
/**
* Called after the start element but before the end element to indicate
* each child tag that has been processed
*/
@Override @Override
public void loaderAddChild(SVGLoaderHelper helper, SVGElement child) throws SVGElementException { public void loaderAddChild(SVGLoaderHelper helper, SVGElement child) throws SVGElementException {
super.loaderAddChild(helper, child); super.loaderAddChild(helper, child);
if (!(child instanceof Stop)) { if (!(child instanceof Stop)) {
return; return;
} }
@ -98,10 +63,8 @@ abstract public class Gradient extends FillElement {
@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();
String strn; String strn;
if (getPres(sty.setName("spreadMethod"))) { if (getPres(sty.setName("spreadMethod"))) {
strn = sty.getStringValue().toLowerCase(); strn = sty.getStringValue().toLowerCase();
if (strn.equals("repeat")) { if (strn.equals("repeat")) {
@ -112,7 +75,6 @@ abstract public class Gradient extends FillElement {
spreadMethod = SM_PAD; spreadMethod = SM_PAD;
} }
} }
if (getPres(sty.setName("gradientUnits"))) { if (getPres(sty.setName("gradientUnits"))) {
strn = sty.getStringValue().toLowerCase(); strn = sty.getStringValue().toLowerCase();
if (strn.equals("userspaceonuse")) { if (strn.equals("userspaceonuse")) {
@ -121,23 +83,15 @@ abstract public class Gradient extends FillElement {
gradientUnits = GU_OBJECT_BOUNDING_BOX; gradientUnits = GU_OBJECT_BOUNDING_BOX;
} }
} }
if (getPres(sty.setName("gradientTransform"))) { if (getPres(sty.setName("gradientTransform"))) {
gradientTransform = parseTransform(sty.getStringValue()); gradientTransform = parseTransform(sty.getStringValue());
} }
//If we still don't have one, set it to identity
if (gradientTransform == null) { if (gradientTransform == null) {
gradientTransform = new AffineTransform(); gradientTransform = new AffineTransform();
} }
//Check to see if we're using our own stops or referencing someone else's
if (getPres(sty.setName("xlink:href"))) { if (getPres(sty.setName("xlink:href"))) {
try { try {
stopRef = sty.getURIValue(getXMLBase()); stopRef = sty.getURIValue(getXMLBase());
//System.err.println("Gradient: " + sty.getStringValue() + ", " + getXMLBase() + ", " + src);
// URI src = getXMLBase().resolve(href);
// stopRef = (Gradient)diagram.getUniverse().getElement(src);
} catch (Exception e) { } catch (Exception e) {
throw new SVGException("Could not resolve relative URL in Gradient: " + sty.getStringValue() + ", " + getXMLBase(), e); throw new SVGException("Could not resolve relative URL in Gradient: " + sty.getStringValue() + ", " + getXMLBase(), e);
} }
@ -145,33 +99,23 @@ abstract public class Gradient extends FillElement {
} }
private void buildStops() { private void buildStops() {
ArrayList<Stop> stopList = new ArrayList<Stop>(stops); ArrayList<Stop> stopList = new ArrayList<>(stops);
stopList.sort(new Comparator<Stop>() { stopList.sort((o1, o2) -> Float.compare(o1.offset, o2.offset));
public int compare(Stop o1, Stop o2) {
return Float.compare(o1.offset, o2.offset);
}
});
//Remove doubles
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).offset == stopList.get(i).offset) {
stopList.remove(i + 1); stopList.remove(i + 1);
} }
} }
stopFractions = new float[stopList.size()]; stopFractions = new float[stopList.size()];
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.color.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.opacity * 255), 0, 255));
stopColors[idx] = stopColor; stopColors[idx] = stopColor;
stopFractions[idx] = stop.offset; stopFractions[idx] = stop.offset;
idx++; idx++;
} }
} }
public float[] getStopFractions() { public float[] getStopFractions() {
@ -179,13 +123,10 @@ abstract public class Gradient extends FillElement {
Gradient grad = (Gradient) diagram.getUniverse().getElement(stopRef); Gradient grad = (Gradient) diagram.getUniverse().getElement(stopRef);
return grad.getStopFractions(); return grad.getStopFractions();
} }
if (stopFractions != null) { if (stopFractions != null) {
return stopFractions; return stopFractions;
} }
buildStops(); buildStops();
return stopFractions; return stopFractions;
} }
@ -194,36 +135,18 @@ abstract public class Gradient extends FillElement {
Gradient grad = (Gradient) diagram.getUniverse().getElement(stopRef); Gradient grad = (Gradient) diagram.getUniverse().getElement(stopRef);
return grad.getStopColors(); return grad.getStopColors();
} }
if (stopColors != null) { if (stopColors != null) {
return stopColors; return stopColors;
} }
buildStops(); buildStops();
return stopColors; return stopColors;
} }
// public void setStops(Color[] colors, float[] fractions)
// {
// if (colors.length != fractions.length)
// {
// throw new IllegalArgumentException();
// }
//
// this.stopColors = colors;
// this.stopFractions = fractions;
// stopRef = null;
// }
private int clamp(int val, int min, int max) { private int clamp(int val, int min, int max) {
if (val < min) { if (val < min) {
return min; return min;
} }
if (val > max) { return Math.min(val, max);
return max;
}
return val;
} }
public void setStopRef(URI grad) { public void setStopRef(URI grad) {
@ -234,23 +157,11 @@ abstract public class Gradient extends FillElement {
stops.add(stop); stops.add(stop);
} }
/**
* 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 { public boolean updateTime(double curTime) throws SVGException {
// if (trackManager.getNumTracks() == 0) return false;
boolean stateChange = false; boolean stateChange = false;
//Get current values for parameters
StyleAttribute sty = new StyleAttribute(); StyleAttribute sty = new StyleAttribute();
String strn; String strn;
if (getPres(sty.setName("spreadMethod"))) { if (getPres(sty.setName("spreadMethod"))) {
int newVal; int newVal;
strn = sty.getStringValue().toLowerCase(); strn = sty.getStringValue().toLowerCase();
@ -266,7 +177,6 @@ abstract public class Gradient extends FillElement {
stateChange = true; stateChange = true;
} }
} }
if (getPres(sty.setName("gradientUnits"))) { if (getPres(sty.setName("gradientUnits"))) {
int newVal; int newVal;
strn = sty.getStringValue().toLowerCase(); strn = sty.getStringValue().toLowerCase();
@ -280,31 +190,20 @@ abstract public class Gradient extends FillElement {
stateChange = true; stateChange = true;
} }
} }
if (getPres(sty.setName("gradientTransform"))) { if (getPres(sty.setName("gradientTransform"))) {
AffineTransform newVal = parseTransform(sty.getStringValue()); AffineTransform newVal = parseTransform(sty.getStringValue());
if (newVal != null && newVal.equals(gradientTransform)) { if (newVal.equals(gradientTransform)) {
gradientTransform = newVal; gradientTransform = newVal;
stateChange = true; stateChange = true;
} }
} }
//Check to see if we're using our own stops or referencing someone else's
if (getPres(sty.setName("xlink:href"))) { if (getPres(sty.setName("xlink:href"))) {
try { URI newVal = sty.getURIValue(getXMLBase());
URI newVal = sty.getURIValue(getXMLBase()); if ((newVal == null && stopRef != null) || !newVal.equals(stopRef)) {
if ((newVal == null && stopRef != null) || !newVal.equals(stopRef)) { stopRef = newVal;
stopRef = newVal; stateChange = true;
stateChange = true;
}
} catch (Exception e) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING,
"Could not parse xlink:href", e);
} }
} }
//Check stops, if any
for (Stop stop : stops) { for (Stop stop : stops) {
if (stop.updateTime(curTime)) { if (stop.updateTime(curTime)) {
stateChange = true; stateChange = true;
@ -312,7 +211,6 @@ abstract public class Gradient extends FillElement {
stopColors = null; stopColors = null;
} }
} }
return stateChange; return stateChange;
} }
} }

View file

@ -1,40 +1,7 @@
/* package org.xbib.graphics.svg.element.gradient;
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on January 26, 2004, 1:54 AM
*/
package org.xbib.graphics.svg;
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;
@ -46,21 +13,18 @@ import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.io.IOException; import java.io.IOException;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class LinearGradient extends Gradient { public class LinearGradient extends Gradient {
public static final String TAG_NAME = "lineargradient"; public static final String TAG_NAME = "lineargradient";
float x1 = 0f; float x1 = 0f;
float y1 = 0f; float y1 = 0f;
float x2 = 1f; float x2 = 1f;
float y2 = 0f; float y2 = 0f;
/**
* Creates a new instance of LinearGradient
*/
public LinearGradient() { public LinearGradient() {
} }
@ -72,21 +36,16 @@ public class LinearGradient extends Gradient {
@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("x1"))) { if (getPres(sty.setName("x1"))) {
x1 = sty.getFloatValueWithUnits(); x1 = sty.getFloatValueWithUnits();
} }
if (getPres(sty.setName("y1"))) { if (getPres(sty.setName("y1"))) {
y1 = sty.getFloatValueWithUnits(); y1 = sty.getFloatValueWithUnits();
} }
if (getPres(sty.setName("x2"))) { if (getPres(sty.setName("x2"))) {
x2 = sty.getFloatValueWithUnits(); x2 = sty.getFloatValueWithUnits();
} }
if (getPres(sty.setName("y2"))) { if (getPres(sty.setName("y2"))) {
y2 = sty.getFloatValueWithUnits(); y2 = sty.getFloatValueWithUnits();
} }
@ -107,7 +66,6 @@ public class LinearGradient extends Gradient {
method = MultipleGradientPaint.CycleMethod.REFLECT; method = MultipleGradientPaint.CycleMethod.REFLECT;
break; break;
} }
Paint paint; Paint paint;
Point2D.Float pt1 = new Point2D.Float(x1, y1); Point2D.Float pt1 = new Point2D.Float(x1, y1);
Point2D.Float pt2 = new Point2D.Float(x2, y2); Point2D.Float pt2 = new Point2D.Float(x2, y2);
@ -128,16 +86,12 @@ public class LinearGradient extends Gradient {
} else { } else {
AffineTransform viewXform = new AffineTransform(); AffineTransform viewXform = new AffineTransform();
viewXform.translate(bounds.getX(), bounds.getY()); viewXform.translate(bounds.getX(), bounds.getY());
//This is a hack to get around shapes that have a width or height of 0. Should be close enough to the true answer.
double width = Math.max(1, bounds.getWidth()); double width = Math.max(1, bounds.getWidth());
double height = Math.max(1, bounds.getHeight()); double height = Math.max(1, bounds.getHeight());
viewXform.scale(width, height); viewXform.scale(width, height);
if (gradientTransform != null) { if (gradientTransform != null) {
viewXform.concatenate(gradientTransform); viewXform.concatenate(gradientTransform);
} }
paint = new LinearGradientPaint( paint = new LinearGradientPaint(
pt1, pt1,
pt2, pt2,
@ -147,26 +101,14 @@ public class LinearGradient extends Gradient {
MultipleGradientPaint.ColorSpaceType.SRGB, MultipleGradientPaint.ColorSpaceType.SRGB,
viewXform); viewXform);
} }
return paint; return paint;
} }
/**
* 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 { public boolean updateTime(double curTime) throws SVGException {
// if (trackManager.getNumTracks() == 0) return stopChange;
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 (getPres(sty.setName("x1"))) { if (getPres(sty.setName("x1"))) {
float newVal = sty.getFloatValueWithUnits(); float newVal = sty.getFloatValueWithUnits();
if (newVal != x1) { if (newVal != x1) {
@ -174,7 +116,6 @@ public class LinearGradient extends Gradient {
shapeChange = true; shapeChange = true;
} }
} }
if (getPres(sty.setName("y1"))) { if (getPres(sty.setName("y1"))) {
float newVal = sty.getFloatValueWithUnits(); float newVal = sty.getFloatValueWithUnits();
if (newVal != y1) { if (newVal != y1) {
@ -182,7 +123,6 @@ public class LinearGradient extends Gradient {
shapeChange = true; shapeChange = true;
} }
} }
if (getPres(sty.setName("x2"))) { if (getPres(sty.setName("x2"))) {
float newVal = sty.getFloatValueWithUnits(); float newVal = sty.getFloatValueWithUnits();
if (newVal != x2) { if (newVal != x2) {
@ -190,7 +130,6 @@ public class LinearGradient extends Gradient {
shapeChange = true; shapeChange = true;
} }
} }
if (getPres(sty.setName("y2"))) { if (getPres(sty.setName("y2"))) {
float newVal = sty.getFloatValueWithUnits(); float newVal = sty.getFloatValueWithUnits();
if (newVal != y2) { if (newVal != y2) {
@ -198,7 +137,6 @@ public class LinearGradient extends Gradient {
shapeChange = true; shapeChange = true;
} }
} }
return changeState || shapeChange; return changeState || shapeChange;
} }
} }

View file

@ -1,5 +1,7 @@
package org.xbib.graphics.svg; 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 org.xbib.graphics.svg.xml.StyleAttribute;
import java.awt.Color; import java.awt.Color;

View file

@ -1,70 +1,26 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on January 26, 2004, 8:40 PM
*/
package org.xbib.graphics.svg.pathcmd; package org.xbib.graphics.svg.pathcmd;
//import org.apache.batik.ext.awt.geom.ExtendedGeneralPath;
import java.awt.Shape; import java.awt.Shape;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D; import java.awt.geom.Arc2D;
import java.awt.geom.GeneralPath; import java.awt.geom.GeneralPath;
/**
* This is a little used SVG function, as most editors will save curves as
* Beziers. To reduce the need to rely on the Batik library, this functionallity
* is being bypassed for the time being. In the future, it would be nice to
* extend the GeneralPath command to include the arcTo ability provided by Batik.
*
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class Arc extends PathCommand { public class Arc extends PathCommand {
public float rx = 0f; public float rx = 0f;
public float ry = 0f; public float ry = 0f;
public float xAxisRot = 0f; public float xAxisRot = 0f;
public boolean largeArc = false; public boolean largeArc = false;
public boolean sweep = false; public boolean sweep = false;
public float x = 0f; public float x = 0f;
public float y = 0f; public float y = 0f;
/**
* Creates a new instance of MoveTo
*/
public Arc() { public Arc() {
} }
@ -79,17 +35,13 @@ public class Arc extends PathCommand {
this.y = y; this.y = y;
} }
// public void appendPath(ExtendedGeneralPath path, BuildHistory hist)
@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.lastPoint.x : 0f;
float offy = isRelative ? hist.lastPoint.y : 0f; float offy = isRelative ? hist.lastPoint.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.lastPoint.x, hist.lastPoint.y);
// path.lineTo(x + offx, y + offy);
// hist.setPoint(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);
} }
@ -99,107 +51,44 @@ public class Arc extends PathCommand {
return 6; return 6;
} }
/**
* Adds an elliptical arc, defined by two radii, an angle from the
* x-axis, a flag to choose the large arc or not, a flag to
* indicate if we increase or decrease the angles and the final
* point of the arc.
*
* @param path The path that the arc will be appended to.
* @param rx the x radius of the ellipse
* @param ry the y radius of the ellipse
* @param angle the angle from the x-axis of the current
* coordinate system to the x-axis of the ellipse in degrees.
* @param largeArcFlag the large arc flag. If true the arc
* spanning less than or equal to 180 degrees is chosen, otherwise
* the arc spanning greater than 180 degrees is chosen
* @param sweepFlag the sweep flag. If true the line joining
* center to arc sweeps through decreasing angles otherwise it
* sweeps through increasing angles
* @param x the absolute x coordinate of the final point of the arc.
* @param y the absolute y coordinate of the final point of the arc.
* @param x0 - The absolute x coordinate of the initial point of the arc.
* @param y0 - The absolute y coordinate of the initial point of the arc.
*/
public void arcTo(GeneralPath path, float rx, float ry, public void arcTo(GeneralPath path, float rx, float ry,
float angle, float angle,
boolean largeArcFlag, boolean largeArcFlag,
boolean sweepFlag, boolean sweepFlag,
float x, float y, float x0, float y0) { float x, float y, float x0, float y0) {
// Ensure radii are valid
if (rx == 0 || ry == 0) { if (rx == 0 || ry == 0) {
path.lineTo(x, y); path.lineTo(x, y);
return; return;
} }
if (x0 == x && y0 == y) { if (x0 == x && y0 == y) {
// If the endpoints (x, y) and (x0, y0) are identical, then this
// is equivalent to omitting the elliptical arc segment entirely.
return; return;
} }
Arc2D arc = computeArc(x0, y0, rx, ry, angle, largeArcFlag, sweepFlag, x, y);
Arc2D arc = computeArc(x0, y0, rx, ry, angle,
largeArcFlag, sweepFlag, x, y);
if (arc == null) return;
AffineTransform t = AffineTransform.getRotateInstance AffineTransform t = AffineTransform.getRotateInstance
(Math.toRadians(angle), arc.getCenterX(), arc.getCenterY()); (Math.toRadians(angle), arc.getCenterX(), arc.getCenterY());
Shape s = t.createTransformedShape(arc); Shape s = t.createTransformedShape(arc);
path.append(s, true); path.append(s, true);
} }
/**
* This constructs an unrotated Arc2D from the SVG specification of an
* Elliptical arc. To get the final arc you need to apply a rotation
* transform such as:
* <p>
* AffineTransform.getRotateInstance
* (angle, arc.getX()+arc.getWidth()/2, arc.getY()+arc.getHeight()/2);
*
* @param x0 origin of arc in x
* @param y0 origin of arc in y
* @param rx radius of arc in x
* @param ry radius of arc in y
* @param angle number of radians in arc
* @param largeArcFlag
* @param sweepFlag
* @param x ending coordinate of arc in x
* @param y ending coordinate of arc in y
* @return arc shape
*/
public static Arc2D computeArc(double x0, double y0, public static Arc2D computeArc(double x0, double y0,
double rx, double ry, double rx, double ry,
double angle, double angle,
boolean largeArcFlag, boolean largeArcFlag,
boolean sweepFlag, boolean sweepFlag,
double x, double y) { double x, double y) {
//
// Elliptical arc implementation based on the SVG specification notes
//
// Compute the half distance between the current and the final point
double dx2 = (x0 - x) / 2.0; double dx2 = (x0 - x) / 2.0;
double dy2 = (y0 - y) / 2.0; double dy2 = (y0 - y) / 2.0;
// Convert angle from degrees to radians
angle = Math.toRadians(angle % 360.0); angle = Math.toRadians(angle % 360.0);
double cosAngle = Math.cos(angle); double cosAngle = Math.cos(angle);
double sinAngle = Math.sin(angle); double sinAngle = Math.sin(angle);
//
// Step 1 : Compute (x1, y1)
//
double x1 = (cosAngle * dx2 + sinAngle * dy2); double x1 = (cosAngle * dx2 + sinAngle * dy2);
double y1 = (-sinAngle * dx2 + cosAngle * dy2); double y1 = (-sinAngle * dx2 + cosAngle * dy2);
// Ensure radii are large enough
rx = Math.abs(rx); rx = Math.abs(rx);
ry = Math.abs(ry); ry = Math.abs(ry);
double Prx = rx * rx; double Prx = rx * rx;
double Pry = ry * ry; double Pry = ry * ry;
double Px1 = x1 * x1; double Px1 = x1 * x1;
double Py1 = y1 * y1; double Py1 = y1 * y1;
// check that radii are large enough
double radiiCheck = Px1 / Prx + Py1 / Pry; double radiiCheck = Px1 / Prx + Py1 / Pry;
if (radiiCheck > 1) { if (radiiCheck > 1) {
rx = Math.sqrt(radiiCheck) * rx; rx = Math.sqrt(radiiCheck) * rx;
@ -207,40 +96,25 @@ public class Arc extends PathCommand {
Prx = rx * rx; Prx = rx * rx;
Pry = ry * ry; Pry = ry * ry;
} }
//
// Step 2 : Compute (cx1, cy1)
//
double sign = (largeArcFlag == sweepFlag) ? -1 : 1; double sign = (largeArcFlag == sweepFlag) ? -1 : 1;
double sq = ((Prx * Pry) - (Prx * Py1) - (Pry * Px1)) / ((Prx * Py1) + (Pry * Px1)); double sq = ((Prx * Pry) - (Prx * Py1) - (Pry * Px1)) / ((Prx * Py1) + (Pry * Px1));
sq = (sq < 0) ? 0 : sq; sq = (sq < 0) ? 0 : sq;
double coef = (sign * Math.sqrt(sq)); double coef = (sign * Math.sqrt(sq));
double cx1 = coef * ((rx * y1) / ry); double cx1 = coef * ((rx * y1) / ry);
double cy1 = coef * -((ry * x1) / rx); double cy1 = coef * -((ry * x1) / rx);
//
// Step 3 : Compute (cx, cy) from (cx1, cy1)
//
double sx2 = (x0 + x) / 2.0; double sx2 = (x0 + x) / 2.0;
double sy2 = (y0 + y) / 2.0; double sy2 = (y0 + y) / 2.0;
double cx = sx2 + (cosAngle * cx1 - sinAngle * cy1); double cx = sx2 + (cosAngle * cx1 - sinAngle * cy1);
double cy = sy2 + (sinAngle * cx1 + cosAngle * cy1); double cy = sy2 + (sinAngle * cx1 + cosAngle * cy1);
//
// Step 4 : Compute the angleStart (angle1) and the angleExtent (dangle)
//
double ux = (x1 - cx1) / rx; double ux = (x1 - cx1) / rx;
double uy = (y1 - cy1) / ry; double uy = (y1 - cy1) / ry;
double vx = (-x1 - cx1) / rx; double vx = (-x1 - cx1) / rx;
double vy = (-y1 - cy1) / ry; double vy = (-y1 - cy1) / ry;
double p, n; double p, n;
// Compute the angle start
n = Math.sqrt((ux * ux) + (uy * uy)); n = Math.sqrt((ux * ux) + (uy * uy));
p = ux; // (1 * ux) + (0 * uy) p = ux;
sign = (uy < 0) ? -1d : 1d; sign = (uy < 0) ? -1d : 1d;
double angleStart = Math.toDegrees(sign * Math.acos(p / n)); double angleStart = Math.toDegrees(sign * Math.acos(p / n));
// Compute the angle extent
n = Math.sqrt((ux * ux + uy * uy) * (vx * vx + vy * vy)); n = Math.sqrt((ux * ux + uy * uy) * (vx * vx + vy * vy));
p = ux * vx + uy * vy; p = ux * vx + uy * vy;
sign = (ux * vy - uy * vx < 0) ? -1d : 1d; sign = (ux * vy - uy * vx < 0) ? -1d : 1d;
@ -252,10 +126,6 @@ public class Arc extends PathCommand {
} }
angleExtent %= 360f; angleExtent %= 360f;
angleStart %= 360f; angleStart %= 360f;
//
// We can now build the resulting Arc2D in double precision
//
Arc2D.Double arc = new Arc2D.Double(); Arc2D.Double arc = new Arc2D.Double();
arc.x = cx - rx; arc.x = cx - rx;
arc.y = cy - ry; arc.y = cy - ry;
@ -263,7 +133,6 @@ public class Arc extends PathCommand {
arc.height = ry * 2.0; arc.height = ry * 2.0;
arc.start = -angleStart; arc.start = -angleStart;
arc.extent = -angleExtent; arc.extent = -angleExtent;
return arc; return arc;
} }

View file

@ -1,64 +1,13 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on January 26, 2004, 9:18 PM
*/
package org.xbib.graphics.svg.pathcmd; package org.xbib.graphics.svg.pathcmd;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
/**
* When building a path from command segments, most need to cache information
* (such as the point finished at) for future commands. This structure allows
* that
*
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class BuildHistory { public class BuildHistory {
// Point2D.Float[] history = new Point2D.Float[2];
// Point2D.Float[] history = {new Point2D.Float(), new Point2D.Float()};
// Point2D.Float start = new Point2D.Float();
Point2D.Float startPoint = new Point2D.Float(); Point2D.Float startPoint = new Point2D.Float();
Point2D.Float lastPoint = new Point2D.Float(); Point2D.Float lastPoint = new Point2D.Float();
Point2D.Float lastKnot = new Point2D.Float(); Point2D.Float lastKnot = new Point2D.Float();
boolean init;
//int length = 0;
/**
* Creates a new instance of BuildHistory
*/
public BuildHistory() { public BuildHistory() {
} }
@ -73,19 +22,4 @@ public class BuildHistory {
public void setLastKnot(float x, float y) { public void setLastKnot(float x, float y) {
lastKnot.setLocation(x, y); lastKnot.setLocation(x, y);
} }
// public void setPoint(float x, float y)
// {
// history[0].setLocation(x, y);
// length = 1;
// }
// public void setStart(float x, float y)
// {
// start.setLocation(x, y);
// }
// public void setPointAndKnot(float x, float y, float kx, float ky)
// {
// history[0].setLocation(x, y);
// history[1].setLocation(kx, ky);
// length = 2;
// }
} }

View file

@ -1,49 +1,7 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on January 26, 2004, 8:40 PM
*/
package org.xbib.graphics.svg.pathcmd; package org.xbib.graphics.svg.pathcmd;
//import org.apache.batik.ext.awt.geom.ExtendedGeneralPath;
import java.awt.geom.GeneralPath; import java.awt.geom.GeneralPath;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class Cubic extends PathCommand { public class Cubic extends PathCommand {
public float k1x = 0f; public float k1x = 0f;
@ -53,19 +11,9 @@ public class Cubic extends PathCommand {
public float x = 0f; public float x = 0f;
public float y = 0f; public float y = 0f;
/**
* Creates a new instance of MoveTo
*/
public Cubic() { public Cubic() {
} }
@Override
public String toString() {
return "C " + k1x + " " + k1y
+ " " + k2x + " " + k2y
+ " " + x + " " + y;
}
public Cubic(boolean isRelative, float k1x, float k1y, float k2x, float k2y, float x, float y) { public Cubic(boolean isRelative, float k1x, float k1y, float k2x, float k2y, float x, float y) {
super(isRelative); super(isRelative);
this.k1x = k1x; this.k1x = k1x;
@ -76,16 +24,13 @@ public class Cubic extends PathCommand {
this.y = y; this.y = y;
} }
// public void appendPath(ExtendedGeneralPath path, BuildHistory hist)
@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.lastPoint.x : 0f;
float offy = isRelative ? hist.lastPoint.y : 0f; float offy = isRelative ? hist.lastPoint.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);
// hist.setPointAndKnot(x + offx, y + offy, k2x + offx, k2y + offy);
hist.setLastPoint(x + offx, y + offy); hist.setLastPoint(x + offx, y + offy);
hist.setLastKnot(k2x + offx, k2y + offy); hist.setLastKnot(k2x + offx, k2y + offy);
} }
@ -94,4 +39,11 @@ public class Cubic extends PathCommand {
public int getNumKnotsAdded() { public int getNumKnotsAdded() {
return 6; return 6;
} }
@Override
public String toString() {
return "C " + k1x + " " + k1y
+ " " + k2x + " " + k2y
+ " " + x + " " + y;
}
} }

View file

@ -1,59 +1,17 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on January 26, 2004, 8:40 PM
*/
package org.xbib.graphics.svg.pathcmd; package org.xbib.graphics.svg.pathcmd;
//import org.apache.batik.ext.awt.geom.ExtendedGeneralPath;
import java.awt.geom.GeneralPath; import java.awt.geom.GeneralPath;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class CubicSmooth extends PathCommand { public class CubicSmooth extends PathCommand {
public float x = 0f; public float x = 0f;
public float y = 0f; public float y = 0f;
public float k2x = 0f; public float k2x = 0f;
public float k2y = 0f; public float k2y = 0f;
/**
* Creates a new instance of MoveTo
*/
public CubicSmooth() { public CubicSmooth() {
} }
@ -65,20 +23,16 @@ public class CubicSmooth extends PathCommand {
this.y = y; this.y = y;
} }
// public void appendPath(ExtendedGeneralPath path, BuildHistory hist)
@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.lastPoint.x : 0f;
float offy = isRelative ? hist.lastPoint.y : 0f; float offy = isRelative ? hist.lastPoint.y : 0f;
float oldKx = hist.lastKnot.x; float oldKx = hist.lastKnot.x;
float oldKy = hist.lastKnot.y; float oldKy = hist.lastKnot.y;
float oldX = hist.lastPoint.x; float oldX = hist.lastPoint.x;
float oldY = hist.lastPoint.y; float oldY = hist.lastPoint.y;
//Calc knot as reflection of old knot
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);
hist.setLastPoint(x + offx, y + offy); hist.setLastPoint(x + offx, y + offy);
hist.setLastKnot(k2x + offx, k2y + offy); hist.setLastKnot(k2x + offx, k2y + offy);

View file

@ -1,56 +1,11 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on January 26, 2004, 8:40 PM
*/
package org.xbib.graphics.svg.pathcmd; package org.xbib.graphics.svg.pathcmd;
//import org.apache.batik.ext.awt.geom.ExtendedGeneralPath;
import java.awt.geom.GeneralPath; import java.awt.geom.GeneralPath;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class Horizontal extends PathCommand { public class Horizontal extends PathCommand {
public float x = 0f; public float x = 0f;
/**
* Creates a new instance of MoveTo
*/
public Horizontal() { public Horizontal() {
} }
@ -64,13 +19,10 @@ public class Horizontal extends PathCommand {
this.x = x; this.x = x;
} }
// public void appendPath(ExtendedGeneralPath path, BuildHistory hist)
@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.lastPoint.x : 0f;
float offy = hist.lastPoint.y; float offy = hist.lastPoint.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);

View file

@ -1,57 +1,12 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on January 26, 2004, 8:40 PM
*/
package org.xbib.graphics.svg.pathcmd; package org.xbib.graphics.svg.pathcmd;
//import org.apache.batik.ext.awt.geom.ExtendedGeneralPath;
import java.awt.geom.GeneralPath; import java.awt.geom.GeneralPath;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class LineTo extends PathCommand { public class LineTo extends PathCommand {
public float x = 0f; public float x = 0f;
public float y = 0f; public float y = 0f;
/**
* Creates a new instance of MoveTo
*/
public LineTo() { public LineTo() {
} }
@ -61,13 +16,10 @@ public class LineTo extends PathCommand {
this.y = y; this.y = y;
} }
// public void appendPath(ExtendedGeneralPath path, BuildHistory hist)
@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.lastPoint.x : 0f;
float offy = isRelative ? hist.lastPoint.y : 0f; float offy = isRelative ? hist.lastPoint.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

@ -1,57 +1,13 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on January 26, 2004, 8:40 PM
*/
package org.xbib.graphics.svg.pathcmd; package org.xbib.graphics.svg.pathcmd;
//import org.apache.batik.ext.awt.geom.ExtendedGeneralPath;
import java.awt.geom.GeneralPath; import java.awt.geom.GeneralPath;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class MoveTo extends PathCommand { public class MoveTo extends PathCommand {
public float x = 0f; public float x = 0f;
public float y = 0f; public float y = 0f;
/**
* Creates a new instance of MoveTo
*/
public MoveTo() { public MoveTo() {
} }
@ -61,12 +17,10 @@ public class MoveTo extends PathCommand {
this.y = y; this.y = y;
} }
// public void appendPath(ExtendedGeneralPath path, BuildHistory hist)
@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.lastPoint.x : 0f;
float offy = isRelative ? hist.lastPoint.y : 0f; float offy = isRelative ? hist.lastPoint.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);
@ -82,6 +36,4 @@ public class MoveTo extends PathCommand {
public String toString() { public String toString() {
return "M " + x + " " + y; return "M " + x + " " + y;
} }
} }

View file

@ -1,59 +1,11 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on January 26, 2004, 8:39 PM
*/
package org.xbib.graphics.svg.pathcmd; package org.xbib.graphics.svg.pathcmd;
//import org.apache.batik.ext.awt.geom.ExtendedGeneralPath;
import java.awt.geom.GeneralPath; import java.awt.geom.GeneralPath;
/**
* This is the element of a path and contains instructions for rendering a
* portion of the path
*
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
abstract public class PathCommand { abstract public class PathCommand {
public boolean isRelative = false; public boolean isRelative = false;
/**
* Creates a new instance of PathCommand
*/
public PathCommand() { public PathCommand() {
} }
@ -61,7 +13,6 @@ abstract public class PathCommand {
this.isRelative = isRelative; this.isRelative = isRelative;
} }
// abstract public void appendPath(ExtendedGeneralPath path, BuildHistory hist);
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,51 +1,16 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
*/
package org.xbib.graphics.svg.pathcmd; package org.xbib.graphics.svg.pathcmd;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/**
* A helper for parsing {@link PathCommand}s.
*
* @author Jannis Weis
*/
public class PathParser { public class PathParser {
private final String input; private final String input;
private final int inputLength; private final int inputLength;
private int index; private int index;
private char currentCommand; private char currentCommand;
public PathParser(String input) { public PathParser(String input) {
@ -73,13 +38,9 @@ public class PathParser {
return index < inputLength; return index < inputLength;
} }
// This only checks for the rough structure of a number as we need to know
// when to separate the next token.
// Explicit parsing is done by Float#parseFloat.
private boolean isValidNumberChar(char c, NumberCharState state) { private boolean isValidNumberChar(char c, NumberCharState state) {
boolean valid = '0' <= c && c <= '9'; boolean valid = '0' <= c && c <= '9';
if (valid && state.iteration == 1 && input.charAt(index - 1) == '0') { if (valid && state.iteration == 1 && input.charAt(index - 1) == '0') {
// Break up combined zeros into multiple numbers.
return false; return false;
} }
state.signAllowed = state.signAllowed && !valid; state.signAllowed = state.signAllowed && !valid;
@ -92,7 +53,6 @@ public class PathParser {
state.signAllowed = valid; state.signAllowed = valid;
} }
if (state.exponentAllowed && !valid) { if (state.exponentAllowed && !valid) {
// Possible exponent notation. Needs at least one preceding number
valid = c == 'e' || c == 'E'; valid = c == 'e' || c == 'E';
state.exponentAllowed = !valid; state.exponentAllowed = !valid;
state.signAllowed = valid; state.signAllowed = valid;
@ -128,7 +88,6 @@ public class PathParser {
public PathCommand[] parsePathCommand() { public PathCommand[] parsePathCommand() {
List<PathCommand> commands = new ArrayList<>(); List<PathCommand> commands = new ArrayList<>();
currentCommand = 'Z'; currentCommand = 'Z';
while (hasNext()) { while (hasNext()) {
char peekChar = peek(); char peekChar = peek();
@ -137,7 +96,6 @@ public class PathParser {
currentCommand = peekChar; currentCommand = peekChar;
} }
consumeWhiteSpaceOrSeparator(); consumeWhiteSpaceOrSeparator();
PathCommand cmd; PathCommand cmd;
switch (currentCommand) { switch (currentCommand) {
case 'M': case 'M':

View file

@ -1,70 +1,19 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on May 10, 2005, 5:56 AM
*/
package org.xbib.graphics.svg.pathcmd; package org.xbib.graphics.svg.pathcmd;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath; import java.awt.geom.GeneralPath;
import java.awt.geom.PathIterator; import java.awt.geom.PathIterator;
/**
* @author kitfox
*/
public class PathUtil { public class PathUtil {
/**
* Creates a new instance of PathUtil
*/
public PathUtil() { public PathUtil() {
} }
/**
* Converts a GeneralPath into an SVG representation
*
* @param path The shape to be encoded
* @return A string encoding the path using the SVG path notation
*/
public static String buildPathString(GeneralPath path) { public static String buildPathString(GeneralPath path) {
float[] coords = new float[6]; float[] coords = new float[6];
StringBuilder sb = new StringBuilder();
StringBuffer sb = new StringBuffer();
for (PathIterator pathIt = path.getPathIterator(new AffineTransform()); !pathIt.isDone(); pathIt.next()) { for (PathIterator pathIt = path.getPathIterator(new AffineTransform()); !pathIt.isDone(); pathIt.next()) {
int segId = pathIt.currentSegment(coords); int segId = pathIt.currentSegment(coords);
switch (segId) { switch (segId) {
case PathIterator.SEG_CLOSE: { case PathIterator.SEG_CLOSE: {
sb.append(" Z"); sb.append(" Z");
@ -88,7 +37,6 @@ public class PathUtil {
} }
} }
} }
return sb.toString(); return sb.toString();
} }
} }

View file

@ -1,68 +1,20 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on January 26, 2004, 8:40 PM
*/
package org.xbib.graphics.svg.pathcmd; package org.xbib.graphics.svg.pathcmd;
//import org.apache.batik.ext.awt.geom.ExtendedGeneralPath;
import java.awt.geom.GeneralPath; import java.awt.geom.GeneralPath;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class Quadratic extends PathCommand { public class Quadratic extends PathCommand {
public float kx = 0f; public float kx = 0f;
public float ky = 0f; public float ky = 0f;
public float x = 0f; public float x = 0f;
public float y = 0f; public float y = 0f;
/**
* Creates a new instance of MoveTo
*/
public Quadratic() { public Quadratic() {
} }
@Override
public String toString() {
return "Q " + kx + " " + ky
+ " " + x + " " + y;
}
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);
this.kx = kx; this.kx = kx;
@ -71,12 +23,10 @@ public class Quadratic extends PathCommand {
this.y = y; this.y = y;
} }
// public void appendPath(ExtendedGeneralPath path, BuildHistory hist)
@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.lastPoint.x : 0f;
float offy = isRelative ? hist.lastPoint.y : 0f; float offy = isRelative ? hist.lastPoint.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);
@ -86,4 +36,10 @@ public class Quadratic extends PathCommand {
public int getNumKnotsAdded() { public int getNumKnotsAdded() {
return 4; return 4;
} }
@Override
public String toString() {
return "Q " + kx + " " + ky
+ " " + x + " " + y;
}
} }

View file

@ -1,57 +1,13 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on January 26, 2004, 8:40 PM
*/
package org.xbib.graphics.svg.pathcmd; package org.xbib.graphics.svg.pathcmd;
//import org.apache.batik.ext.awt.geom.ExtendedGeneralPath;
import java.awt.geom.GeneralPath; import java.awt.geom.GeneralPath;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class QuadraticSmooth extends PathCommand { public class QuadraticSmooth extends PathCommand {
public float x = 0f; public float x = 0f;
public float y = 0f; public float y = 0f;
/**
* Creates a new instance of MoveTo
*/
public QuadraticSmooth() { public QuadraticSmooth() {
} }
@ -66,20 +22,16 @@ public class QuadraticSmooth extends PathCommand {
this.y = y; this.y = y;
} }
// public void appendPath(ExtendedGeneralPath path, BuildHistory hist)
@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.lastPoint.x : 0f;
float offy = isRelative ? hist.lastPoint.y : 0f; float offy = isRelative ? hist.lastPoint.y : 0f;
float oldKx = hist.lastKnot.x; float oldKx = hist.lastKnot.x;
float oldKy = hist.lastKnot.y; float oldKy = hist.lastKnot.y;
float oldX = hist.lastPoint.x; float oldX = hist.lastPoint.x;
float oldY = hist.lastPoint.y; float oldY = hist.lastPoint.y;
//Calc knot as reflection of old knot
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);
hist.setLastPoint(x + offx, y + offy); hist.setLastPoint(x + offx, y + offy);
hist.setLastKnot(kx, ky); hist.setLastKnot(kx, ky);

View file

@ -1,56 +1,9 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on January 26, 2004, 8:40 PM
*/
package org.xbib.graphics.svg.pathcmd; package org.xbib.graphics.svg.pathcmd;
//import org.apache.batik.ext.awt.geom.ExtendedGeneralPath;
import java.awt.geom.GeneralPath; import java.awt.geom.GeneralPath;
/**
* Finishes a path
*
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class Terminal extends PathCommand { public class Terminal extends PathCommand {
/**
* Creates a new instance of MoveTo
*/
public Terminal() { public Terminal() {
} }
@ -59,8 +12,6 @@ public class Terminal extends PathCommand {
return "Z"; return "Z";
} }
// public void appendPath(ExtendedGeneralPath path, BuildHistory hist)
@Override @Override
public void appendPath(GeneralPath path, BuildHistory hist) { public void appendPath(GeneralPath path, BuildHistory hist) {
path.closePath(); path.closePath();

View file

@ -1,56 +1,11 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on January 26, 2004, 8:40 PM
*/
package org.xbib.graphics.svg.pathcmd; package org.xbib.graphics.svg.pathcmd;
//import org.apache.batik.ext.awt.geom.ExtendedGeneralPath;
import java.awt.geom.GeneralPath; import java.awt.geom.GeneralPath;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class Vertical extends PathCommand { public class Vertical extends PathCommand {
public float y = 0f; public float y = 0f;
/**
* Creates a new instance of MoveTo
*/
public Vertical() { public Vertical() {
} }
@ -64,12 +19,10 @@ public class Vertical extends PathCommand {
this.y = y; this.y = y;
} }
// public void appendPath(ExtendedGeneralPath path, BuildHistory hist)
@Override @Override
public void appendPath(GeneralPath path, BuildHistory hist) { public void appendPath(GeneralPath path, BuildHistory hist) {
float offx = hist.lastPoint.x; float offx = hist.lastPoint.x;
float offy = isRelative ? hist.lastPoint.y : 0f; float offy = isRelative ? hist.lastPoint.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);

View file

@ -1,72 +0,0 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on April 1, 2004, 3:37 AM
*/
package org.xbib.graphics.svg.pattern;
import java.awt.Paint;
import java.awt.PaintContext;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class PatternPaint implements Paint {
BufferedImage source; //Image we're rendering from
AffineTransform xform;
/**
* Creates a new instance of PatternPaint
*/
public PatternPaint(BufferedImage source, AffineTransform xform) {
this.source = source;
this.xform = xform;
}
public PaintContext createContext(ColorModel cm, Rectangle deviceBounds, Rectangle2D userBounds, AffineTransform xform, RenderingHints hints) {
return new PatternPaintContext(source, deviceBounds, xform, this.xform);
}
public int getTransparency() {
return source.getColorModel().getTransparency();
}
}

View file

@ -1,133 +0,0 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on April 1, 2004, 3:37 AM
*/
package org.xbib.graphics.svg.pattern;
import org.xbib.graphics.svg.SVGConst;
import java.awt.PaintContext;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* @author Mark McKay
* @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
*/
public class PatternPaintContext implements PaintContext {
BufferedImage source; //Image we're rendering from
Rectangle deviceBounds; //int size of rectangle we're rendering to
// AffineTransform userXform; //xform from user space to device space
// AffineTransform distortXform; //distortion applied to this pattern
AffineTransform xform; //distortion applied to this pattern
int sourceWidth;
int sourceHeight;
//Raster we use to build tile
BufferedImage buf;
/**
* Creates a new instance of PatternPaintContext
*/
public PatternPaintContext(BufferedImage source, Rectangle deviceBounds, AffineTransform userXform, AffineTransform distortXform) {
//System.err.println("Bounds " + deviceBounds);
this.source = source;
this.deviceBounds = deviceBounds;
try {
// this.distortXform = distortXform.createInverse();
// this.userXform = userXform.createInverse();
// xform = userXform.createInverse();
// xform.concatenate(distortXform.createInverse());
xform = distortXform.createInverse();
xform.concatenate(userXform.createInverse());
} catch (Exception e) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, null, e);
}
sourceWidth = source.getWidth();
sourceHeight = source.getHeight();
}
public void dispose() {
}
public ColorModel getColorModel() {
return source.getColorModel();
}
public Raster getRaster(int x, int y, int w, int h) {
//System.err.println("" + x + ", " + y + ", " + w + ", " + h);
if (buf == null || buf.getWidth() != w || buf.getHeight() != h) {
buf = new BufferedImage(w, h, source.getType());
}
// Point2D.Float srcPt = new Point2D.Float(), srcPt2 = new Point2D.Float(), destPt = new Point2D.Float();
Point2D.Float srcPt = new Point2D.Float(), destPt = new Point2D.Float();
for (int j = 0; j < h; j++) {
for (int i = 0; i < w; i++) {
destPt.setLocation(i + x, j + y);
xform.transform(destPt, srcPt);
// userXform.transform(destPt, srcPt2);
// distortXform.transform(srcPt2, srcPt);
int ii = ((int) srcPt.x) % sourceWidth;
if (ii < 0) ii += sourceWidth;
int jj = ((int) srcPt.y) % sourceHeight;
if (jj < 0) jj += sourceHeight;
buf.setRGB(i, j, source.getRGB(ii, jj));
}
}
return buf.getData();
}
public static void main(String[] argv) {
int i = -4;
System.err.println("Hello " + (i % 4));
}
}

View file

@ -1,41 +1,9 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*/
package org.xbib.graphics.svg.util; package org.xbib.graphics.svg.util;
import org.xbib.graphics.svg.Font; import org.xbib.graphics.svg.element.Font;
import org.xbib.graphics.svg.FontSystem;
import org.xbib.graphics.svg.SVGDiagram; import org.xbib.graphics.svg.SVGDiagram;
import org.xbib.graphics.svg.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.Text;
import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.StyleAttribute;
@ -45,17 +13,16 @@ import java.util.Objects;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
/**
* Utility class for parsing font information of an {@link SVGElement}.
*
* @author Jannis Weis
*/
public final class FontUtil { public final class FontUtil {
private static final String DEFAULT_FONT_FAMILY = "sans-serif"; private static final String DEFAULT_FONT_FAMILY = "sans-serif";
private static final float DEFAULT_FONT_SIZE = 12f; private static final float DEFAULT_FONT_SIZE = 12f;
private static final int DEFAULT_LETTER_SPACING = 0; private static final int DEFAULT_LETTER_SPACING = 0;
private static final int DEFAULT_FONT_STYLE = Text.TXST_NORMAL; private static final int DEFAULT_FONT_STYLE = Text.TXST_NORMAL;
private static final int DEFAULT_FONT_WEIGHT = Text.TXWE_NORMAL; private static final int DEFAULT_FONT_WEIGHT = Text.TXWE_NORMAL;
private FontUtil() { private FontUtil() {
@ -78,8 +45,12 @@ public final class FontUtil {
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) {
if (!(o instanceof FontInfo)) return false; return true;
}
if (!(o instanceof FontInfo)) {
return false;
}
FontInfo fontInfo = (FontInfo) o; FontInfo fontInfo = (FontInfo) o;
return Float.compare(fontInfo.size, size) == 0 return Float.compare(fontInfo.size, size) == 0
&& style == fontInfo.style && weight == fontInfo.weight && style == fontInfo.style && weight == fontInfo.weight
@ -100,17 +71,14 @@ public final class FontUtil {
if (element.getStyle(sty.setName("font-family"))) { if (element.getStyle(sty.setName("font-family"))) {
fontFamily = sty.getStringValue(); fontFamily = sty.getStringValue();
} }
float fontSize = DEFAULT_FONT_SIZE; float fontSize = DEFAULT_FONT_SIZE;
if (element.getStyle(sty.setName("font-size"))) { if (element.getStyle(sty.setName("font-size"))) {
fontSize = sty.getFloatValueWithUnits(); fontSize = sty.getFloatValueWithUnits();
} }
float letterSpacing = DEFAULT_LETTER_SPACING; float letterSpacing = DEFAULT_LETTER_SPACING;
if (element.getStyle(sty.setName("letter-spacing"))) { if (element.getStyle(sty.setName("letter-spacing"))) {
letterSpacing = sty.getFloatValueWithUnits(); letterSpacing = sty.getFloatValueWithUnits();
} }
int fontStyle = DEFAULT_FONT_STYLE; int fontStyle = DEFAULT_FONT_STYLE;
if (element.getStyle(sty.setName("font-style"))) { if (element.getStyle(sty.setName("font-style"))) {
String s = sty.getStringValue(); String s = sty.getStringValue();
@ -122,7 +90,6 @@ public final class FontUtil {
fontStyle = Text.TXST_OBLIQUE; fontStyle = Text.TXST_OBLIQUE;
} }
} }
int fontWeight = DEFAULT_FONT_WEIGHT; int fontWeight = DEFAULT_FONT_WEIGHT;
if (element.getStyle(sty.setName("font-weight"))) { if (element.getStyle(sty.setName("font-weight"))) {
String s = sty.getStringValue(); String s = sty.getStringValue();
@ -132,7 +99,6 @@ public final class FontUtil {
fontWeight = Text.TXWE_BOLD; fontWeight = Text.TXWE_BOLD;
} }
} }
return new FontInfo(fontFamily.split(","), fontSize, fontStyle, fontWeight, letterSpacing); return new FontInfo(fontFamily.split(","), fontSize, fontStyle, fontWeight, letterSpacing);
} }
@ -147,7 +113,6 @@ public final class FontUtil {
if (font != null) break; if (font != null) break;
} }
if (font == null) { if (font == null) {
//Check system fonts
font = FontSystem.createFont(families, fontStyle, fontWeight, fontSize); font = FontSystem.createFont(families, fontStyle, fontWeight, fontSize);
} }
if (font == null) { if (font == null) {

View file

@ -0,0 +1,38 @@
package org.xbib.graphics.svg.util;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
public class PaintCache {
private final BufferedImage img;
private final Rectangle bounds;
private final AffineTransform transform;
public PaintCache(BufferedImage img, Rectangle bounds, AffineTransform transform) {
this.img = img;
this.bounds = bounds;
this.transform = transform;
}
public BufferedImage getImage() {
return img;
}
public boolean isCompatible(AffineTransform tx) {
return tx.getScaleX() == transform.getScaleX()
&& tx.getScaleY() == transform.getScaleY()
&& tx.getShearX() == transform.getShearX()
&& tx.getShearY() == transform.getShearY();
}
public Rectangle getBoundsForTransform(AffineTransform tx) {
double dx = tx.getTranslateX() - transform.getTranslateX();
double dy = tx.getTranslateY() - transform.getTranslateY();
return new Rectangle((int) (bounds.x + dx), (int) (bounds.y + dy),
bounds.width, bounds.height);
}
}

View file

@ -1,4 +1,8 @@
package org.xbib.graphics.svg; package org.xbib.graphics.svg.util;
import org.xbib.graphics.svg.element.filtereffects.FilterOp;
import org.xbib.graphics.svg.element.RenderableElement;
import org.xbib.graphics.svg.SVGException;
import java.awt.Color; import java.awt.Color;
import java.awt.Graphics2D; import java.awt.Graphics2D;
@ -12,35 +16,10 @@ import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class BufferPainter { public class PaintUtil {
public static final boolean DEBUG_PAINT = false; public static final boolean DEBUG_PAINT = false;
public static class Cache {
private final BufferedImage img;
private final Rectangle bounds;
private final AffineTransform transform;
public Cache(BufferedImage img, Rectangle bounds, AffineTransform transform) {
this.img = img;
this.bounds = bounds;
this.transform = transform;
}
boolean isCompatible(AffineTransform tx) {
return tx.getScaleX() == transform.getScaleX()
&& tx.getScaleY() == transform.getScaleY()
&& tx.getShearX() == transform.getShearX()
&& tx.getShearY() == transform.getShearY();
}
Rectangle getBoundsForTransform(AffineTransform tx) {
double dx = tx.getTranslateX() - transform.getTranslateX();
double dy = tx.getTranslateY() - transform.getTranslateY();
return new Rectangle((int) (bounds.x + dx), (int) (bounds.y + dy),
bounds.width, bounds.height);
}
}
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.cachedMask != null
|| (element.filter != null && !element.filter.filterEffects.isEmpty())) { || (element.filter != null && !element.filter.filterEffects.isEmpty())) {
@ -64,12 +43,12 @@ public class BufferPainter {
Rectangle elementBounds = element.getBoundingBox().getBounds(); Rectangle elementBounds = element.getBoundingBox().getBounds();
Rectangle transformedBounds = transform.createTransformedShape(elementBounds).getBounds(); Rectangle transformedBounds = transform.createTransformedShape(elementBounds).getBounds();
Rectangle dstBounds = new Rectangle(transformedBounds); Rectangle dstBounds = new Rectangle(transformedBounds);
Cache cache = element.getBufferCache(); PaintCache cache = element.getBufferCache();
BufferedImage elementImage; BufferedImage elementImage;
if (cache == null || !cache.isCompatible(transform)) { if (cache == null || !cache.isCompatible(transform)) {
elementImage = renderToBuffer(gg, element, transform, transformedBounds, dstBounds); elementImage = renderToBuffer(gg, element, transform, transformedBounds, dstBounds);
} else { } else {
elementImage = cache.img; elementImage = cache.getImage();
dstBounds.setBounds(cache.getBoundsForTransform(transform)); dstBounds.setBounds(cache.getBoundsForTransform(transform));
} }
gg.setTransform(new AffineTransform()); gg.setTransform(new AffineTransform());
@ -90,22 +69,17 @@ public class BufferPainter {
Rectangle dstBounds) throws SVGException, IOException { Rectangle dstBounds) throws SVGException, IOException {
Point2D.Float origin = new Point2D.Float(0, 0); Point2D.Float origin = new Point2D.Float(0, 0);
transform.transform(origin, origin); transform.transform(origin, origin);
// As filter operations are commonly implemented using convolutions they need to be
// aware of any possible scaling to compensate for it in their kernel size.
Point2D.Float testPoint = new Point2D.Float(1, 0); Point2D.Float testPoint = new Point2D.Float(1, 0);
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<FilterEffects.FilterOp> filterOps = element.filter == null
? Collections.emptyList() ? Collections.emptyList()
: element.filter.filterEffects.stream() : element.filter.filterEffects.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 (FilterEffects.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.requiredImageBounds.x + filterOp.requiredImageBounds.width);
int bottom = Math.max(dstBounds.y + dstBounds.height, int bottom = Math.max(dstBounds.y + dstBounds.height,
@ -115,17 +89,13 @@ public class BufferPainter {
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 = BufferPainter.paintToBuffer(gg, transform, dstBounds, transformedBounds,
element, null, true); element, null, true);
for (FilterOp filterOp : filterOps) {
for (FilterEffects.FilterOp filterOp : filterOps) {
elementImage = filterOp.op.filter(elementImage, null); elementImage = filterOp.op.filter(elementImage, null);
} }
if (element.cachedMask != null) { if (element.cachedMask != null) {
BufferedImage maskImage = BufferPainter.paintToBuffer(gg, transform, dstBounds, transformedBounds, BufferedImage maskImage = PaintUtil.paintToBuffer(gg, transform, dstBounds, transformedBounds,
element.cachedMask, Color.BLACK, false); element.cachedMask, Color.BLACK, false);
Graphics2D elementGraphics = (Graphics2D) elementImage.getGraphics(); Graphics2D elementGraphics = (Graphics2D) elementImage.getGraphics();
elementGraphics.setRenderingHints(gg.getRenderingHints()); elementGraphics.setRenderingHints(gg.getRenderingHints());

View file

@ -1,43 +0,0 @@
/*
* SVG Salamander
* Copyright (c) 2004, Mark McKay
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Mark McKay can be contacted at mark@kitfox.com. Salamander and other
* projects can be found at http://www.kitfox.com
*
* Created on April 24, 2015
*/
package org.xbib.graphics.svg.util;
/**
* @author kitfox
*/
public class TextBuilder {
}

View file

@ -1,7 +1,5 @@
package org.xbib.graphics.svg.xml; package org.xbib.graphics.svg.xml;
import org.xbib.graphics.svg.SVGConst;
import java.awt.Color; import java.awt.Color;
import java.awt.HeadlessException; import java.awt.HeadlessException;
import java.awt.Toolkit; import java.awt.Toolkit;
@ -15,16 +13,16 @@ import java.util.regex.Pattern;
public class StyleAttribute { public class StyleAttribute {
private static final Logger logger = Logger.getLogger(StyleAttribute.class.getName());
static final Pattern patternUrl = Pattern.compile("\\s*url\\((.*)\\)\\s*"); static final Pattern patternUrl = Pattern.compile("\\s*url\\((.*)\\)\\s*");
static final Matcher matchFpNumUnits = Pattern.compile("\\s*([-+]?((\\d*\\.\\d+)|(\\d+))([-+]?[eE]\\d+)?)\\s*(px|cm|mm|in|pc|pt|em|ex)\\s*").matcher(""); static final Matcher matchFpNumUnits = Pattern.compile("\\s*([-+]?((\\d*\\.\\d+)|(\\d+))([-+]?[eE]\\d+)?)\\s*(px|cm|mm|in|pc|pt|em|ex)\\s*").matcher("");
String name; String name;
String stringValue; String stringValue;
/**
* Creates a new instance of StyleAttribute
*/
public StyleAttribute() { public StyleAttribute() {
this(null, null); this(null, null);
} }
@ -161,19 +159,7 @@ public class StyleAttribute {
try { try {
return new URL(docRoot, fragment); return new URL(docRoot, fragment);
} catch (Exception e) { } catch (Exception e) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, null, e); logger.log(Level.WARNING, null, e);
return null;
}
}
public URL getURLValue(URI docRoot) {
String fragment = parseURLFn();
if (fragment == null) return null;
try {
URI ref = docRoot.resolve(fragment);
return ref.toURL();
} catch (Exception e) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, null, e);
return null; return null;
} }
} }
@ -206,7 +192,7 @@ public class StyleAttribute {
} }
return new URI(base.getScheme() + ":" + relUri); return new URI(base.getScheme() + ":" + relUri);
} catch (Exception e) { } catch (Exception e) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, null, e); logger.log(Level.WARNING, null, e);
return null; return null;
} }
} }

View file

@ -1,18 +1,13 @@
package org.xbib.graphics.svg.xml; package org.xbib.graphics.svg.xml;
import org.xbib.graphics.svg.SVGConst;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
public class StyleSheet { public class StyleSheet {
Map<StyleSheetRule, String> ruleMap = new HashMap<>(); Map<StyleSheetRule, String> ruleMap = new HashMap<>();
public static StyleSheet parseSheet(String src) { public static StyleSheet parseSheet(String src) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, "CSS parser not implemented yet");
return null; return null;
} }

View file

@ -1,7 +1,5 @@
package org.xbib.graphics.svg.xml; package org.xbib.graphics.svg.xml;
import org.xbib.graphics.svg.SVGConst;
import java.awt.Toolkit; import java.awt.Toolkit;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
@ -14,7 +12,9 @@ import java.util.regex.Pattern;
public class XMLParseUtil { public class XMLParseUtil {
static final Matcher fpMatch = Pattern.compile("([-+]?((\\d*\\.\\d+)|(\\d+))([eE][+-]?\\d+)?)(\\%|in|cm|mm|pt|pc|px|em|ex)?").matcher(""); private static final Logger logger = Logger.getLogger(XMLParseUtil.class.getName());
static final Matcher fpMatch = Pattern.compile("([-+]?((\\d*\\.\\d+)|(\\d+))([eE][+-]?\\d+)?)(%|in|cm|mm|pt|pc|px|em|ex)?").matcher("");
static final Matcher intMatch = Pattern.compile("[-+]?\\d+").matcher(""); static final Matcher intMatch = Pattern.compile("[-+]?\\d+").matcher("");
@ -48,7 +48,7 @@ public class XMLParseUtil {
return 0; return 0;
} }
} catch (StringIndexOutOfBoundsException e) { } catch (StringIndexOutOfBoundsException e) {
Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, logger.log(Level.WARNING,
"XMLParseUtil: regex parse problem: '" + val + "'", e); "XMLParseUtil: regex parse problem: '" + val + "'", e);
} }
val = fpMatch.group(1); val = fpMatch.group(1);
@ -188,13 +188,14 @@ public class XMLParseUtil {
} }
public static NumberWithUnits parseNumberWithUnits(String val) { public static NumberWithUnits parseNumberWithUnits(String val) {
if (val == null) return null; if (val == null) {
return null;
}
return new NumberWithUnits(val); return new NumberWithUnits(val);
} }
public static HashMap<String, StyleAttribute> parseStyle(String styleString, HashMap<String, StyleAttribute> map) { public static HashMap<String, StyleAttribute> parseStyle(String styleString, HashMap<String, StyleAttribute> map) {
final 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) {
if (style.length() == 0) { if (style.length() == 0) {

View file

@ -0,0 +1,18 @@
package org.xbib.graphics.svg.test;
import org.junit.jupiter.api.Test;
import org.xbib.graphics.svg.SVGDiagram;
import org.xbib.graphics.svg.SVGUniverse;
import java.io.IOException;
import java.io.InputStream;
public class SimpleSVGLoadTest {
@Test
public void test() throws IOException {
InputStream inputStream = getClass().getResourceAsStream("test.svg");
SVGUniverse svgUniverse = new SVGUniverse();
SVGDiagram diagram = svgUniverse.getDiagram(svgUniverse.loadSVG(inputStream, "test.svg"));
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Some files were not shown because too many files have changed in this diff Show more