From 958b6eae644f738808983e1dc43acbc95bbcda04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=CC=88rg=20Prante?= Date: Fri, 17 Dec 2021 09:59:30 +0100 Subject: [PATCH] working on salamander svg cleanup --- .../main/java/org/xbib/graphics/svg/A.java | 1 + .../org/xbib/graphics/svg/AdobeComposite.java | 39 + .../graphics/svg/AdobeCompositeContext.java | 57 + .../java/org/xbib/graphics/svg/ClipPath.java | 159 - .../main/java/org/xbib/graphics/svg/Defs.java | 91 - .../main/java/org/xbib/graphics/svg/Desc.java | 76 - .../org/xbib/graphics/svg/FeDistantLight.java | 112 - .../java/org/xbib/graphics/svg/FeLight.java | 56 - .../org/xbib/graphics/svg/FePointLight.java | 131 - .../org/xbib/graphics/svg/FillElement.java | 63 - .../org/xbib/graphics/svg/FilterEffects.java | 251 - .../java/org/xbib/graphics/svg/FontFace.java | 2 + .../graphics/svg/{util => }/FontSystem.java | 81 +- .../java/org/xbib/graphics/svg/Glyph.java | 97 - .../graphics/svg/{app/data => }/Handler.java | 2 +- .../svg/{app/data => }/HandlerFactory.java | 4 +- .../java/org/xbib/graphics/svg/Hkern.java | 51 +- .../java/org/xbib/graphics/svg/ImageSVG.java | 20 +- .../java/org/xbib/graphics/svg/Marker.java | 145 +- .../org/xbib/graphics/svg/MarkerLayout.java | 112 + .../java/org/xbib/graphics/svg/MarkerPos.java | 30 + .../java/org/xbib/graphics/svg/Metadata.java | 47 +- .../main/java/org/xbib/graphics/svg/Path.java | 71 +- .../org/xbib/graphics/svg/PatternPaint.java | 37 + .../graphics/svg/PatternPaintContext.java | 63 + .../org/xbib/graphics/svg/PatternSVG.java | 137 +- .../java/org/xbib/graphics/svg/Polygon.java | 43 +- .../java/org/xbib/graphics/svg/Polyline.java | 3 +- .../main/java/org/xbib/graphics/svg/Rect.java | 3 +- .../java/org/xbib/graphics/svg/SVGCache.java | 57 - .../java/org/xbib/graphics/svg/SVGConst.java | 12 - .../org/xbib/graphics/svg/SVGDiagram.java | 6 +- .../graphics/svg/SVGElementException.java | 63 +- .../graphics/svg/{app/beans => }/SVGIcon.java | 8 +- .../java/org/xbib/graphics/svg/SVGLoader.java | 27 +- .../xbib/graphics/svg/SVGParseException.java | 52 +- .../java/org/xbib/graphics/svg/SVGRoot.java | 6 +- .../org/xbib/graphics/svg/SVGUniverse.java | 88 +- .../main/java/org/xbib/graphics/svg/Stop.java | 70 +- .../java/org/xbib/graphics/svg/Symbol.java | 3 +- .../java/org/xbib/graphics/svg/Title.java | 60 +- .../graphics/svg/TransformableElement.java | 133 - .../java/org/xbib/graphics/svg/Tspan.java | 6 +- .../main/java/org/xbib/graphics/svg/Use.java | 5 +- .../svg/composite/AdobeComposite.java | 87 - .../svg/composite/AdobeCompositeContext.java | 105 - .../graphics/svg/{ => element}/Circle.java | 34 +- .../xbib/graphics/svg/element/ClipPath.java | 89 + .../org/xbib/graphics/svg/element/Defs.java | 38 + .../org/xbib/graphics/svg/element/Desc.java | 29 + .../graphics/svg/{ => element}/Ellipse.java | 76 +- .../graphics/svg/element/FillElement.java | 10 + .../graphics/svg/{ => element}/Filter.java | 73 +- .../xbib/graphics/svg/{ => element}/Font.java | 9 +- .../graphics/svg/{ => element}/Group.java | 12 +- .../xbib/graphics/svg/{ => element}/Line.java | 75 +- .../xbib/graphics/svg/{ => element}/Mask.java | 76 +- .../svg/{ => element}/RenderableElement.java | 85 +- .../svg/{ => element}/SVGElement.java | 28 +- .../svg/{ => element}/ShapeElement.java | 48 +- .../graphics/svg/{ => element}/Style.java | 5 +- .../svg/element/TransformableElement.java | 57 + .../element/filtereffects/DistantLight.java | 61 + .../element/filtereffects/FilterEffects.java | 120 + .../svg/element/filtereffects/FilterOp.java | 16 + .../filtereffects/GaussianBlur.java} | 19 +- .../svg/element/filtereffects/Light.java | 11 + .../svg/element/filtereffects/PointLight.java | 82 + .../filtereffects/SpotLight.java} | 86 +- .../graphics/svg/element/glyph/Glyph.java | 39 + .../svg/{ => element/glyph}/MissingGlyph.java | 14 +- .../svg/{ => element/gradient}/Gradient.java | 162 +- .../gradient}/LinearGradient.java | 76 +- .../gradient}/RadialGradient.java | 4 +- .../org/xbib/graphics/svg/pathcmd/Arc.java | 147 +- .../graphics/svg/pathcmd/BuildHistory.java | 66 - .../org/xbib/graphics/svg/pathcmd/Cubic.java | 62 +- .../graphics/svg/pathcmd/CubicSmooth.java | 52 +- .../xbib/graphics/svg/pathcmd/Horizontal.java | 48 - .../org/xbib/graphics/svg/pathcmd/LineTo.java | 48 - .../org/xbib/graphics/svg/pathcmd/MoveTo.java | 50 +- .../graphics/svg/pathcmd/PathCommand.java | 49 - .../xbib/graphics/svg/pathcmd/PathParser.java | 50 +- .../xbib/graphics/svg/pathcmd/PathUtil.java | 54 +- .../xbib/graphics/svg/pathcmd/Quadratic.java | 62 +- .../graphics/svg/pathcmd/QuadraticSmooth.java | 50 +- .../xbib/graphics/svg/pathcmd/Terminal.java | 49 - .../xbib/graphics/svg/pathcmd/Vertical.java | 47 - .../graphics/svg/pattern/PatternPaint.java | 72 - .../svg/pattern/PatternPaintContext.java | 133 - .../org/xbib/graphics/svg/util/FontUtil.java | 61 +- .../xbib/graphics/svg/util/PaintCache.java | 38 + .../PaintUtil.java} | 58 +- .../xbib/graphics/svg/util/TextBuilder.java | 43 - .../xbib/graphics/svg/xml/StyleAttribute.java | 24 +- .../org/xbib/graphics/svg/xml/StyleSheet.java | 5 - .../xbib/graphics/svg/xml/XMLParseUtil.java | 15 +- .../graphics/svg/test/SimpleSVGLoadTest.java | 18 + graphics-svg/src/test/res/1C2EC147.png | Bin 48520 -> 0 bytes graphics-svg/src/test/res/1C2EC148.png | Bin 48520 -> 0 bytes .../src/test/res/AdamTagletClasses.svg | 104 - graphics-svg/src/test/res/Monitor.svg | 84 - graphics-svg/src/test/res/bad_alias.svg | 131 - graphics-svg/src/test/res/bad_alias2.svg | 229 - graphics-svg/src/test/res/bad_alias3.svg | 5689 ---------- .../test/res/data-uri-scheme-test-image.svg | 23 - graphics-svg/src/test/res/drawing.svg | 9361 ----------------- graphics-svg/src/test/res/embed_image.svg | 5689 ---------- graphics-svg/src/test/res/embed_image.svgz | Bin 45950 -> 0 bytes graphics-svg/src/test/res/missing.svg | 1090 -- graphics-svg/src/test/res/missing.svgz | Bin 15968 -> 0 bytes graphics-svg/src/test/res/round_path.svg | 20 - .../org/xbib/graphics/svg/test/test.svg | 119 + 113 files changed, 1584 insertions(+), 26462 deletions(-) create mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/AdobeComposite.java create mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/AdobeCompositeContext.java delete mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/ClipPath.java delete mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/Defs.java delete mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/Desc.java delete mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/FeDistantLight.java delete mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/FeLight.java delete mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/FePointLight.java delete mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/FillElement.java delete mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/FilterEffects.java rename graphics-svg/src/main/java/org/xbib/graphics/svg/{util => }/FontSystem.java (55%) delete mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/Glyph.java rename graphics-svg/src/main/java/org/xbib/graphics/svg/{app/data => }/Handler.java (97%) rename graphics-svg/src/main/java/org/xbib/graphics/svg/{app/data => }/HandlerFactory.java (84%) create mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/MarkerLayout.java create mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/MarkerPos.java create mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/PatternPaint.java create mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/PatternPaintContext.java delete mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/SVGCache.java delete mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/SVGConst.java rename graphics-svg/src/main/java/org/xbib/graphics/svg/{app/beans => }/SVGIcon.java (97%) delete mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/TransformableElement.java delete mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/composite/AdobeComposite.java delete mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/composite/AdobeCompositeContext.java rename graphics-svg/src/main/java/org/xbib/graphics/svg/{ => element}/Circle.java (79%) create mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/element/ClipPath.java create mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/element/Defs.java create mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/element/Desc.java rename graphics-svg/src/main/java/org/xbib/graphics/svg/{ => element}/Ellipse.java (54%) create mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/element/FillElement.java rename graphics-svg/src/main/java/org/xbib/graphics/svg/{ => element}/Filter.java (90%) rename graphics-svg/src/main/java/org/xbib/graphics/svg/{ => element}/Font.java (89%) rename graphics-svg/src/main/java/org/xbib/graphics/svg/{ => element}/Group.java (91%) rename graphics-svg/src/main/java/org/xbib/graphics/svg/{ => element}/Line.java (54%) rename graphics-svg/src/main/java/org/xbib/graphics/svg/{ => element}/Mask.java (63%) rename graphics-svg/src/main/java/org/xbib/graphics/svg/{ => element}/RenderableElement.java (76%) rename graphics-svg/src/main/java/org/xbib/graphics/svg/{ => element}/SVGElement.java (95%) rename graphics-svg/src/main/java/org/xbib/graphics/svg/{ => element}/ShapeElement.java (93%) rename graphics-svg/src/main/java/org/xbib/graphics/svg/{ => element}/Style.java (86%) create mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/element/TransformableElement.java create mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/DistantLight.java create mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/FilterEffects.java create mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/FilterOp.java rename graphics-svg/src/main/java/org/xbib/graphics/svg/{FeGaussianBlur.java => element/filtereffects/GaussianBlur.java} (95%) create mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/Light.java create mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/PointLight.java rename graphics-svg/src/main/java/org/xbib/graphics/svg/{FeSpotLight.java => element/filtereffects/SpotLight.java} (67%) create mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/element/glyph/Glyph.java rename graphics-svg/src/main/java/org/xbib/graphics/svg/{ => element/glyph}/MissingGlyph.java (90%) rename graphics-svg/src/main/java/org/xbib/graphics/svg/{ => element/gradient}/Gradient.java (57%) rename graphics-svg/src/main/java/org/xbib/graphics/svg/{ => element/gradient}/LinearGradient.java (65%) rename graphics-svg/src/main/java/org/xbib/graphics/svg/{ => element/gradient}/RadialGradient.java (96%) delete mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/pattern/PatternPaint.java delete mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/pattern/PatternPaintContext.java create mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/util/PaintCache.java rename graphics-svg/src/main/java/org/xbib/graphics/svg/{BufferPainter.java => util/PaintUtil.java} (77%) delete mode 100644 graphics-svg/src/main/java/org/xbib/graphics/svg/util/TextBuilder.java create mode 100644 graphics-svg/src/test/java/org/xbib/graphics/svg/test/SimpleSVGLoadTest.java delete mode 100644 graphics-svg/src/test/res/1C2EC147.png delete mode 100644 graphics-svg/src/test/res/1C2EC148.png delete mode 100644 graphics-svg/src/test/res/AdamTagletClasses.svg delete mode 100644 graphics-svg/src/test/res/Monitor.svg delete mode 100644 graphics-svg/src/test/res/bad_alias.svg delete mode 100644 graphics-svg/src/test/res/bad_alias2.svg delete mode 100644 graphics-svg/src/test/res/bad_alias3.svg delete mode 100644 graphics-svg/src/test/res/data-uri-scheme-test-image.svg delete mode 100644 graphics-svg/src/test/res/drawing.svg delete mode 100644 graphics-svg/src/test/res/embed_image.svg delete mode 100644 graphics-svg/src/test/res/embed_image.svgz delete mode 100644 graphics-svg/src/test/res/missing.svg delete mode 100644 graphics-svg/src/test/res/missing.svgz delete mode 100644 graphics-svg/src/test/res/round_path.svg create mode 100644 graphics-svg/src/test/resources/org/xbib/graphics/svg/test/test.svg diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/A.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/A.java index ef85b1b..c94cb38 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/A.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/A.java @@ -1,5 +1,6 @@ package org.xbib.graphics.svg; +import org.xbib.graphics.svg.element.Group; import org.xbib.graphics.svg.xml.StyleAttribute; import java.io.IOException; diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/AdobeComposite.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/AdobeComposite.java new file mode 100644 index 0000000..9971921 --- /dev/null +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/AdobeComposite.java @@ -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); + } +} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/AdobeCompositeContext.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/AdobeCompositeContext.java new file mode 100644 index 0000000..62e481f --- /dev/null +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/AdobeCompositeContext.java @@ -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() { + } +} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/ClipPath.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/ClipPath.java deleted file mode 100644 index dec8098..0000000 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/ClipPath.java +++ /dev/null @@ -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 Mark McKay - */ -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; - } -} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/Defs.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/Defs.java deleted file mode 100644 index 06961e5..0000000 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/Defs.java +++ /dev/null @@ -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 Mark McKay - */ -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; - } -} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/Desc.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/Desc.java deleted file mode 100644 index ea9f14e..0000000 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/Desc.java +++ /dev/null @@ -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 Mark McKay - */ -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; - } -} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/FeDistantLight.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/FeDistantLight.java deleted file mode 100644 index e46f2d6..0000000 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/FeDistantLight.java +++ /dev/null @@ -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 Mark McKay - */ -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; - } -} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/FeLight.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/FeLight.java deleted file mode 100644 index c782a07..0000000 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/FeLight.java +++ /dev/null @@ -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 Mark McKay - */ -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; - } -} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/FePointLight.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/FePointLight.java deleted file mode 100644 index 92d1f78..0000000 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/FePointLight.java +++ /dev/null @@ -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 Mark McKay - */ -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; - } -} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/FillElement.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/FillElement.java deleted file mode 100644 index adc859a..0000000 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/FillElement.java +++ /dev/null @@ -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 Mark McKay - */ -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); -} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/FilterEffects.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/FilterEffects.java deleted file mode 100644 index 28af4a6..0000000 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/FilterEffects.java +++ /dev/null @@ -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 Mark McKay - */ -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 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; - } - } -} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/FontFace.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/FontFace.java index 0899065..6b6cae6 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/FontFace.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/FontFace.java @@ -1,5 +1,7 @@ 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 java.io.IOException; diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/util/FontSystem.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/FontSystem.java similarity index 55% rename from graphics-svg/src/main/java/org/xbib/graphics/svg/util/FontSystem.java rename to graphics-svg/src/main/java/org/xbib/graphics/svg/FontSystem.java index cb58e0e..cce01f5 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/util/FontSystem.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/FontSystem.java @@ -1,70 +1,32 @@ -/* - * 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; +package org.xbib.graphics.svg; -import org.xbib.graphics.svg.Font; -import org.xbib.graphics.svg.FontFace; -import org.xbib.graphics.svg.Glyph; -import org.xbib.graphics.svg.MissingGlyph; -import org.xbib.graphics.svg.Text; +import org.xbib.graphics.svg.element.Font; +import org.xbib.graphics.svg.element.glyph.Glyph; +import org.xbib.graphics.svg.element.glyph.MissingGlyph; import java.awt.GraphicsEnvironment; import java.awt.font.FontRenderContext; import java.awt.font.GlyphMetrics; import java.awt.font.GlyphVector; import java.awt.font.LineMetrics; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Locale; +import java.util.Map; +import java.util.Set; -/** - * @author kitfox - */ public class FontSystem extends Font { + java.awt.Font sysFont; - HashMap glyphCache = new HashMap<>(); + Map glyphCache = new HashMap<>(); - static HashSet sysFontNames = new HashSet<>(); + static Set sysFontNames = new HashSet<>(); public static boolean checkIfSystemFontExists(String fontName) { if (sysFontNames.isEmpty()) { - for (String name : GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(Locale.ENGLISH)) { - sysFontNames.add(name); - } + Collections.addAll(sysFontNames, GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(Locale.ENGLISH)); } return sysFontNames.contains(fontName); @@ -94,15 +56,11 @@ public class FontSystem extends Font { private FontSystem(String fontFamily, int fontStyle, int fontWeight, float fontSize) { int style; - switch (fontStyle) { - case Text.TXST_ITALIC: - style = java.awt.Font.ITALIC; - break; - default: - style = java.awt.Font.PLAIN; - break; + if (fontStyle == Text.TXST_ITALIC) { + style = java.awt.Font.ITALIC; + } else { + style = java.awt.Font.PLAIN; } - int weight; switch (fontWeight) { case Text.TXWE_BOLD: @@ -113,12 +71,9 @@ public class FontSystem extends Font { weight = java.awt.Font.PLAIN; break; } - sysFont = new java.awt.Font(fontFamily, style | weight, 1).deriveFont(fontSize); - FontRenderContext fontRenderContext = new FontRenderContext(null, true, true); LineMetrics lineMetrics = sysFont.getLineMetrics("M", fontRenderContext); - FontFace face = new FontFace(); face.setAscent((int) lineMetrics.getAscent()); face.setDescent((int) lineMetrics.getDescent()); @@ -130,23 +85,17 @@ public class FontSystem extends Font { public MissingGlyph getGlyph(String unicode) { FontRenderContext frc = new FontRenderContext(null, true, true); GlyphVector vec = sysFont.createGlyphVector(frc, unicode); - Glyph glyph = glyphCache.get(unicode); if (glyph == null) { glyph = new Glyph(); glyph.setPath(vec.getGlyphOutline(0)); - GlyphMetrics gm = vec.getGlyphMetrics(0); glyph.setHorizAdvX(gm.getAdvanceX()); glyph.setVertAdvY(gm.getAdvanceY()); glyph.setVertOriginX(0); glyph.setVertOriginY(0); - glyphCache.put(unicode, glyph); } - return glyph; } - - } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/Glyph.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/Glyph.java deleted file mode 100644 index 01564b1..0000000 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/Glyph.java +++ /dev/null @@ -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. - *

- * SVG specification: http://www.w3.org/TR/SVG/fonts.html - * - * @author Mark McKay - * @author Mark McKay - */ -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; - } -} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/app/data/Handler.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/Handler.java similarity index 97% rename from graphics-svg/src/main/java/org/xbib/graphics/svg/app/data/Handler.java rename to graphics-svg/src/main/java/org/xbib/graphics/svg/Handler.java index 7e7106d..6a8ca58 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/app/data/Handler.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/Handler.java @@ -1,4 +1,4 @@ -package org.xbib.graphics.svg.app.data; +package org.xbib.graphics.svg; import java.io.ByteArrayInputStream; import java.io.InputStream; diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/app/data/HandlerFactory.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/HandlerFactory.java similarity index 84% rename from graphics-svg/src/main/java/org/xbib/graphics/svg/app/data/HandlerFactory.java rename to graphics-svg/src/main/java/org/xbib/graphics/svg/HandlerFactory.java index 306634f..75b5437 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/app/data/HandlerFactory.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/HandlerFactory.java @@ -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.URLStreamHandlerFactory; diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/Hkern.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/Hkern.java index 64c4d88..f71b359 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/Hkern.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/Hkern.java @@ -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; +import org.xbib.graphics.svg.element.SVGElement; import org.xbib.graphics.svg.xml.StyleAttribute; import java.io.IOException; -/** - * @author kitfox - */ public class Hkern extends SVGElement { public static final String TAG_NAME = "hkern"; + String u1; + String u2; + int k; @Override @@ -57,19 +23,13 @@ public class Hkern extends SVGElement { @Override protected void build() throws SVGException, IOException { super.build(); - StyleAttribute sty = new StyleAttribute(); - - - //Read glyph spacing info - if (getPres(sty.setName("u1"))) { + if (getPres(sty.setName("u1"))) { u1 = sty.getStringValue(); } - if (getPres(sty.setName("u2"))) { u2 = sty.getStringValue(); } - if (getPres(sty.setName("k"))) { k = sty.getIntValue(); } @@ -77,7 +37,6 @@ public class Hkern extends SVGElement { @Override public boolean updateTime(double curTime) throws SVGException { - //Fonts can't change return false; } } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/ImageSVG.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/ImageSVG.java index ddd2bd4..7e67d90 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/ImageSVG.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/ImageSVG.java @@ -1,6 +1,7 @@ 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 java.awt.AlphaComposite; @@ -19,6 +20,8 @@ import java.util.logging.Logger; public class ImageSVG extends RenderableElement { + private static final Logger logger = Logger.getLogger(ImageSVG.class.getName()); + public static final String TAG_NAME = "image"; float x = 0f; @@ -67,8 +70,7 @@ public class ImageSVG extends RenderableElement { try { imageSrc = src.toURL(); } catch (Exception e) { - Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, - "Could not parse xlink:href " + src, e); + logger.log(Level.SEVERE, "Could not parse xlink:href " + src, e); imageSrc = null; } } @@ -111,21 +113,21 @@ public class ImageSVG extends RenderableElement { } @Override - protected void doPick(Point2D point, boolean boundingBox, List> retVec) { + public void doPick(Point2D point, boolean boundingBox, List> retVec) { if (getBoundingBox().contains(point)) { retVec.add(getPath(null)); } } @Override - protected void doPick(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List> retVec) { + public void doPick(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List> retVec) { if (ltw.createTransformedShape(getBoundingBox()).intersects(pickArea)) { retVec.add(getPath(null)); } } @Override - protected void doRender(Graphics2D g) throws SVGException, IOException { + public void doRender(Graphics2D g) throws SVGException, IOException { StyleAttribute styleAttrib = new StyleAttribute(); if (getStyle(styleAttrib.setName("visibility"))) { if (!styleAttrib.getStringValue().equals("visible")) { @@ -218,12 +220,10 @@ public class ImageSVG extends RenderableElement { } } } catch (IllegalArgumentException ie) { - Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, - "Image provided with illegal value for href: \"" + logger.log(Level.SEVERE, "Image provided with illegal value for href: \"" + sty.getStringValue() + '"', ie); } catch (Exception e) { - Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, - "Could not parse xlink:href", e); + logger.log(Level.WARNING, "Could not parse xlink:href", e); } if (shapeChange) { build(); diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/Marker.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/Marker.java index 6d0831f..673b468 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/Marker.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/Marker.java @@ -1,21 +1,25 @@ package org.xbib.graphics.svg; +import org.xbib.graphics.svg.element.Group; import org.xbib.graphics.svg.xml.StyleAttribute; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.Shape; import java.awt.geom.AffineTransform; -import java.awt.geom.PathIterator; import java.awt.geom.Rectangle2D; import java.io.IOException; -import java.util.ArrayList; -import java.util.List; public class Marker extends Group { public static final String TAG_NAME = "marker"; + public static final int MARKER_START = 0; + + public static final int MARKER_MID = 1; + + public static final int MARKER_END = 2; + AffineTransform viewXform; AffineTransform markerXform; @@ -93,7 +97,7 @@ public class Marker extends Group { } @Override - protected void doRender(Graphics2D g) throws SVGException, IOException { + public void doRender(Graphics2D g) throws SVGException, IOException { AffineTransform oldXform = g.getTransform(); g.transform(markerXform); super.doRender(g); @@ -130,137 +134,4 @@ public class Marker extends Group { build(); 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 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 getMarkerList() { - return markerList; - } - } } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/MarkerLayout.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/MarkerLayout.java new file mode 100644 index 0000000..c509f8d --- /dev/null +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/MarkerLayout.java @@ -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 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 getMarkerList() { + return markerList; + } +} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/MarkerPos.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/MarkerPos.java new file mode 100644 index 0000000..a84b340 --- /dev/null +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/MarkerPos.java @@ -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; + } +} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/Metadata.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/Metadata.java index 512ebd1..4480838 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/Metadata.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/Metadata.java @@ -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; -/** - * Does not hold any information. Included to allow metadata tag to be parsed. - * - * @author Mark McKay - * @author Mark McKay - */ +import org.xbib.graphics.svg.element.SVGElement; + public class Metadata extends SVGElement { + public static final String TAG_NAME = "metadata"; - /** - * Creates a new instance of Stop - */ public Metadata() { } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/Path.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/Path.java index 9aaffab..2c9ba9b 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/Path.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/Path.java @@ -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; +import org.xbib.graphics.svg.element.ShapeElement; import org.xbib.graphics.svg.xml.StyleAttribute; import java.awt.Graphics2D; @@ -43,22 +9,16 @@ import java.awt.geom.GeneralPath; import java.awt.geom.Rectangle2D; import java.io.IOException; -/** - * @author Mark McKay - * @author Mark McKay - */ public class Path extends ShapeElement { public static final String TAG_NAME = "path"; - // PathCommand[] commands = null; + int fillRule = GeneralPath.WIND_NON_ZERO; + String d = ""; - // ExtendedGeneralPath path; + GeneralPath path; - /** - * Creates a new instance of Rect - */ public Path() { } @@ -70,22 +30,17 @@ public class Path extends ShapeElement { @Override protected void build() throws SVGException, IOException { super.build(); - StyleAttribute sty = new StyleAttribute(); - - String fillRuleStrn = (getStyle(sty.setName("fill-rule"))) ? sty.getStringValue() : "nonzero"; fillRule = fillRuleStrn.equals("evenodd") ? GeneralPath.WIND_EVEN_ODD : GeneralPath.WIND_NON_ZERO; - if (getPres(sty.setName("d"))) { d = sty.getStringValue(); } - path = buildPath(d, fillRule); } @Override - protected void doRender(Graphics2D g) throws SVGException, IOException { + public void doRender(Graphics2D g) throws SVGException, IOException { beginLayer(g); renderShape(g, path); finishLayer(g); @@ -101,22 +56,11 @@ public class Path extends ShapeElement { return boundsToParent(includeStrokeInBounds(path.getBounds2D())); } - /** - * Updates all attributes in this diagram associated with a time event. Ie, - * all attributes with track information. - * - * @return - true if this node has changed state as a result of the time - * update - */ @Override public boolean updateTime(double curTime) throws SVGException, IOException { -// if (trackManager.getNumTracks() == 0) return false; boolean changeState = super.updateTime(curTime); - - //Get current values for parameters StyleAttribute sty = new StyleAttribute(); boolean shapeChange = false; - if (getStyle(sty.setName("fill-rule"))) { int newVal = sty.getStringValue().equals("evenodd") ? GeneralPath.WIND_EVEN_ODD @@ -126,7 +70,6 @@ public class Path extends ShapeElement { changeState = true; } } - if (getPres(sty.setName("d"))) { String newVal = sty.getStringValue(); if (!newVal.equals(d)) { @@ -134,13 +77,9 @@ public class Path extends ShapeElement { shapeChange = true; } } - if (shapeChange) { build(); -// path = buildPath(d, fillRule); -// return true; } - return changeState || shapeChange; } } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/PatternPaint.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/PatternPaint.java new file mode 100644 index 0000000..ee9c55a --- /dev/null +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/PatternPaint.java @@ -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(); + } + +} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/PatternPaintContext.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/PatternPaintContext.java new file mode 100644 index 0000000..39a74c5 --- /dev/null +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/PatternPaintContext.java @@ -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(); + } +} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/PatternSVG.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/PatternSVG.java index 58c00a2..68d2ba7 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/PatternSVG.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/PatternSVG.java @@ -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; -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 java.awt.Graphics2D; @@ -48,30 +15,31 @@ import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.net.URI; -import java.util.logging.Level; -import java.util.logging.Logger; -/** - * @author Mark McKay - * @author Mark McKay - */ public class PatternSVG extends FillElement { + public static final String TAG_NAME = "pattern"; public static final int GU_OBJECT_BOUNDING_BOX = 0; + public static final int GU_USER_SPACE_ON_USE = 1; + int gradientUnits = GU_OBJECT_BOUNDING_BOX; + float x; + float y; + float width; + float height; + AffineTransform patternXform = new AffineTransform(); + Rectangle2D.Float viewBox; + Paint texPaint; - /** - * Creates a new instance of Gradient - */ public PatternSVG() { } @@ -80,10 +48,6 @@ public class PatternSVG extends FillElement { 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); @@ -92,36 +56,23 @@ public class PatternSVG extends FillElement { @Override protected void build() throws SVGException, IOException { super.build(); - StyleAttribute sty = new StyleAttribute(); - - //Load style string String href = null; if (getPres(sty.setName("xlink:href"))) { 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) { -//System.err.println("Gradient.loaderStartElement() href '" + href + "'"); - try { - URI src = getXMLBase().resolve(href); - PatternSVG patSrc = (PatternSVG) diagram.getUniverse().getElement(src); - - gradientUnits = patSrc.gradientUnits; - x = patSrc.x; - y = patSrc.y; - width = patSrc.width; - height = patSrc.height; - 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); - } + URI src = getXMLBase().resolve(href); + PatternSVG patSrc = (PatternSVG) diagram.getUniverse().getElement(src); + gradientUnits = patSrc.gradientUnits; + x = patSrc.x; + y = patSrc.y; + width = patSrc.width; + height = patSrc.height; + viewBox = patSrc.viewBox; + patternXform.setTransform(patSrc.patternXform); + children.addAll(patSrc.children); } - String gradientUnits = ""; if (getPres(sty.setName("gradientUnits"))) { gradientUnits = sty.getStringValue().toLowerCase(); @@ -131,106 +82,72 @@ public class PatternSVG extends FillElement { } else { this.gradientUnits = GU_OBJECT_BOUNDING_BOX; } - String patternTransform = ""; if (getPres(sty.setName("patternTransform"))) { patternTransform = sty.getStringValue(); } patternXform = parseTransform(patternTransform); - - if (getPres(sty.setName("x"))) { x = sty.getFloatValueWithUnits(); } - if (getPres(sty.setName("y"))) { y = sty.getFloatValueWithUnits(); } - if (getPres(sty.setName("width"))) { width = sty.getFloatValueWithUnits(); } - if (getPres(sty.setName("height"))) { height = sty.getFloatValueWithUnits(); } - if (getPres(sty.setName("viewBox"))) { float[] dim = sty.getFloatList(); viewBox = new Rectangle2D.Float(dim[0], dim[1], dim[2], dim[3]); } - preparePattern(); } - /* - public void loaderEndElement(SVGLoaderHelper helper) - { - build(); - } - */ 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 tileHeight = (int) height; - float stretchX = 1f, stretchY = 1f; if (!patternXform.isIdentity()) { - //Scale our source tile so that we can have nice sampling from it. float xlateX = (float) patternXform.getTranslateX(); float xlateY = (float) patternXform.getTranslateY(); - Point2D.Float pt = new Point2D.Float(), pt2 = new Point2D.Float(); - pt.setLocation(width, 0); patternXform.transform(pt, pt2); pt2.x -= xlateX; pt2.y -= xlateY; stretchX = (float) Math.sqrt(pt2.x * pt2.x + pt2.y * pt2.y) * 1.5f / width; - pt.setLocation(height, 0); patternXform.transform(pt, pt2); pt2.x -= xlateX; pt2.y -= xlateY; stretchY = (float) Math.sqrt(pt2.x * pt2.x + pt2.y * pt2.y) * 1.5f / height; - tileWidth *= stretchX; tileHeight *= stretchY; } - if (tileWidth == 0 || tileHeight == 0) { - //Use defaults if tile has degenerate size return; } - BufferedImage buf = new BufferedImage(tileWidth, tileHeight, BufferedImage.TYPE_INT_ARGB); Graphics2D g = buf.createGraphics(); g.setClip(0, 0, tileWidth, tileHeight); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - for (SVGElement ele : children) { if (ele instanceof RenderableElement) { AffineTransform xform = new AffineTransform(); - if (viewBox == null) { xform.translate(-x, -y); } else { xform.scale(tileWidth / viewBox.width, tileHeight / viewBox.height); xform.translate(-viewBox.x, -viewBox.y); } - g.setTransform(xform); ((RenderableElement) ele).render(g); } } - g.dispose(); - -//try { -//javax.imageio.ImageIO.write(buf, "png", new java.io.File("c:\\tmp\\texPaint.png")); -//} catch (Exception e ) {} - if (patternXform.isIdentity()) { texPaint = new TexturePaint(buf, new Rectangle2D.Float(x, y, width, height)); } else { @@ -244,16 +161,8 @@ public class PatternSVG extends FillElement { 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 public boolean updateTime(double curTime) throws SVGException { - //Patterns don't change state return false; } } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/Polygon.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/Polygon.java index 05a5135..8c208d1 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/Polygon.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/Polygon.java @@ -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; +import org.xbib.graphics.svg.element.ShapeElement; import org.xbib.graphics.svg.xml.StyleAttribute; import org.xbib.graphics.svg.xml.XMLParseUtil; @@ -44,11 +10,8 @@ import java.awt.geom.GeneralPath; import java.awt.geom.Rectangle2D; import java.io.IOException; -/** - * @author Mark McKay - * @author Mark McKay - */ public class Polygon extends ShapeElement { + public static final String TAG_NAME = "polygon"; int fillRule = GeneralPath.WIND_NON_ZERO; @@ -94,7 +57,7 @@ public class Polygon extends ShapeElement { } @Override - protected void doRender(Graphics2D g) throws SVGException, IOException { + public void doRender(Graphics2D g) throws SVGException, IOException { beginLayer(g); renderShape(g, path); finishLayer(g); diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/Polyline.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/Polyline.java index 6021399..5aba970 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/Polyline.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/Polyline.java @@ -1,5 +1,6 @@ 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.XMLParseUtil; @@ -49,7 +50,7 @@ public class Polyline extends ShapeElement { } @Override - protected void doRender(Graphics2D g) throws SVGException, IOException { + public void doRender(Graphics2D g) throws SVGException, IOException { beginLayer(g); renderShape(g, path); finishLayer(g); diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/Rect.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/Rect.java index 6bd291c..000e780 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/Rect.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/Rect.java @@ -1,5 +1,6 @@ package org.xbib.graphics.svg; +import org.xbib.graphics.svg.element.ShapeElement; import org.xbib.graphics.svg.xml.StyleAttribute; import java.awt.Graphics2D; @@ -69,7 +70,7 @@ public class Rect extends ShapeElement { } @Override - protected void doRender(Graphics2D g) throws SVGException, IOException { + public void doRender(Graphics2D g) throws SVGException, IOException { beginLayer(g); renderShape(g, rect); finishLayer(g); diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGCache.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGCache.java deleted file mode 100644 index 6791e09..0000000 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGCache.java +++ /dev/null @@ -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; - } - -} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGConst.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGConst.java deleted file mode 100644 index 13b3d0b..0000000 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGConst.java +++ /dev/null @@ -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"; -} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGDiagram.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGDiagram.java index f3558bf..1f35d97 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGDiagram.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGDiagram.java @@ -1,5 +1,7 @@ package org.xbib.graphics.svg; +import org.xbib.graphics.svg.element.SVGElement; + import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.geom.AffineTransform; @@ -16,6 +18,8 @@ import java.util.logging.Logger; public class SVGDiagram { + private static final Logger logger = Logger.getLogger(SVGDiagram.class.getName()); + final Map idMap = new HashMap<>(); SVGRoot root; @@ -132,7 +136,7 @@ public class SVGDiagram { try { root.build(); } 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); } } } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGElementException.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGElementException.java index bdfc9e7..b0f161e 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGElementException.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGElementException.java @@ -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; -/** - * @author kitfox - */ +import org.xbib.graphics.svg.element.SVGElement; + +@SuppressWarnings("serial") public class SVGElementException extends SVGException { - public static final long serialVersionUID = 0; private final SVGElement element; - /** - * Creates a new instance of SVGException without detail message. - * - * @param element - */ - public SVGElementException(SVGElement element) { - this(element, null, null); - } - - - /** - * Constructs an instance of SVGException with the specified detail message. - * - * @param element - * @param msg the detail message. - */ public SVGElementException(SVGElement element, String msg) { this(element, msg, null); } @@ -69,10 +16,6 @@ public class SVGElementException extends SVGException { this.element = element; } - public SVGElementException(SVGElement element, Throwable cause) { - this(element, null, cause); - } - public SVGElement getElement() { return element; } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/app/beans/SVGIcon.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGIcon.java similarity index 97% rename from graphics-svg/src/main/java/org/xbib/graphics/svg/app/beans/SVGIcon.java rename to graphics-svg/src/main/java/org/xbib/graphics/svg/SVGIcon.java index 199dfe9..1f8cb14 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/app/beans/SVGIcon.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGIcon.java @@ -1,10 +1,6 @@ -package org.xbib.graphics.svg.app.beans; +package org.xbib.graphics.svg; 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.Dimension; @@ -28,7 +24,7 @@ public class SVGIcon extends ImageIcon { private final PropertyChangeSupport changes = new PropertyChangeSupport(this); - SVGUniverse svgUniverse = SVGCache.getSVGUniverse(); + SVGUniverse svgUniverse = new SVGUniverse(); public static final int INTERP_NEAREST_NEIGHBOR = 0; diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGLoader.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGLoader.java index 82d3c40..a07d671 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGLoader.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGLoader.java @@ -1,5 +1,23 @@ 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.SAXException; import org.xml.sax.helpers.DefaultHandler; @@ -15,6 +33,8 @@ import java.util.logging.Logger; public class SVGLoader extends DefaultHandler { + private static final Logger logger = Logger.getLogger(SVGLoader.class.getName()); + final Map> nodeClasses = new HashMap<>(); final LinkedList buildStack = new LinkedList<>(); @@ -38,7 +58,7 @@ public class SVGLoader extends DefaultHandler { nodeClasses.put("desc", Desc.class); nodeClasses.put("ellipse", Ellipse.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-face", FontFace.class); nodeClasses.put("g", Group.class); @@ -98,8 +118,7 @@ public class SVGLoader extends DefaultHandler { svgEle.loaderStartElement(helper, attrs, parent); buildStack.addLast(svgEle); } catch (Exception e) { - Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, - "Could not load", e); + logger.log(Level.SEVERE, "Could not load", e); throw new SAXException(e); } @@ -130,7 +149,7 @@ public class SVGLoader extends DefaultHandler { diagram.setRoot((SVGRoot) svgEle); } } 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); } } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGParseException.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGParseException.java index 13f4d8b..12df3dd 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGParseException.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGParseException.java @@ -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; -/** - * @author kitfox - */ -public class SVGParseException extends java.lang.Exception { - public static final long serialVersionUID = 0; +@SuppressWarnings("serial") +public class SVGParseException extends Exception { - /** - * Creates a new instance of SVGException without detail message. - */ public SVGParseException() { } - - /** - * Constructs an instance of SVGException with the specified detail message. - * - * @param msg the detail message. - */ public SVGParseException(String msg) { super(msg); } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGRoot.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGRoot.java index 7cfc6be..329d815 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGRoot.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGRoot.java @@ -1,5 +1,9 @@ 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.StyleAttribute; import org.xbib.graphics.svg.xml.StyleSheet; @@ -194,7 +198,7 @@ public class SVGRoot extends Group { } @Override - protected void doRender(Graphics2D g) throws SVGException, IOException { + public void doRender(Graphics2D g) throws SVGException, IOException { prepareViewport(); Rectangle targetViewport; Rectangle deviceViewport = diagram.getDeviceViewport(); diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGUniverse.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGUniverse.java index eaf18e7..9b7f5ae 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGUniverse.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGUniverse.java @@ -4,7 +4,9 @@ import javax.imageio.ImageIO; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; 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.SAXException; import org.xml.sax.SAXParseException; @@ -26,19 +28,22 @@ import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Base64; import java.util.HashMap; +import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import java.util.zip.GZIPInputStream; public class SVGUniverse { - final HashMap loadedDocs = new HashMap(); + private static final Logger logger = Logger.getLogger(SVGUniverse.class.getName()); - final HashMap loadedFonts = new HashMap(); + final Map loadedDocs = new HashMap<>(); - final HashMap> loadedImages = new HashMap>(); + final Map loadedFonts = new HashMap<>(); - public static final String INPUTSTREAM_SCHEME = "svgSalamander"; + final Map> loadedImages = new HashMap<>(); + + public static final String INPUTSTREAM_SCHEME = "svgXbib"; 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); } @@ -110,8 +115,7 @@ public class SVGUniverse { loadedImages.put(url, ref); return url; } catch (IOException ex) { - Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, - "Could not decode inline image", ex); + logger.log(Level.SEVERE, "Could not decode inline image", ex); } } return null; @@ -121,8 +125,7 @@ public class SVGUniverse { registerImage(url); return url; } catch (MalformedURLException ex) { - Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, - "Bad url", ex); + logger.log(Level.SEVERE, "Bad url", ex); } return null; } @@ -149,8 +152,7 @@ public class SVGUniverse { } loadedImages.put(imageURL, ref); } catch (Exception e) { - Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, - "Could not load image: " + imageURL, e); + logger.log(Level.SEVERE, "Could not load image: " + imageURL, e); } } @@ -177,8 +179,7 @@ public class SVGUniverse { URI uri = new URI(path.toString()); return getElement(uri, true); } catch (Exception e) { - Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, - "Could not parse url " + path, e); + logger.log(Level.SEVERE, "Could not parse url " + path, e); } return null; } @@ -216,8 +217,7 @@ public class SVGUniverse { String fragment = path.getFragment(); return fragment == null ? dia.getRoot() : dia.getElement(fragment); } catch (Exception e) { - Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, - "Could not parse path " + path, e); + logger.log(Level.SEVERE, "Could not parse path " + path, e); return null; } } @@ -245,8 +245,7 @@ public class SVGUniverse { dia = loadedDocs.get(xmlBase); return dia; } catch (Exception e) { - Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, - "Could not parse", e); + logger.log(Level.SEVERE, "Could not parse", e); } return null; } @@ -259,32 +258,10 @@ public class SVGUniverse { if ((b1 << 8 | b0) == GZIPInputStream.GZIP_MAGIC) { return new GZIPInputStream(bin); } else { - //Plain text 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 { return loadSVG(is, name, false); } @@ -301,6 +278,28 @@ public class SVGUniverse { 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) { return loadSVG(reader, name, false); } @@ -326,8 +325,7 @@ public class SVGUniverse { try { return new URI(INPUTSTREAM_SCHEME, name, null); } catch (Exception e) { - Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, - "Could not parse", e); + logger.log(Level.SEVERE, "Could not parse", e); return null; } } @@ -357,13 +355,11 @@ public class SVGUniverse { handler.getLoadedDiagram().updateTime(curTime); return xmlBase; } catch (SAXParseException sex) { - Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, - "Error processing " + xmlBase, sex); + logger.log(Level.SEVERE, "Error processing " + xmlBase, sex); loadedDocs.remove(xmlBase); return null; } catch (Throwable e) { - Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, - "Could not load SVG " + xmlBase, e); + logger.log(Level.SEVERE, "Could not load SVG " + xmlBase, e); } return null; } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/Stop.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/Stop.java index 1f660b9..748e6de 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/Stop.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/Stop.java @@ -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; +import org.xbib.graphics.svg.element.SVGElement; import org.xbib.graphics.svg.xml.StyleAttribute; import java.awt.Color; import java.io.IOException; -/** - * @author Mark McKay - * @author Mark McKay - */ public class Stop extends SVGElement { public static final String TAG_NAME = "stop"; - float offset = 0f; - float opacity = 1f; - Color color = Color.black; - /** - * Creates a new instance of Stop - */ + public float offset = 0f; + + public float opacity = 1f; + + public Color color = Color.black; + public Stop() { } @@ -65,9 +27,7 @@ public class Stop extends SVGElement { @Override protected void build() throws SVGException, IOException { super.build(); - StyleAttribute sty = new StyleAttribute(); - if (getPres(sty.setName("offset"))) { offset = sty.getFloatValue(); String units = sty.getUnits(); @@ -81,31 +41,18 @@ public class Stop extends SVGElement { offset = 0; } } - if (getStyle(sty.setName("stop-color"))) { color = sty.getColorValue(); } - if (getStyle(sty.setName("stop-opacity"))) { 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 public boolean updateTime(double curTime) throws SVGException { -// if (trackManager.getNumTracks() == 0) return false; - - //Get current values for parameters StyleAttribute sty = new StyleAttribute(); boolean shapeChange = false; - if (getPres(sty.setName("offset"))) { float newVal = sty.getFloatValue(); if (newVal != offset) { @@ -113,7 +60,6 @@ public class Stop extends SVGElement { shapeChange = true; } } - if (getStyle(sty.setName("stop-color"))) { Color newVal = sty.getColorValue(); if (newVal != color) { @@ -121,7 +67,6 @@ public class Stop extends SVGElement { shapeChange = true; } } - if (getStyle(sty.setName("stop-opacity"))) { float newVal = sty.getFloatValue(); if (newVal != opacity) { @@ -129,7 +74,6 @@ public class Stop extends SVGElement { shapeChange = true; } } - return shapeChange; } } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/Symbol.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/Symbol.java index 0630c02..2c13e4b 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/Symbol.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/Symbol.java @@ -1,5 +1,6 @@ package org.xbib.graphics.svg; +import org.xbib.graphics.svg.element.Group; import org.xbib.graphics.svg.xml.StyleAttribute; import java.awt.Graphics2D; @@ -49,7 +50,7 @@ public class Symbol extends Group { } @Override - protected void doRender(Graphics2D g) throws SVGException, IOException { + public void doRender(Graphics2D g) throws SVGException, IOException { AffineTransform oldXform = g.getTransform(); g.transform(viewXform); super.doRender(g); diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/Title.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/Title.java index 3ccaa2b..2e7e9a8 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/Title.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/Title.java @@ -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; -/** - * Holds title textual information within tree - * - * @author Mark McKay - * @author Mark McKay - */ +import org.xbib.graphics.svg.element.SVGElement; + public class Title extends SVGElement { + public static final String TAG_NAME = "title"; - StringBuffer text = new StringBuffer(); + StringBuilder text = new StringBuilder(); - /** - * Creates a new instance of Stop - */ public Title() { } @@ -57,9 +16,6 @@ public class Title extends SVGElement { 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); @@ -69,16 +25,8 @@ public class Title extends SVGElement { 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 public boolean updateTime(double curTime) throws SVGException { - //Title does not change return false; } } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/TransformableElement.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/TransformableElement.java deleted file mode 100644 index 9455488..0000000 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/TransformableElement.java +++ /dev/null @@ -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 Mark McKay - */ -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; - } -} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/Tspan.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/Tspan.java index 1aec7f1..08e61bd 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/Tspan.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/Tspan.java @@ -1,5 +1,9 @@ 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.xml.StyleAttribute; @@ -200,7 +204,7 @@ public class Tspan extends ShapeElement { } @Override - protected void doRender(Graphics2D g) throws SVGException, IOException { + public void doRender(Graphics2D g) throws SVGException, IOException { beginLayer(g); for (TextSegment segment : segments) { if (segment.textPath != null) { diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/Use.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/Use.java index eb7adb4..e862c61 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/Use.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/Use.java @@ -1,5 +1,8 @@ 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 java.awt.Graphics2D; @@ -57,7 +60,7 @@ public class Use extends ShapeElement { } @Override - protected void doRender(Graphics2D g) throws SVGException, IOException { + public void doRender(Graphics2D g) throws SVGException, IOException { beginLayer(g); AffineTransform oldXform = g.getTransform(); g.transform(refXform); diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/composite/AdobeComposite.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/composite/AdobeComposite.java deleted file mode 100644 index 34a090e..0000000 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/composite/AdobeComposite.java +++ /dev/null @@ -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 Mark McKay - */ -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); - } - -} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/composite/AdobeCompositeContext.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/composite/AdobeCompositeContext.java deleted file mode 100644 index ba7dc84..0000000 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/composite/AdobeCompositeContext.java +++ /dev/null @@ -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 Mark McKay - */ -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() { - } - -} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/Circle.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/Circle.java similarity index 79% rename from graphics-svg/src/main/java/org/xbib/graphics/svg/Circle.java rename to graphics-svg/src/main/java/org/xbib/graphics/svg/element/Circle.java index b402935..0ec7f32 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/Circle.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/Circle.java @@ -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 java.awt.Graphics2D; @@ -11,14 +12,15 @@ import java.io.IOException; public class Circle extends ShapeElement { public static final String TAG_NAME = "circle"; + float cx = 0f; + float cy = 0f; + float r = 0f; + Ellipse2D.Float circle = new Ellipse2D.Float(); - /** - * Creates a new instance of Rect - */ public Circle() { } @@ -30,26 +32,21 @@ public class Circle extends ShapeElement { @Override protected void build() throws SVGException, IOException { super.build(); - StyleAttribute sty = new StyleAttribute(); - if (getPres(sty.setName("cx"))) { cx = sty.getFloatValueWithUnits(); } - if (getPres(sty.setName("cy"))) { cy = sty.getFloatValueWithUnits(); } - if (getPres(sty.setName("r"))) { r = sty.getFloatValueWithUnits(); } - circle.setFrame(cx - r, cy - r, r * 2f, r * 2f); } @Override - protected void doRender(Graphics2D g) throws SVGException, IOException { + public void doRender(Graphics2D g) throws SVGException, IOException { beginLayer(g); renderShape(g, circle); finishLayer(g); @@ -65,22 +62,11 @@ public class Circle extends ShapeElement { 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 public boolean updateTime(double curTime) throws SVGException, IOException { -// if (trackManager.getNumTracks() == 0) return false; boolean changeState = super.updateTime(curTime); - - //Get current values for parameters StyleAttribute sty = new StyleAttribute(); boolean shapeChange = false; - if (getPres(sty.setName("cx"))) { float newVal = sty.getFloatValueWithUnits(); if (newVal != cx) { @@ -88,7 +74,6 @@ public class Circle extends ShapeElement { shapeChange = true; } } - if (getPres(sty.setName("cy"))) { float newVal = sty.getFloatValueWithUnits(); if (newVal != cy) { @@ -96,7 +81,6 @@ public class Circle extends ShapeElement { shapeChange = true; } } - if (getPres(sty.setName("r"))) { float newVal = sty.getFloatValueWithUnits(); if (newVal != r) { @@ -104,13 +88,9 @@ public class Circle extends ShapeElement { shapeChange = true; } } - if (shapeChange) { build(); -// circle.setFrame(cx - r, cy - r, r * 2f, r * 2f); -// return true; } - return changeState || shapeChange; } } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/element/ClipPath.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/ClipPath.java new file mode 100644 index 0000000..035dd30 --- /dev/null +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/ClipPath.java @@ -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; + } +} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/element/Defs.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/Defs.java new file mode 100644 index 0000000..acade91 --- /dev/null +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/Defs.java @@ -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; + } +} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/element/Desc.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/Desc.java new file mode 100644 index 0000000..73d8c45 --- /dev/null +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/Desc.java @@ -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; + } +} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/Ellipse.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/Ellipse.java similarity index 54% rename from graphics-svg/src/main/java/org/xbib/graphics/svg/Ellipse.java rename to graphics-svg/src/main/java/org/xbib/graphics/svg/element/Ellipse.java index 6659352..c1b3a36 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/Ellipse.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/Ellipse.java @@ -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.element; +import org.xbib.graphics.svg.SVGException; import org.xbib.graphics.svg.xml.StyleAttribute; import java.awt.Graphics2D; @@ -43,22 +9,20 @@ import java.awt.geom.Ellipse2D; import java.awt.geom.Rectangle2D; import java.io.IOException; -/** - * @author Mark McKay - * @author Mark McKay - */ public class Ellipse extends ShapeElement { public static final String TAG_NAME = "ellipse"; + float cx = 0.0f; + float cy = 0.0f; + float rx = 0.0f; + float ry = 0.0f; + Ellipse2D.Float ellipse = new Ellipse2D.Float(); - /** - * Creates a new instance of Rect - */ public Ellipse() { } @@ -70,30 +34,24 @@ public class Ellipse extends ShapeElement { @Override protected void build() throws SVGException, IOException { super.build(); - StyleAttribute sty = new StyleAttribute(); - if (getPres(sty.setName("cx"))) { cx = sty.getFloatValueWithUnits(); } - if (getPres(sty.setName("cy"))) { cy = sty.getFloatValueWithUnits(); } - if (getPres(sty.setName("rx"))) { rx = sty.getFloatValueWithUnits(); } - if (getPres(sty.setName("ry"))) { ry = sty.getFloatValueWithUnits(); } - ellipse.setFrame(cx - rx, cy - ry, rx * 2f, ry * 2f); } @Override - protected void doRender(Graphics2D g) throws SVGException, IOException { + public void doRender(Graphics2D g) throws SVGException, IOException { beginLayer(g); renderShape(g, ellipse); finishLayer(g); @@ -109,22 +67,11 @@ public class Ellipse extends ShapeElement { 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 public boolean updateTime(double curTime) throws SVGException, IOException { -// if (trackManager.getNumTracks() == 0) return false; boolean changeState = super.updateTime(curTime); - - //Get current values for parameters StyleAttribute sty = new StyleAttribute(); boolean shapeChange = false; - if (getPres(sty.setName("cx"))) { float newCx = sty.getFloatValueWithUnits(); if (newCx != cx) { @@ -132,7 +79,6 @@ public class Ellipse extends ShapeElement { shapeChange = true; } } - if (getPres(sty.setName("cy"))) { float newCy = sty.getFloatValueWithUnits(); if (newCy != cy) { @@ -140,7 +86,6 @@ public class Ellipse extends ShapeElement { shapeChange = true; } } - if (getPres(sty.setName("rx"))) { float newRx = sty.getFloatValueWithUnits(); if (newRx != rx) { @@ -148,7 +93,6 @@ public class Ellipse extends ShapeElement { shapeChange = true; } } - if (getPres(sty.setName("ry"))) { float newRy = sty.getFloatValueWithUnits(); if (newRy != ry) { @@ -156,13 +100,9 @@ public class Ellipse extends ShapeElement { shapeChange = true; } } - if (shapeChange) { build(); -// ellipse.setFrame(cx - rx, cy - ry, rx * 2f, ry * 2f); -// return true; } - return changeState || shapeChange; } } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/element/FillElement.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/FillElement.java new file mode 100644 index 0000000..d45df06 --- /dev/null +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/FillElement.java @@ -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); +} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/Filter.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/Filter.java similarity index 90% rename from graphics-svg/src/main/java/org/xbib/graphics/svg/Filter.java rename to graphics-svg/src/main/java/org/xbib/graphics/svg/element/Filter.java index 7132c69..6b6b564 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/Filter.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/Filter.java @@ -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 java.awt.geom.Point2D; import java.io.IOException; import java.net.URI; import java.net.URL; import java.util.ArrayList; +import java.util.List; public class Filter extends SVGElement { 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 = new ArrayList<>(); - /** - * Creates a new instance of FillElement - */ + public static final int FU_OBJECT_BOUNDING_BOX = 0; + + 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 = new ArrayList<>(); + public Filter() { } @@ -36,14 +48,9 @@ public class Filter extends SVGElement { 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((FilterEffects) child); } @@ -52,10 +59,8 @@ public class Filter extends SVGElement { @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")) { @@ -64,7 +69,6 @@ public class Filter extends SVGElement { filterUnits = FU_OBJECT_BOUNDING_BOX; } } - if (getPres(sty.setName("primitiveUnits"))) { strn = sty.getStringValue().toLowerCase(); if (strn.equals("userspaceonuse")) { @@ -73,23 +77,18 @@ public class Filter extends SVGElement { primitiveUnits = PU_OBJECT_BOUNDING_BOX; } } - if (getPres(sty.setName("x"))) { x = sty.getFloatValueWithUnits(); } - if (getPres(sty.setName("y"))) { y = sty.getFloatValueWithUnits(); } - if (getPres(sty.setName("width"))) { width = sty.getFloatValueWithUnits(); } - if (getPres(sty.setName("height"))) { height = sty.getFloatValueWithUnits(); } - try { if (getPres(sty.setName("xlink:href"))) { URI src = sty.getURIValue(getXMLBase()); @@ -119,12 +118,8 @@ public class Filter extends SVGElement { @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) { @@ -132,7 +127,6 @@ public class Filter extends SVGElement { stateChange = true; } } - if (getPres(sty.setName("y"))) { float newVal = sty.getFloatValueWithUnits(); if (newVal != y) { @@ -140,7 +134,6 @@ public class Filter extends SVGElement { stateChange = true; } } - if (getPres(sty.setName("width"))) { float newVal = sty.getFloatValueWithUnits(); if (newVal != width) { @@ -148,7 +141,6 @@ public class Filter extends SVGElement { stateChange = true; } } - if (getPres(sty.setName("height"))) { float newVal = sty.getFloatValueWithUnits(); if (newVal != height) { @@ -156,7 +148,6 @@ public class Filter extends SVGElement { stateChange = true; } } - try { if (getPres(sty.setName("xlink:href"))) { URI src = sty.getURIValue(getXMLBase()); @@ -170,7 +161,6 @@ public class Filter extends SVGElement { } catch (Exception e) { throw new SVGException(e); } - if (getPres(sty.setName("filterUnits"))) { int newVal; String strn = sty.getStringValue().toLowerCase(); @@ -184,7 +174,6 @@ public class Filter extends SVGElement { stateChange = true; } } - if (getPres(sty.setName("primitiveUnits"))) { int newVal; String strn = sty.getStringValue().toLowerCase(); @@ -198,8 +187,6 @@ public class Filter extends SVGElement { stateChange = true; } } - - return stateChange; } } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/Font.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/Font.java similarity index 89% rename from graphics-svg/src/main/java/org/xbib/graphics/svg/Font.java rename to graphics-svg/src/main/java/org/xbib/graphics/svg/element/Font.java index 066d26c..c74fb30 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/Font.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/Font.java @@ -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 java.io.IOException; diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/Group.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/Group.java similarity index 91% rename from graphics-svg/src/main/java/org/xbib/graphics/svg/Group.java rename to graphics-svg/src/main/java/org/xbib/graphics/svg/element/Group.java index 6c0e941..b44195a 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/Group.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/Group.java @@ -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 java.awt.Graphics2D; @@ -18,6 +21,7 @@ public class Group extends ShapeElement { public static final String TAG_NAME = "group"; Rectangle2D boundingBox; + Shape cachedShape; public Group() { @@ -43,7 +47,7 @@ public class Group extends ShapeElement { } @Override - protected void doPick(Point2D point, boolean boundingBox, List> retVec) throws SVGException, IOException { + public void doPick(Point2D point, boolean boundingBox, List> retVec) throws SVGException, IOException { Point2D xPoint = new Point2D.Double(point.getX(), point.getY()); if (xform != null) { try { @@ -61,7 +65,7 @@ public class Group extends ShapeElement { } @Override - protected void doPick(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List> retVec) throws SVGException, IOException { + public void doPick(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List> retVec) throws SVGException, IOException { if (xform != null) { ltw = new AffineTransform(ltw); ltw.concatenate(xform); @@ -75,7 +79,7 @@ public class Group extends ShapeElement { } @Override - protected void doRender(Graphics2D g) throws SVGException, IOException { + public void doRender(Graphics2D g) throws SVGException, IOException { StyleAttribute styleAttrib = new StyleAttribute(); if (getStyle(styleAttrib.setName("display"))) { if (styleAttrib.getStringValue().equals("none")) { diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/Line.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/Line.java similarity index 54% rename from graphics-svg/src/main/java/org/xbib/graphics/svg/Line.java rename to graphics-svg/src/main/java/org/xbib/graphics/svg/element/Line.java index 51065c2..f84bf2f 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/Line.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/Line.java @@ -1,40 +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, 5:25 PM - */ -package org.xbib.graphics.svg; +package org.xbib.graphics.svg.element; +import org.xbib.graphics.svg.SVGException; +import org.xbib.graphics.svg.element.ShapeElement; import org.xbib.graphics.svg.xml.StyleAttribute; import java.awt.Graphics2D; @@ -43,22 +10,20 @@ import java.awt.geom.Line2D; import java.awt.geom.Rectangle2D; import java.io.IOException; -/** - * @author Mark McKay - * @author Mark McKay - */ public class Line extends ShapeElement { + public static final String TAG_NAME = "line"; float x1 = 0f; + float y1 = 0f; + float x2 = 0f; + float y2 = 0f; + Line2D.Float line; - /** - * Creates a new instance of Rect - */ public Line() { } @@ -70,30 +35,24 @@ public class Line extends ShapeElement { @Override protected void build() throws SVGException, IOException { super.build(); - StyleAttribute sty = new StyleAttribute(); - if (getPres(sty.setName("x1"))) { x1 = sty.getFloatValueWithUnits(); } - if (getPres(sty.setName("y1"))) { y1 = sty.getFloatValueWithUnits(); } - if (getPres(sty.setName("x2"))) { x2 = sty.getFloatValueWithUnits(); } - if (getPres(sty.setName("y2"))) { y2 = sty.getFloatValueWithUnits(); } - line = new Line2D.Float(x1, y1, x2, y2); } @Override - protected void doRender(Graphics2D g) throws SVGException, IOException { + public void doRender(Graphics2D g) throws SVGException, IOException { beginLayer(g); renderShape(g, line); finishLayer(g); @@ -109,22 +68,11 @@ public class Line extends ShapeElement { 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 public boolean updateTime(double curTime) throws SVGException, IOException { -// if (trackManager.getNumTracks() == 0) return false; boolean changeState = super.updateTime(curTime); - - //Get current values for parameters StyleAttribute sty = new StyleAttribute(); boolean shapeChange = false; - if (getPres(sty.setName("x1"))) { float newVal = sty.getFloatValueWithUnits(); if (newVal != x1) { @@ -132,7 +80,6 @@ public class Line extends ShapeElement { shapeChange = true; } } - if (getPres(sty.setName("y1"))) { float newVal = sty.getFloatValueWithUnits(); if (newVal != y1) { @@ -140,7 +87,6 @@ public class Line extends ShapeElement { shapeChange = true; } } - if (getPres(sty.setName("x2"))) { float newVal = sty.getFloatValueWithUnits(); if (newVal != x2) { @@ -148,7 +94,6 @@ public class Line extends ShapeElement { shapeChange = true; } } - if (getPres(sty.setName("y2"))) { float newVal = sty.getFloatValueWithUnits(); if (newVal != y2) { @@ -156,11 +101,9 @@ public class Line extends ShapeElement { shapeChange = true; } } - if (shapeChange) { build(); } - return changeState || shapeChange; } } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/Mask.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/Mask.java similarity index 63% rename from graphics-svg/src/main/java/org/xbib/graphics/svg/Mask.java rename to graphics-svg/src/main/java/org/xbib/graphics/svg/element/Mask.java index 49622f5..b3ac8ff 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/Mask.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/Mask.java @@ -1,37 +1,10 @@ -/* - * 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; +package org.xbib.graphics.svg.element; + +import org.xbib.graphics.svg.SVGException; +import org.xbib.graphics.svg.element.Group; +import org.xbib.graphics.svg.element.RenderableElement; +import org.xbib.graphics.svg.element.SVGElement; +import org.xbib.graphics.svg.util.PaintUtil; import java.awt.Color; import java.awt.Composite; @@ -50,12 +23,8 @@ import java.awt.image.WritableRaster; import java.io.IOException; import java.util.List; -/** - * Implements the mask element. - * - * @author Jannis Weis - */ public class Mask extends Group { + public static final String TAG_NAME = "mask"; @Override @@ -72,11 +41,11 @@ public class Mask extends Group { } @Override - void pick(Point2D point, boolean boundingBox, List> retVec) { + public void pick(Point2D point, boolean boundingBox, List> retVec) { } @Override - void pick(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List> retVec) { + public void pick(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List> retVec) { } public void pickElement(Point2D point, boolean boundingBox, @@ -85,8 +54,7 @@ public class Mask extends Group { element.doPick(point, true, retVec); } else { Rectangle pickPoint = new Rectangle((int) point.getX(), (int) point.getY(), 1, 1); - BufferedImage img = BufferPainter.paintToBuffer(null, new AffineTransform(), pickPoint, this, Color.BLACK); - // Only try picking the element if the picked point is visible. + BufferedImage img = PaintUtil.paintToBuffer(null, new AffineTransform(), pickPoint, this, Color.BLACK); if (luminanceToAlpha(img.getRGB(0, 0)) > 0) { element.doPick(point, false, retVec); } @@ -95,22 +63,22 @@ public class Mask extends Group { public void pickElement(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List> retVec, RenderableElement element) throws SVGException, IOException { - // If at any point the considered picking area becomes empty we break out early. - if (pickArea.isEmpty()) return; + if (pickArea.isEmpty()) { + return; + } if (boundingBox) { element.doPick(pickArea, ltw, true, retVec); } else { - // Clip with the element bounds to avoid creating a larger buffer than needed. Area transformedBounds = new Area(ltw.createTransformedShape(element.getBoundingBox())); transformedBounds.intersect(new Area(pickArea)); - if (transformedBounds.isEmpty()) return; - + if (transformedBounds.isEmpty()) { + return; + } Rectangle pickRect = transformedBounds.getBounds(); - if (pickRect.isEmpty()) return; - - BufferedImage maskArea = BufferPainter.paintToBuffer(null, ltw, pickRect, this, Color.BLACK); - - // Pick if any pixel in the pick area is visible. + if (pickRect.isEmpty()) { + return; + } + BufferedImage maskArea = PaintUtil.paintToBuffer(null, ltw, pickRect, this, Color.BLACK); if (hasVisiblePixel(maskArea)) { 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) { - // Assuming 'linearRGB' as the 'color-interpolation' value of the mask. 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) { assert dstIn == dstOut; assert src.getNumBands() == dstIn.getNumBands(); - int x = dstOut.getMinX(); int w = dstOut.getWidth(); int y = dstOut.getMinY(); diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/RenderableElement.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/RenderableElement.java similarity index 76% rename from graphics-svg/src/main/java/org/xbib/graphics/svg/RenderableElement.java rename to graphics-svg/src/main/java/org/xbib/graphics/svg/element/RenderableElement.java index 3f19363..0673991 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/RenderableElement.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/RenderableElement.java @@ -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 java.awt.Graphics2D; @@ -12,23 +15,23 @@ import java.io.IOException; import java.net.URI; 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_NON_SCALING_STROKE = 1; - int vectorEffect; + protected int vectorEffect; - private BufferPainter.Cache bufferCache; + private PaintCache bufferCache; public RenderableElement() { } @@ -37,11 +40,11 @@ abstract public class RenderableElement extends TransformableElement { super(id, parent); } - BufferPainter.Cache getBufferCache() { + public PaintCache getBufferCache() { return bufferCache; } - void setBufferImage(BufferPainter.Cache bufferCache) { + public void setBufferImage(PaintCache bufferCache) { this.bufferCache = bufferCache; } @@ -63,36 +66,12 @@ abstract public class RenderableElement extends TransformableElement { } public void render(Graphics2D g) throws SVGException, IOException { - BufferPainter.paintElement(g, this); + PaintUtil.paintElement(g, this); } - 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; - } + public abstract void doRender(Graphics2D g) throws SVGException, IOException; - 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; - } - - abstract protected void doRender(Graphics2D g) throws SVGException, IOException; - - void pick(Point2D point, boolean boundingBox, List> retVec) throws SVGException, IOException { + public void pick(Point2D point, boolean boundingBox, List> retVec) throws SVGException, IOException { if (cachedMask != null) { cachedMask.pickElement(point, boundingBox, retVec, this); } else { @@ -100,9 +79,9 @@ abstract public class RenderableElement extends TransformableElement { } } - protected abstract void doPick(Point2D point, boolean boundingBox, List> retVec) throws SVGException, IOException; + public abstract void doPick(Point2D point, boolean boundingBox, List> retVec) throws SVGException, IOException; - void pick(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List> retVec) throws SVGException, IOException { + public void pick(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List> retVec) throws SVGException, IOException { if (cachedMask != null) { cachedMask.pickElement(pickArea, ltw, boundingBox, retVec, this); } else { @@ -110,9 +89,9 @@ abstract public class RenderableElement extends TransformableElement { } } - protected abstract void doPick(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List> retVec) throws SVGException, IOException; + public abstract void doPick(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List> retVec) throws SVGException, IOException; - abstract public Rectangle2D getBoundingBox() throws SVGException; + public abstract Rectangle2D getBoundingBox() throws SVGException; protected void beginLayer(Graphics2D g) throws SVGException { if (xform != null) { @@ -157,4 +136,28 @@ abstract public class RenderableElement extends TransformableElement { 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; + } } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGElement.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/SVGElement.java similarity index 95% rename from graphics-svg/src/main/java/org/xbib/graphics/svg/SVGElement.java rename to graphics-svg/src/main/java/org/xbib/graphics/svg/element/SVGElement.java index 9c2dc18..21237e4 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/SVGElement.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/SVGElement.java @@ -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.PathCommand; import org.xbib.graphics.svg.pathcmd.PathParser; @@ -22,10 +28,12 @@ import java.util.Set; import java.util.regex.Matcher; 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"; + LinkedList contexts = new LinkedList<>(); + protected SVGElement parent; protected final ArrayList children = new ArrayList<>(); @@ -58,7 +66,7 @@ abstract public class SVGElement { this.parent = parent; } - abstract public String getTagName(); + public abstract String getTagName(); public SVGElement getParent() { return parent; @@ -81,11 +89,9 @@ abstract public class SVGElement { public List getChildren(List retVec) { if (retVec == null) { - retVec = new ArrayList(); + retVec = new ArrayList<>(); } - retVec.addAll(children); - return retVec; } @@ -157,7 +163,7 @@ abstract public class SVGElement { child.setDiagram(diagram); } - protected void setDiagram(SVGDiagram diagram) { + public void setDiagram(SVGDiagram diagram) { this.diagram = diagram; diagram.setElement(id, this); for (SVGElement ele : children) { @@ -207,17 +213,15 @@ abstract public class SVGElement { return id; } - LinkedList contexts = new LinkedList<>(); - - protected void pushParentContext(SVGElement context) { + public void pushParentContext(SVGElement context) { contexts.addLast(context); } - protected SVGElement popParentContext() { + public SVGElement popParentContext() { return contexts.removeLast(); } - protected SVGElement getParentContext() { + public SVGElement getParentContext() { return contexts.isEmpty() ? null : contexts.getLast(); } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/ShapeElement.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/ShapeElement.java similarity index 93% rename from graphics-svg/src/main/java/org/xbib/graphics/svg/ShapeElement.java rename to graphics-svg/src/main/java/org/xbib/graphics/svg/element/ShapeElement.java index a458d91..f42564e 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/ShapeElement.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/ShapeElement.java @@ -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.MarkerPos; +import org.xbib.graphics.svg.Marker; +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 java.awt.AlphaComposite; @@ -18,7 +20,7 @@ import java.io.IOException; import java.net.URI; import java.util.List; -abstract public class ShapeElement extends RenderableElement { +public abstract class ShapeElement extends RenderableElement { protected float strokeWidthScalar = 1f; @@ -26,36 +28,22 @@ abstract public class ShapeElement extends RenderableElement { } @Override - abstract protected void doRender(Graphics2D g) throws SVGException, IOException; + public abstract void doRender(Graphics2D g) throws SVGException, IOException; @Override - protected void doPick(Point2D point, boolean boundingBox, List> retVec) throws SVGException, IOException { + public void doPick(Point2D point, boolean boundingBox, List> retVec) throws SVGException, IOException { if ((boundingBox ? getBoundingBox() : getShape()).contains(point)) { retVec.add(getPath(null)); } } @Override - protected void doPick(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List> retVec) throws SVGException, IOException { + public void doPick(Rectangle2D pickArea, AffineTransform ltw, boolean boundingBox, List> retVec) throws SVGException, IOException { if (ltw.createTransformedShape((boundingBox ? getBoundingBox() : getShape())).intersects(pickArea)) { 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 { StyleAttribute styleAttrib = new StyleAttribute(); if (getStyle(styleAttrib.setName("visibility"))) { @@ -229,7 +217,7 @@ abstract public class ShapeElement extends RenderableElement { layout.layout(shape); List list = layout.getMarkerList(); for (MarkerPos pos : list) { - switch (pos.type) { + switch (pos.getType()) { case Marker.MARKER_START: if (markerStart != null) { 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 { StyleAttribute styleAttrib = new StyleAttribute(); @@ -267,4 +255,18 @@ abstract public class ShapeElement extends RenderableElement { rect.getHeight() + strokeWidth); 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(); + } + } } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/Style.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/Style.java similarity index 86% rename from graphics-svg/src/main/java/org/xbib/graphics/svg/Style.java rename to graphics-svg/src/main/java/org/xbib/graphics/svg/element/Style.java index 233b075..2d84d2e 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/Style.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/Style.java @@ -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.StyleSheet; diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/element/TransformableElement.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/TransformableElement.java new file mode 100644 index 0000000..82d6b50 --- /dev/null +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/TransformableElement.java @@ -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(); + } +} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/DistantLight.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/DistantLight.java new file mode 100644 index 0000000..8fadef6 --- /dev/null +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/DistantLight.java @@ -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; + } +} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/FilterEffects.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/FilterEffects.java new file mode 100644 index 0000000..f1c6fd2 --- /dev/null +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/FilterEffects.java @@ -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 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; + } +} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/FilterOp.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/FilterOp.java new file mode 100644 index 0000000..67c84a6 --- /dev/null +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/FilterOp.java @@ -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; + } +} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/FeGaussianBlur.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/GaussianBlur.java similarity index 95% rename from graphics-svg/src/main/java/org/xbib/graphics/svg/FeGaussianBlur.java rename to graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/GaussianBlur.java index 271b284..859c0b8 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/FeGaussianBlur.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/GaussianBlur.java @@ -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 java.awt.Rectangle; @@ -9,13 +10,18 @@ import java.io.IOException; import java.util.Arrays; import java.util.List; -public class FeGaussianBlur extends FilterEffects { +public class GaussianBlur extends FilterEffects { + public static final String TAG_NAME = "fegaussianblur"; private float[] stdDeviation; + private float xCurrent; + private float yCurrent; + private ConvolveOp xBlur; + private ConvolveOp yBlur; @Override @@ -27,7 +33,6 @@ public class FeGaussianBlur extends FilterEffects { protected void build() throws SVGException, IOException { super.build(); StyleAttribute sty = new StyleAttribute(); - stdDeviation = new float[]{0f}; if (getPres(sty.setName("stdDeviation"))) { stdDeviation = sty.getFloatList(); @@ -40,7 +45,6 @@ public class FeGaussianBlur extends FilterEffects { public List getOperations(Rectangle inputBounds, float xScale, float yScale) { float xSigma = xScale * stdDeviation[0]; float ySigma = yScale * stdDeviation[Math.min(stdDeviation.length - 1, 1)]; - return Arrays.asList( xSigma > 0 ? getGaussianBlurFilter(inputBounds, xSigma, true) @@ -63,41 +67,34 @@ public class FeGaussianBlur extends FilterEffects { yCurrent = sigma; } float[] data = new float[size]; - float radius2 = radius * radius; float twoSigmaSquare = 2.0f * sigma * sigma; float sigmaRoot = (float) Math.sqrt(twoSigmaSquare * Math.PI); float total = 0.0f; - float middle = size / 2f; for (int i = 0; i < size; i++) { float distance = middle - i; distance *= distance; - data[i] = distance > radius2 ? 0 : (float) Math.exp(-distance / twoSigmaSquare) / sigmaRoot; total += data[i]; } - for (int i = 0; i < data.length; i++) { data[i] /= total; } - if (horizontal) { xBlur = new ConvolveOp(new Kernel(size, 1, data), ConvolveOp.EDGE_NO_OP, null); } else { yBlur = new ConvolveOp(new Kernel(1, size, data), ConvolveOp.EDGE_NO_OP, null); } } - Rectangle dstBounds = new Rectangle(inputBounds); if (horizontal) { dstBounds.grow(size, 0); } else { dstBounds.grow(0, size); } - return new FilterOp(horizontal ? xBlur : yBlur, dstBounds); } } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/Light.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/Light.java new file mode 100644 index 0000000..bf5eb06 --- /dev/null +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/Light.java @@ -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; + } +} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/PointLight.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/PointLight.java new file mode 100644 index 0000000..d881d2d --- /dev/null +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/PointLight.java @@ -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; + } +} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/FeSpotLight.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/SpotLight.java similarity index 67% rename from graphics-svg/src/main/java/org/xbib/graphics/svg/FeSpotLight.java rename to graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/SpotLight.java index 8836ee9..260c406 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/FeSpotLight.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/filtereffects/SpotLight.java @@ -1,65 +1,29 @@ -/* - * 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; +package org.xbib.graphics.svg.element.filtereffects; +import org.xbib.graphics.svg.SVGException; import org.xbib.graphics.svg.xml.StyleAttribute; import java.io.IOException; -/** - * @author Mark McKay - * @author Mark McKay - */ -public class FeSpotLight extends FeLight { +public class SpotLight extends Light { 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; - /** - * Creates a new instance of FillElement - */ - public 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; @Override public String getTagName() { @@ -69,9 +33,7 @@ public class FeSpotLight extends FeLight { @Override protected void build() throws SVGException, IOException { super.build(); - StyleAttribute sty = new StyleAttribute(); - if (getPres(sty.setName("x"))) { x = sty.getFloatValueWithUnits(); } @@ -134,12 +96,8 @@ public class FeSpotLight extends FeLight { @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) { @@ -147,7 +105,6 @@ public class FeSpotLight extends FeLight { stateChange = true; } } - if (getPres(sty.setName("y"))) { float newVal = sty.getFloatValueWithUnits(); if (newVal != y) { @@ -155,7 +112,6 @@ public class FeSpotLight extends FeLight { stateChange = true; } } - if (getPres(sty.setName("z"))) { float newVal = sty.getFloatValueWithUnits(); if (newVal != z) { @@ -163,7 +119,6 @@ public class FeSpotLight extends FeLight { stateChange = true; } } - if (getPres(sty.setName("pointsAtX"))) { float newVal = sty.getFloatValueWithUnits(); if (newVal != pointsAtX) { @@ -171,7 +126,6 @@ public class FeSpotLight extends FeLight { stateChange = true; } } - if (getPres(sty.setName("pointsAtY"))) { float newVal = sty.getFloatValueWithUnits(); if (newVal != pointsAtY) { @@ -179,7 +133,6 @@ public class FeSpotLight extends FeLight { stateChange = true; } } - if (getPres(sty.setName("pointsAtZ"))) { float newVal = sty.getFloatValueWithUnits(); if (newVal != pointsAtZ) { @@ -187,7 +140,6 @@ public class FeSpotLight extends FeLight { stateChange = true; } } - if (getPres(sty.setName("specularComponent"))) { float newVal = sty.getFloatValueWithUnits(); if (newVal != specularComponent) { @@ -195,7 +147,6 @@ public class FeSpotLight extends FeLight { stateChange = true; } } - if (getPres(sty.setName("limitingConeAngle"))) { float newVal = sty.getFloatValueWithUnits(); if (newVal != limitingConeAngle) { @@ -203,7 +154,6 @@ public class FeSpotLight extends FeLight { stateChange = true; } } - return stateChange; } } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/element/glyph/Glyph.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/glyph/Glyph.java new file mode 100644 index 0000000..c227535 --- /dev/null +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/glyph/Glyph.java @@ -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; + } +} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/MissingGlyph.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/glyph/MissingGlyph.java similarity index 90% rename from graphics-svg/src/main/java/org/xbib/graphics/svg/MissingGlyph.java rename to graphics-svg/src/main/java/org/xbib/graphics/svg/element/glyph/MissingGlyph.java index dad6214..fc33cb4 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/MissingGlyph.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/glyph/MissingGlyph.java @@ -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.PathCommand; import org.xbib.graphics.svg.xml.StyleAttribute; @@ -18,8 +25,11 @@ public class MissingGlyph extends ShapeElement { private Shape path = null; private float horizAdvX = -1; + private float vertOriginX = -1; + private float vertOriginY = -1; + private float vertAdvY = -1; public MissingGlyph() { @@ -78,7 +88,7 @@ public class MissingGlyph extends ShapeElement { } @Override - protected void doRender(Graphics2D g) throws SVGException, IOException { + public void doRender(Graphics2D g) throws SVGException, IOException { if (path != null) { renderShape(g, path); } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/Gradient.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/gradient/Gradient.java similarity index 57% rename from graphics-svg/src/main/java/org/xbib/graphics/svg/Gradient.java rename to graphics-svg/src/main/java/org/xbib/graphics/svg/element/gradient/Gradient.java index 68e94ba..7b681a5 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/Gradient.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/gradient/Gradient.java @@ -1,40 +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, 3:25 AM - */ -package org.xbib.graphics.svg; +package org.xbib.graphics.svg.element.gradient; +import org.xbib.graphics.svg.SVGElementException; +import org.xbib.graphics.svg.SVGException; +import org.xbib.graphics.svg.SVGLoaderHelper; +import org.xbib.graphics.svg.Stop; +import org.xbib.graphics.svg.element.FillElement; +import org.xbib.graphics.svg.element.SVGElement; import org.xbib.graphics.svg.xml.StyleAttribute; import java.awt.Color; @@ -42,37 +13,36 @@ import java.awt.geom.AffineTransform; import java.io.IOException; import java.net.URI; import java.util.ArrayList; -import java.util.Comparator; -import java.util.logging.Level; -import java.util.logging.Logger; +import java.util.List; + +public abstract class Gradient extends FillElement { -/** - * @author Mark McKay - * @author Mark McKay - */ -abstract public class Gradient extends FillElement { public static final String TAG_NAME = "gradient"; public static final int SM_PAD = 0; + public static final int SM_REPEAT = 1; + 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_USER_SPACE_ON_USE = 1; + 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 - ArrayList stops = new ArrayList(); + + List stops = new ArrayList<>(); + URI stopRef = null; + protected AffineTransform gradientTransform = null; - //Cache arrays of stop values here float[] stopFractions; + Color[] stopColors; - /** - * Creates a new instance of Gradient - */ public Gradient() { } @@ -81,14 +51,9 @@ abstract public class Gradient extends FillElement { 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 Stop)) { return; } @@ -98,10 +63,8 @@ abstract public class Gradient extends FillElement { @Override protected void build() throws SVGException, IOException { super.build(); - StyleAttribute sty = new StyleAttribute(); String strn; - if (getPres(sty.setName("spreadMethod"))) { strn = sty.getStringValue().toLowerCase(); if (strn.equals("repeat")) { @@ -112,7 +75,6 @@ abstract public class Gradient extends FillElement { spreadMethod = SM_PAD; } } - if (getPres(sty.setName("gradientUnits"))) { strn = sty.getStringValue().toLowerCase(); if (strn.equals("userspaceonuse")) { @@ -121,23 +83,15 @@ abstract public class Gradient extends FillElement { gradientUnits = GU_OBJECT_BOUNDING_BOX; } } - if (getPres(sty.setName("gradientTransform"))) { gradientTransform = parseTransform(sty.getStringValue()); } - //If we still don't have one, set it to identity if (gradientTransform == null) { gradientTransform = new AffineTransform(); } - - - //Check to see if we're using our own stops or referencing someone else's if (getPres(sty.setName("xlink:href"))) { try { 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) { 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() { - ArrayList stopList = new ArrayList(stops); - stopList.sort(new Comparator() { - public int compare(Stop o1, Stop o2) { - return Float.compare(o1.offset, o2.offset); - } - }); - - //Remove doubles + ArrayList stopList = new ArrayList<>(stops); + stopList.sort((o1, o2) -> Float.compare(o1.offset, o2.offset)); for (int i = stopList.size() - 2; i >= 0; --i) { if (stopList.get(i + 1).offset == stopList.get(i).offset) { stopList.remove(i + 1); } } - - stopFractions = new float[stopList.size()]; stopColors = new Color[stopList.size()]; int idx = 0; for (Stop stop : stopList) { int stopColorVal = stop.color.getRGB(); Color stopColor = new Color((stopColorVal >> 16) & 0xff, (stopColorVal >> 8) & 0xff, stopColorVal & 0xff, clamp((int) (stop.opacity * 255), 0, 255)); - stopColors[idx] = stopColor; stopFractions[idx] = stop.offset; idx++; } - } public float[] getStopFractions() { @@ -179,13 +123,10 @@ abstract public class Gradient extends FillElement { Gradient grad = (Gradient) diagram.getUniverse().getElement(stopRef); return grad.getStopFractions(); } - if (stopFractions != null) { return stopFractions; } - buildStops(); - return stopFractions; } @@ -194,36 +135,18 @@ abstract public class Gradient extends FillElement { Gradient grad = (Gradient) diagram.getUniverse().getElement(stopRef); return grad.getStopColors(); } - if (stopColors != null) { return stopColors; } - buildStops(); - 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) { if (val < min) { return min; } - if (val > max) { - return max; - } - return val; + return Math.min(val, max); } public void setStopRef(URI grad) { @@ -234,23 +157,11 @@ abstract public class Gradient extends FillElement { 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 public boolean updateTime(double curTime) throws SVGException { -// if (trackManager.getNumTracks() == 0) return false; boolean stateChange = false; - - //Get current values for parameters StyleAttribute sty = new StyleAttribute(); String strn; - - if (getPres(sty.setName("spreadMethod"))) { int newVal; strn = sty.getStringValue().toLowerCase(); @@ -266,7 +177,6 @@ abstract public class Gradient extends FillElement { stateChange = true; } } - if (getPres(sty.setName("gradientUnits"))) { int newVal; strn = sty.getStringValue().toLowerCase(); @@ -280,31 +190,20 @@ abstract public class Gradient extends FillElement { stateChange = true; } } - if (getPres(sty.setName("gradientTransform"))) { AffineTransform newVal = parseTransform(sty.getStringValue()); - if (newVal != null && newVal.equals(gradientTransform)) { + if (newVal.equals(gradientTransform)) { gradientTransform = newVal; stateChange = true; } } - - - //Check to see if we're using our own stops or referencing someone else's if (getPres(sty.setName("xlink:href"))) { - try { - URI newVal = sty.getURIValue(getXMLBase()); - if ((newVal == null && stopRef != null) || !newVal.equals(stopRef)) { - stopRef = newVal; - stateChange = true; - } - } catch (Exception e) { - Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, - "Could not parse xlink:href", e); + URI newVal = sty.getURIValue(getXMLBase()); + if ((newVal == null && stopRef != null) || !newVal.equals(stopRef)) { + stopRef = newVal; + stateChange = true; } } - - //Check stops, if any for (Stop stop : stops) { if (stop.updateTime(curTime)) { stateChange = true; @@ -312,7 +211,6 @@ abstract public class Gradient extends FillElement { stopColors = null; } } - return stateChange; } } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/LinearGradient.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/gradient/LinearGradient.java similarity index 65% rename from graphics-svg/src/main/java/org/xbib/graphics/svg/LinearGradient.java rename to graphics-svg/src/main/java/org/xbib/graphics/svg/element/gradient/LinearGradient.java index ff442d8..fa9b44a 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/LinearGradient.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/gradient/LinearGradient.java @@ -1,40 +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, 1:54 AM - */ -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 java.awt.Color; @@ -46,21 +13,18 @@ import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.io.IOException; -/** - * @author Mark McKay - * @author Mark McKay - */ public class LinearGradient extends Gradient { + public static final String TAG_NAME = "lineargradient"; float x1 = 0f; + float y1 = 0f; + float x2 = 1f; + float y2 = 0f; - /** - * Creates a new instance of LinearGradient - */ public LinearGradient() { } @@ -72,21 +36,16 @@ public class LinearGradient extends Gradient { @Override protected void build() throws SVGException, IOException { super.build(); - StyleAttribute sty = new StyleAttribute(); - if (getPres(sty.setName("x1"))) { x1 = sty.getFloatValueWithUnits(); } - if (getPres(sty.setName("y1"))) { y1 = sty.getFloatValueWithUnits(); } - if (getPres(sty.setName("x2"))) { x2 = sty.getFloatValueWithUnits(); } - if (getPres(sty.setName("y2"))) { y2 = sty.getFloatValueWithUnits(); } @@ -107,7 +66,6 @@ public class LinearGradient extends Gradient { method = MultipleGradientPaint.CycleMethod.REFLECT; break; } - Paint paint; Point2D.Float pt1 = new Point2D.Float(x1, y1); Point2D.Float pt2 = new Point2D.Float(x2, y2); @@ -128,16 +86,12 @@ public class LinearGradient extends Gradient { } else { AffineTransform viewXform = new AffineTransform(); 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 height = Math.max(1, bounds.getHeight()); viewXform.scale(width, height); - if (gradientTransform != null) { viewXform.concatenate(gradientTransform); } - paint = new LinearGradientPaint( pt1, pt2, @@ -147,26 +101,14 @@ public class LinearGradient extends Gradient { MultipleGradientPaint.ColorSpaceType.SRGB, viewXform); } - 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 public boolean updateTime(double curTime) throws SVGException { -// if (trackManager.getNumTracks() == 0) return stopChange; boolean changeState = super.updateTime(curTime); - - //Get current values for parameters StyleAttribute sty = new StyleAttribute(); boolean shapeChange = false; - if (getPres(sty.setName("x1"))) { float newVal = sty.getFloatValueWithUnits(); if (newVal != x1) { @@ -174,7 +116,6 @@ public class LinearGradient extends Gradient { shapeChange = true; } } - if (getPres(sty.setName("y1"))) { float newVal = sty.getFloatValueWithUnits(); if (newVal != y1) { @@ -182,7 +123,6 @@ public class LinearGradient extends Gradient { shapeChange = true; } } - if (getPres(sty.setName("x2"))) { float newVal = sty.getFloatValueWithUnits(); if (newVal != x2) { @@ -190,7 +130,6 @@ public class LinearGradient extends Gradient { shapeChange = true; } } - if (getPres(sty.setName("y2"))) { float newVal = sty.getFloatValueWithUnits(); if (newVal != y2) { @@ -198,7 +137,6 @@ public class LinearGradient extends Gradient { shapeChange = true; } } - return changeState || shapeChange; } } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/RadialGradient.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/gradient/RadialGradient.java similarity index 96% rename from graphics-svg/src/main/java/org/xbib/graphics/svg/RadialGradient.java rename to graphics-svg/src/main/java/org/xbib/graphics/svg/element/gradient/RadialGradient.java index c707d2b..83ba0cb 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/RadialGradient.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/element/gradient/RadialGradient.java @@ -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 java.awt.Color; diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/Arc.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/Arc.java index 6434fee..93b573a 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/Arc.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/Arc.java @@ -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; -//import org.apache.batik.ext.awt.geom.ExtendedGeneralPath; - import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.geom.Arc2D; 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 Mark McKay - */ public class Arc extends PathCommand { public float rx = 0f; + public float ry = 0f; + public float xAxisRot = 0f; + public boolean largeArc = false; + public boolean sweep = false; + public float x = 0f; + public float y = 0f; - /** - * Creates a new instance of MoveTo - */ public Arc() { } @@ -79,17 +35,13 @@ public class Arc extends PathCommand { this.y = y; } - // public void appendPath(ExtendedGeneralPath path, BuildHistory hist) @Override public void appendPath(GeneralPath path, BuildHistory hist) { float offx = isRelative ? hist.lastPoint.x : 0f; float offy = isRelative ? hist.lastPoint.y : 0f; - arcTo(path, rx, ry, xAxisRot, largeArc, sweep, x + offx, y + offy, 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.setLastKnot(x + offx, y + offy); } @@ -99,107 +51,44 @@ public class Arc extends PathCommand { 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, float angle, boolean largeArcFlag, boolean sweepFlag, float x, float y, float x0, float y0) { - - // Ensure radii are valid if (rx == 0 || ry == 0) { path.lineTo(x, y); return; } - 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; } - - Arc2D arc = computeArc(x0, y0, rx, ry, angle, - largeArcFlag, sweepFlag, x, y); - if (arc == null) return; - + Arc2D arc = computeArc(x0, y0, rx, ry, angle, largeArcFlag, sweepFlag, x, y); AffineTransform t = AffineTransform.getRotateInstance (Math.toRadians(angle), arc.getCenterX(), arc.getCenterY()); Shape s = t.createTransformedShape(arc); 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: - *

- * 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, double rx, double ry, double angle, boolean largeArcFlag, boolean sweepFlag, 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 dy2 = (y0 - y) / 2.0; - // Convert angle from degrees to radians angle = Math.toRadians(angle % 360.0); double cosAngle = Math.cos(angle); double sinAngle = Math.sin(angle); - - // - // Step 1 : Compute (x1, y1) - // double x1 = (cosAngle * dx2 + sinAngle * dy2); double y1 = (-sinAngle * dx2 + cosAngle * dy2); - // Ensure radii are large enough rx = Math.abs(rx); ry = Math.abs(ry); double Prx = rx * rx; double Pry = ry * ry; double Px1 = x1 * x1; double Py1 = y1 * y1; - // check that radii are large enough double radiiCheck = Px1 / Prx + Py1 / Pry; if (radiiCheck > 1) { rx = Math.sqrt(radiiCheck) * rx; @@ -207,40 +96,25 @@ public class Arc extends PathCommand { Prx = rx * rx; Pry = ry * ry; } - - // - // Step 2 : Compute (cx1, cy1) - // double sign = (largeArcFlag == sweepFlag) ? -1 : 1; double sq = ((Prx * Pry) - (Prx * Py1) - (Pry * Px1)) / ((Prx * Py1) + (Pry * Px1)); sq = (sq < 0) ? 0 : sq; double coef = (sign * Math.sqrt(sq)); double cx1 = coef * ((rx * y1) / ry); double cy1 = coef * -((ry * x1) / rx); - - // - // Step 3 : Compute (cx, cy) from (cx1, cy1) - // double sx2 = (x0 + x) / 2.0; double sy2 = (y0 + y) / 2.0; double cx = sx2 + (cosAngle * cx1 - sinAngle * cy1); double cy = sy2 + (sinAngle * cx1 + cosAngle * cy1); - - // - // Step 4 : Compute the angleStart (angle1) and the angleExtent (dangle) - // double ux = (x1 - cx1) / rx; double uy = (y1 - cy1) / ry; double vx = (-x1 - cx1) / rx; double vy = (-y1 - cy1) / ry; double p, n; - // Compute the angle start n = Math.sqrt((ux * ux) + (uy * uy)); - p = ux; // (1 * ux) + (0 * uy) + p = ux; sign = (uy < 0) ? -1d : 1d; double angleStart = Math.toDegrees(sign * Math.acos(p / n)); - - // Compute the angle extent n = Math.sqrt((ux * ux + uy * uy) * (vx * vx + vy * vy)); p = ux * vx + uy * vy; sign = (ux * vy - uy * vx < 0) ? -1d : 1d; @@ -252,10 +126,6 @@ public class Arc extends PathCommand { } angleExtent %= 360f; angleStart %= 360f; - - // - // We can now build the resulting Arc2D in double precision - // Arc2D.Double arc = new Arc2D.Double(); arc.x = cx - rx; arc.y = cy - ry; @@ -263,7 +133,6 @@ public class Arc extends PathCommand { arc.height = ry * 2.0; arc.start = -angleStart; arc.extent = -angleExtent; - return arc; } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/BuildHistory.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/BuildHistory.java index 8ca2a39..b6faf8b 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/BuildHistory.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/BuildHistory.java @@ -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; 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 Mark McKay - */ 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 lastPoint = new Point2D.Float(); Point2D.Float lastKnot = new Point2D.Float(); - boolean init; - //int length = 0; - /** - * Creates a new instance of BuildHistory - */ public BuildHistory() { } @@ -73,19 +22,4 @@ public class BuildHistory { public void setLastKnot(float x, float 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; -// } } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/Cubic.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/Cubic.java index 4e6fbfe..a6ee322 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/Cubic.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/Cubic.java @@ -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; -//import org.apache.batik.ext.awt.geom.ExtendedGeneralPath; - import java.awt.geom.GeneralPath; -/** - * @author Mark McKay - * @author Mark McKay - */ public class Cubic extends PathCommand { public float k1x = 0f; @@ -53,19 +11,9 @@ public class Cubic extends PathCommand { public float x = 0f; public float y = 0f; - /** - * Creates a new instance of MoveTo - */ 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) { super(isRelative); this.k1x = k1x; @@ -76,16 +24,13 @@ public class Cubic extends PathCommand { this.y = y; } - // public void appendPath(ExtendedGeneralPath path, BuildHistory hist) @Override public void appendPath(GeneralPath path, BuildHistory hist) { float offx = isRelative ? hist.lastPoint.x : 0f; float offy = isRelative ? hist.lastPoint.y : 0f; - path.curveTo(k1x + offx, k1y + offy, k2x + offx, k2y + offy, x + offx, y + offy); -// hist.setPointAndKnot(x + offx, y + offy, k2x + offx, k2y + offy); hist.setLastPoint(x + offx, y + offy); hist.setLastKnot(k2x + offx, k2y + offy); } @@ -94,4 +39,11 @@ public class Cubic extends PathCommand { public int getNumKnotsAdded() { return 6; } + + @Override + public String toString() { + return "C " + k1x + " " + k1y + + " " + k2x + " " + k2y + + " " + x + " " + y; + } } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/CubicSmooth.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/CubicSmooth.java index 4330d7e..0a27564 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/CubicSmooth.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/CubicSmooth.java @@ -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; -//import org.apache.batik.ext.awt.geom.ExtendedGeneralPath; - import java.awt.geom.GeneralPath; -/** - * @author Mark McKay - * @author Mark McKay - */ public class CubicSmooth extends PathCommand { public float x = 0f; + public float y = 0f; + public float k2x = 0f; + public float k2y = 0f; - /** - * Creates a new instance of MoveTo - */ public CubicSmooth() { } @@ -65,20 +23,16 @@ public class CubicSmooth extends PathCommand { this.y = y; } - // public void appendPath(ExtendedGeneralPath path, BuildHistory hist) @Override public void appendPath(GeneralPath path, BuildHistory hist) { float offx = isRelative ? hist.lastPoint.x : 0f; float offy = isRelative ? hist.lastPoint.y : 0f; - float oldKx = hist.lastKnot.x; float oldKy = hist.lastKnot.y; float oldX = hist.lastPoint.x; float oldY = hist.lastPoint.y; - //Calc knot as reflection of old knot float k1x = oldX * 2f - oldKx; float k1y = oldY * 2f - oldKy; - path.curveTo(k1x, k1y, k2x + offx, k2y + offy, x + offx, y + offy); hist.setLastPoint(x + offx, y + offy); hist.setLastKnot(k2x + offx, k2y + offy); diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/Horizontal.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/Horizontal.java index 2ddc226..ac8f346 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/Horizontal.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/Horizontal.java @@ -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; -//import org.apache.batik.ext.awt.geom.ExtendedGeneralPath; - import java.awt.geom.GeneralPath; -/** - * @author Mark McKay - * @author Mark McKay - */ public class Horizontal extends PathCommand { public float x = 0f; - /** - * Creates a new instance of MoveTo - */ public Horizontal() { } @@ -64,13 +19,10 @@ public class Horizontal extends PathCommand { this.x = x; } - - // public void appendPath(ExtendedGeneralPath path, BuildHistory hist) @Override public void appendPath(GeneralPath path, BuildHistory hist) { float offx = isRelative ? hist.lastPoint.x : 0f; float offy = hist.lastPoint.y; - path.lineTo(x + offx, offy); hist.setLastPoint(x + offx, offy); hist.setLastKnot(x + offx, offy); diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/LineTo.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/LineTo.java index 6f5ae86..3d48975 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/LineTo.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/LineTo.java @@ -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; -//import org.apache.batik.ext.awt.geom.ExtendedGeneralPath; - import java.awt.geom.GeneralPath; -/** - * @author Mark McKay - * @author Mark McKay - */ public class LineTo extends PathCommand { public float x = 0f; public float y = 0f; - /** - * Creates a new instance of MoveTo - */ public LineTo() { } @@ -61,13 +16,10 @@ public class LineTo extends PathCommand { this.y = y; } - - // public void appendPath(ExtendedGeneralPath path, BuildHistory hist) @Override public void appendPath(GeneralPath path, BuildHistory hist) { float offx = isRelative ? hist.lastPoint.x : 0f; float offy = isRelative ? hist.lastPoint.y : 0f; - path.lineTo(x + offx, y + offy); hist.setLastPoint(x + offx, y + offy); hist.setLastKnot(x + offx, y + offy); diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/MoveTo.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/MoveTo.java index 9541889..1f5d8a8 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/MoveTo.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/MoveTo.java @@ -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; -//import org.apache.batik.ext.awt.geom.ExtendedGeneralPath; - import java.awt.geom.GeneralPath; -/** - * @author Mark McKay - * @author Mark McKay - */ public class MoveTo extends PathCommand { public float x = 0f; + public float y = 0f; - /** - * Creates a new instance of MoveTo - */ public MoveTo() { } @@ -61,12 +17,10 @@ public class MoveTo extends PathCommand { this.y = y; } - // public void appendPath(ExtendedGeneralPath path, BuildHistory hist) @Override public void appendPath(GeneralPath path, BuildHistory hist) { float offx = isRelative ? hist.lastPoint.x : 0f; float offy = isRelative ? hist.lastPoint.y : 0f; - path.moveTo(x + offx, y + offy); hist.setStartPoint(x + offx, y + offy); hist.setLastPoint(x + offx, y + offy); @@ -82,6 +36,4 @@ public class MoveTo extends PathCommand { public String toString() { return "M " + x + " " + y; } - - } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/PathCommand.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/PathCommand.java index b9a3ec6..9286bf3 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/PathCommand.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/PathCommand.java @@ -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; -//import org.apache.batik.ext.awt.geom.ExtendedGeneralPath; - 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 Mark McKay - */ abstract public class PathCommand { public boolean isRelative = false; - /** - * Creates a new instance of PathCommand - */ public PathCommand() { } @@ -61,7 +13,6 @@ abstract public class PathCommand { this.isRelative = isRelative; } - // abstract public void appendPath(ExtendedGeneralPath path, BuildHistory hist); abstract public void appendPath(GeneralPath path, BuildHistory hist); abstract public int getNumKnotsAdded(); diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/PathParser.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/PathParser.java index 5ea6689..ac8692a 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/PathParser.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/PathParser.java @@ -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; import java.util.ArrayList; import java.util.List; -/** - * A helper for parsing {@link PathCommand}s. - * - * @author Jannis Weis - */ public class PathParser { + private final String input; + private final int inputLength; + private int index; + private char currentCommand; public PathParser(String input) { @@ -73,13 +38,9 @@ public class PathParser { 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) { boolean valid = '0' <= c && c <= '9'; if (valid && state.iteration == 1 && input.charAt(index - 1) == '0') { - // Break up combined zeros into multiple numbers. return false; } state.signAllowed = state.signAllowed && !valid; @@ -92,7 +53,6 @@ public class PathParser { state.signAllowed = valid; } if (state.exponentAllowed && !valid) { - // Possible exponent notation. Needs at least one preceding number valid = c == 'e' || c == 'E'; state.exponentAllowed = !valid; state.signAllowed = valid; @@ -128,7 +88,6 @@ public class PathParser { public PathCommand[] parsePathCommand() { List commands = new ArrayList<>(); - currentCommand = 'Z'; while (hasNext()) { char peekChar = peek(); @@ -137,7 +96,6 @@ public class PathParser { currentCommand = peekChar; } consumeWhiteSpaceOrSeparator(); - PathCommand cmd; switch (currentCommand) { case 'M': diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/PathUtil.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/PathUtil.java index 74039b8..fb99552 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/PathUtil.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/PathUtil.java @@ -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; import java.awt.geom.AffineTransform; import java.awt.geom.GeneralPath; import java.awt.geom.PathIterator; -/** - * @author kitfox - */ public class PathUtil { - /** - * Creates a new instance of 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) { float[] coords = new float[6]; - - StringBuffer sb = new StringBuffer(); - + StringBuilder sb = new StringBuilder(); for (PathIterator pathIt = path.getPathIterator(new AffineTransform()); !pathIt.isDone(); pathIt.next()) { int segId = pathIt.currentSegment(coords); - switch (segId) { case PathIterator.SEG_CLOSE: { sb.append(" Z"); @@ -88,7 +37,6 @@ public class PathUtil { } } } - return sb.toString(); } } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/Quadratic.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/Quadratic.java index bce8d81..fbca360 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/Quadratic.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/Quadratic.java @@ -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; -//import org.apache.batik.ext.awt.geom.ExtendedGeneralPath; - import java.awt.geom.GeneralPath; -/** - * @author Mark McKay - * @author Mark McKay - */ public class Quadratic extends PathCommand { public float kx = 0f; + public float ky = 0f; + public float x = 0f; + public float y = 0f; - /** - * Creates a new instance of MoveTo - */ public Quadratic() { } - @Override - public String toString() { - return "Q " + kx + " " + ky - + " " + x + " " + y; - } - public Quadratic(boolean isRelative, float kx, float ky, float x, float y) { super(isRelative); this.kx = kx; @@ -71,12 +23,10 @@ public class Quadratic extends PathCommand { this.y = y; } - // public void appendPath(ExtendedGeneralPath path, BuildHistory hist) @Override public void appendPath(GeneralPath path, BuildHistory hist) { float offx = isRelative ? hist.lastPoint.x : 0f; float offy = isRelative ? hist.lastPoint.y : 0f; - path.quadTo(kx + offx, ky + offy, x + offx, y + offy); hist.setLastPoint(x + offx, y + offy); hist.setLastKnot(kx + offx, ky + offy); @@ -86,4 +36,10 @@ public class Quadratic extends PathCommand { public int getNumKnotsAdded() { return 4; } + + @Override + public String toString() { + return "Q " + kx + " " + ky + + " " + x + " " + y; + } } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/QuadraticSmooth.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/QuadraticSmooth.java index 3ca83e5..5b19a32 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/QuadraticSmooth.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/QuadraticSmooth.java @@ -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; -//import org.apache.batik.ext.awt.geom.ExtendedGeneralPath; - import java.awt.geom.GeneralPath; -/** - * @author Mark McKay - * @author Mark McKay - */ public class QuadraticSmooth extends PathCommand { public float x = 0f; + public float y = 0f; - /** - * Creates a new instance of MoveTo - */ public QuadraticSmooth() { } @@ -66,20 +22,16 @@ public class QuadraticSmooth extends PathCommand { this.y = y; } - // public void appendPath(ExtendedGeneralPath path, BuildHistory hist) @Override public void appendPath(GeneralPath path, BuildHistory hist) { float offx = isRelative ? hist.lastPoint.x : 0f; float offy = isRelative ? hist.lastPoint.y : 0f; - float oldKx = hist.lastKnot.x; float oldKy = hist.lastKnot.y; float oldX = hist.lastPoint.x; float oldY = hist.lastPoint.y; - //Calc knot as reflection of old knot float kx = oldX * 2f - oldKx; float ky = oldY * 2f - oldKy; - path.quadTo(kx, ky, x + offx, y + offy); hist.setLastPoint(x + offx, y + offy); hist.setLastKnot(kx, ky); diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/Terminal.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/Terminal.java index 2683861..53b7cba 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/Terminal.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/Terminal.java @@ -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; -//import org.apache.batik.ext.awt.geom.ExtendedGeneralPath; - import java.awt.geom.GeneralPath; -/** - * Finishes a path - * - * @author Mark McKay - * @author Mark McKay - */ public class Terminal extends PathCommand { - /** - * Creates a new instance of MoveTo - */ public Terminal() { } @@ -59,8 +12,6 @@ public class Terminal extends PathCommand { return "Z"; } - - // public void appendPath(ExtendedGeneralPath path, BuildHistory hist) @Override public void appendPath(GeneralPath path, BuildHistory hist) { path.closePath(); diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/Vertical.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/Vertical.java index 2c88d8d..fe19b46 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/Vertical.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/pathcmd/Vertical.java @@ -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; -//import org.apache.batik.ext.awt.geom.ExtendedGeneralPath; - import java.awt.geom.GeneralPath; -/** - * @author Mark McKay - * @author Mark McKay - */ public class Vertical extends PathCommand { public float y = 0f; - /** - * Creates a new instance of MoveTo - */ public Vertical() { } @@ -64,12 +19,10 @@ public class Vertical extends PathCommand { this.y = y; } - // public void appendPath(ExtendedGeneralPath path, BuildHistory hist) @Override public void appendPath(GeneralPath path, BuildHistory hist) { float offx = hist.lastPoint.x; float offy = isRelative ? hist.lastPoint.y : 0f; - path.lineTo(offx, y + offy); hist.setLastPoint(offx, y + offy); hist.setLastKnot(offx, y + offy); diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/pattern/PatternPaint.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/pattern/PatternPaint.java deleted file mode 100644 index 890717c..0000000 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/pattern/PatternPaint.java +++ /dev/null @@ -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 Mark McKay - */ -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(); - } - -} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/pattern/PatternPaintContext.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/pattern/PatternPaintContext.java deleted file mode 100644 index eb2415e..0000000 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/pattern/PatternPaintContext.java +++ /dev/null @@ -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 Mark McKay - */ -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)); - } - -} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/util/FontUtil.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/util/FontUtil.java index d7de606..6cc292f 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/util/FontUtil.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/util/FontUtil.java @@ -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; -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.SVGElement; +import org.xbib.graphics.svg.element.SVGElement; import org.xbib.graphics.svg.SVGException; import org.xbib.graphics.svg.Text; import org.xbib.graphics.svg.xml.StyleAttribute; @@ -45,17 +13,16 @@ import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; -/** - * Utility class for parsing font information of an {@link SVGElement}. - * - * @author Jannis Weis - */ public final class FontUtil { private static final String DEFAULT_FONT_FAMILY = "sans-serif"; + private static final float DEFAULT_FONT_SIZE = 12f; + private static final int DEFAULT_LETTER_SPACING = 0; + private static final int DEFAULT_FONT_STYLE = Text.TXST_NORMAL; + private static final int DEFAULT_FONT_WEIGHT = Text.TXWE_NORMAL; private FontUtil() { @@ -78,8 +45,12 @@ public final class FontUtil { @Override public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof FontInfo)) return false; + if (this == o) { + return true; + } + if (!(o instanceof FontInfo)) { + return false; + } FontInfo fontInfo = (FontInfo) o; return Float.compare(fontInfo.size, size) == 0 && style == fontInfo.style && weight == fontInfo.weight @@ -100,17 +71,14 @@ public final class FontUtil { if (element.getStyle(sty.setName("font-family"))) { fontFamily = sty.getStringValue(); } - float fontSize = DEFAULT_FONT_SIZE; if (element.getStyle(sty.setName("font-size"))) { fontSize = sty.getFloatValueWithUnits(); } - float letterSpacing = DEFAULT_LETTER_SPACING; if (element.getStyle(sty.setName("letter-spacing"))) { letterSpacing = sty.getFloatValueWithUnits(); } - int fontStyle = DEFAULT_FONT_STYLE; if (element.getStyle(sty.setName("font-style"))) { String s = sty.getStringValue(); @@ -122,7 +90,6 @@ public final class FontUtil { fontStyle = Text.TXST_OBLIQUE; } } - int fontWeight = DEFAULT_FONT_WEIGHT; if (element.getStyle(sty.setName("font-weight"))) { String s = sty.getStringValue(); @@ -132,7 +99,6 @@ public final class FontUtil { fontWeight = Text.TXWE_BOLD; } } - return new FontInfo(fontFamily.split(","), fontSize, fontStyle, fontWeight, letterSpacing); } @@ -147,7 +113,6 @@ public final class FontUtil { if (font != null) break; } if (font == null) { - //Check system fonts font = FontSystem.createFont(families, fontStyle, fontWeight, fontSize); } if (font == null) { diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/util/PaintCache.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/util/PaintCache.java new file mode 100644 index 0000000..759ee74 --- /dev/null +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/util/PaintCache.java @@ -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); + } +} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/BufferPainter.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/util/PaintUtil.java similarity index 77% rename from graphics-svg/src/main/java/org/xbib/graphics/svg/BufferPainter.java rename to graphics-svg/src/main/java/org/xbib/graphics/svg/util/PaintUtil.java index c349c4e..7d1a95b 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/BufferPainter.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/util/PaintUtil.java @@ -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.Graphics2D; @@ -12,35 +16,10 @@ import java.util.List; import java.util.Objects; import java.util.stream.Collectors; -public class BufferPainter { +public class PaintUtil { + 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 { if (element.cachedMask != null || (element.filter != null && !element.filter.filterEffects.isEmpty())) { @@ -64,12 +43,12 @@ public class BufferPainter { Rectangle elementBounds = element.getBoundingBox().getBounds(); Rectangle transformedBounds = transform.createTransformedShape(elementBounds).getBounds(); Rectangle dstBounds = new Rectangle(transformedBounds); - Cache cache = element.getBufferCache(); + PaintCache cache = element.getBufferCache(); BufferedImage elementImage; if (cache == null || !cache.isCompatible(transform)) { elementImage = renderToBuffer(gg, element, transform, transformedBounds, dstBounds); } else { - elementImage = cache.img; + elementImage = cache.getImage(); dstBounds.setBounds(cache.getBoundsForTransform(transform)); } gg.setTransform(new AffineTransform()); @@ -90,22 +69,17 @@ public class BufferPainter { Rectangle dstBounds) throws SVGException, IOException { Point2D.Float origin = new Point2D.Float(0, 0); 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); float xScale = getTransformScale(origin, testPoint, transform); testPoint.setLocation(0, 1); float yScale = getTransformScale(origin, testPoint, transform); - - List filterOps = element.filter == null + List filterOps = element.filter == null ? Collections.emptyList() : element.filter.filterEffects.stream() .flatMap(f -> f.getOperations(dstBounds, xScale, yScale).stream()) .filter(Objects::nonNull) .collect(Collectors.toList()); - - for (FilterEffects.FilterOp filterOp : filterOps) { + for (FilterOp filterOp : filterOps) { int right = Math.max(dstBounds.x + dstBounds.width, filterOp.requiredImageBounds.x + filterOp.requiredImageBounds.width); int bottom = Math.max(dstBounds.y + dstBounds.height, @@ -115,17 +89,13 @@ public class BufferPainter { dstBounds.width = right - dstBounds.x; dstBounds.height = bottom - dstBounds.y; } - - - BufferedImage elementImage = BufferPainter.paintToBuffer(gg, transform, dstBounds, transformedBounds, + BufferedImage elementImage = PaintUtil.paintToBuffer(gg, transform, dstBounds, transformedBounds, element, null, true); - - for (FilterEffects.FilterOp filterOp : filterOps) { + for (FilterOp filterOp : filterOps) { elementImage = filterOp.op.filter(elementImage, 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); Graphics2D elementGraphics = (Graphics2D) elementImage.getGraphics(); elementGraphics.setRenderingHints(gg.getRenderingHints()); diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/util/TextBuilder.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/util/TextBuilder.java deleted file mode 100644 index e734e32..0000000 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/util/TextBuilder.java +++ /dev/null @@ -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 { - -} diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/xml/StyleAttribute.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/xml/StyleAttribute.java index 5398b60..fe9aef9 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/xml/StyleAttribute.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/xml/StyleAttribute.java @@ -1,7 +1,5 @@ package org.xbib.graphics.svg.xml; -import org.xbib.graphics.svg.SVGConst; - import java.awt.Color; import java.awt.HeadlessException; import java.awt.Toolkit; @@ -15,16 +13,16 @@ import java.util.regex.Pattern; public class StyleAttribute { + private static final Logger logger = Logger.getLogger(StyleAttribute.class.getName()); + 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(""); String name; + String stringValue; - /** - * Creates a new instance of StyleAttribute - */ public StyleAttribute() { this(null, null); } @@ -161,19 +159,7 @@ public class StyleAttribute { try { return new URL(docRoot, fragment); } catch (Exception e) { - Logger.getLogger(SVGConst.SVG_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); + logger.log(Level.WARNING, null, e); return null; } } @@ -206,7 +192,7 @@ public class StyleAttribute { } return new URI(base.getScheme() + ":" + relUri); } catch (Exception e) { - Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, null, e); + logger.log(Level.WARNING, null, e); return null; } } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/xml/StyleSheet.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/xml/StyleSheet.java index 73dd11b..fc527e7 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/xml/StyleSheet.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/xml/StyleSheet.java @@ -1,18 +1,13 @@ package org.xbib.graphics.svg.xml; -import org.xbib.graphics.svg.SVGConst; - import java.util.HashMap; import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; public class StyleSheet { Map ruleMap = new HashMap<>(); public static StyleSheet parseSheet(String src) { - Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, "CSS parser not implemented yet"); return null; } diff --git a/graphics-svg/src/main/java/org/xbib/graphics/svg/xml/XMLParseUtil.java b/graphics-svg/src/main/java/org/xbib/graphics/svg/xml/XMLParseUtil.java index 0060ec8..7195709 100644 --- a/graphics-svg/src/main/java/org/xbib/graphics/svg/xml/XMLParseUtil.java +++ b/graphics-svg/src/main/java/org/xbib/graphics/svg/xml/XMLParseUtil.java @@ -1,7 +1,5 @@ package org.xbib.graphics.svg.xml; -import org.xbib.graphics.svg.SVGConst; - import java.awt.Toolkit; import java.util.HashMap; import java.util.Iterator; @@ -14,7 +12,9 @@ import java.util.regex.Pattern; 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(""); @@ -48,7 +48,7 @@ public class XMLParseUtil { return 0; } } catch (StringIndexOutOfBoundsException e) { - Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, + logger.log(Level.WARNING, "XMLParseUtil: regex parse problem: '" + val + "'", e); } val = fpMatch.group(1); @@ -188,13 +188,14 @@ public class XMLParseUtil { } public static NumberWithUnits parseNumberWithUnits(String val) { - if (val == null) return null; - + if (val == null) { + return null; + } return new NumberWithUnits(val); } public static HashMap parseStyle(String styleString, HashMap map) { - final Pattern patSemi = Pattern.compile(";"); + Pattern patSemi = Pattern.compile(";"); String[] styles = patSemi.split(styleString); for (String style : styles) { if (style.length() == 0) { diff --git a/graphics-svg/src/test/java/org/xbib/graphics/svg/test/SimpleSVGLoadTest.java b/graphics-svg/src/test/java/org/xbib/graphics/svg/test/SimpleSVGLoadTest.java new file mode 100644 index 0000000..0558fb0 --- /dev/null +++ b/graphics-svg/src/test/java/org/xbib/graphics/svg/test/SimpleSVGLoadTest.java @@ -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")); + } +} diff --git a/graphics-svg/src/test/res/1C2EC147.png b/graphics-svg/src/test/res/1C2EC147.png deleted file mode 100644 index e33dd29b620d1da8dddf5a05c20af8516acad7bb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48520 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 Eg4ob;p8x;= diff --git a/graphics-svg/src/test/res/1C2EC148.png b/graphics-svg/src/test/res/1C2EC148.png deleted file mode 100644 index e33dd29b620d1da8dddf5a05c20af8516acad7bb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48520 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 Eg4ob;p8x;= diff --git a/graphics-svg/src/test/res/AdamTagletClasses.svg b/graphics-svg/src/test/res/AdamTagletClasses.svg deleted file mode 100644 index ac5b85f..0000000 --- a/graphics-svg/src/test/res/AdamTagletClasses.svg +++ /dev/null @@ -1,104 +0,0 @@ - - -]> - - - - -DigraphName - - -net_walend_adamtaglet_AdamTaglet - - -AdamTaglet - - - -com_sun_tools_doclets_internal_toolkit_taglets_Taglet - - -com.sun.tools.doclets.internal.toolkit.taglets.Taglet - - - -com_sun_tools_doclets_internal_toolkit_taglets_Taglet->net_walend_adamtaglet_AdamTaglet - - - - -net_walend_adamtaglet_ClassDiagramBuilder - - -ClassDiagramBuilder - - - -net_walend_adamtaglet_ClassDiagramVisitor - - -ClassDiagramVisitor - - - -net_walend_tographviz_ToGraphvizVisitor - - -net.walend.tographviz.ToGraphvizVisitor - - - -net_walend_tographviz_ToGraphvizVisitor->net_walend_adamtaglet_ClassDiagramVisitor - - - - -net_walend_adamtaglet_Relationship - - -Relationship - - - -java_lang_Enum - - -java.lang.Enum - - - -java_lang_Enum->net_walend_adamtaglet_Relationship - - - - -java_lang_Comparable - - -java.lang.Comparable - - - -java_lang_Comparable->java_lang_Enum - - - - -java_io_Serializable - - -java.io.Serializable - - - -java_io_Serializable->java_lang_Enum - - - - - diff --git a/graphics-svg/src/test/res/Monitor.svg b/graphics-svg/src/test/res/Monitor.svg deleted file mode 100644 index 9e07a3f..0000000 --- a/graphics-svg/src/test/res/Monitor.svg +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/graphics-svg/src/test/res/bad_alias.svg b/graphics-svg/src/test/res/bad_alias.svg deleted file mode 100644 index 4adc92d..0000000 --- a/graphics-svg/src/test/res/bad_alias.svg +++ /dev/null @@ -1,131 +0,0 @@ - - - - -]> - - - - - - - diff --git a/graphics-svg/src/test/res/bad_alias2.svg b/graphics-svg/src/test/res/bad_alias2.svg deleted file mode 100644 index 81fc016..0000000 --- a/graphics-svg/src/test/res/bad_alias2.svg +++ /dev/null @@ -1,229 +0,0 @@ - - - - -]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/graphics-svg/src/test/res/bad_alias3.svg b/graphics-svg/src/test/res/bad_alias3.svg deleted file mode 100644 index a74e8bd..0000000 --- a/graphics-svg/src/test/res/bad_alias3.svg +++ /dev/null @@ -1,5689 +0,0 @@ - - - - -]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - COMPRESSOR 1 CYLINDER - 8501031 - E - W - I - T - H - O - U - T - - O - I - L - - E - Q - U - A - L - I - S - A - T - I - O - N - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 25 - - .98 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 98 - - 3.85 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 68 - - 2.67 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 109 - - 4.29 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 15 - - .60 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 23 - - .90 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 17 - - .67 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 39 - - 1.52 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 118 - - 4.65 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 123 - - 4.84 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 68 - - 2.68 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 35° - - - - - - - - - - - - - - - - 263 - - 10.34 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 82 - - 3.22 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SUCTION - - D - - I - - S - - C - - H - - A - - R - - G - - E - - - - 142 - - 5.59 - - [ - - ] - - 142 - - 5.60 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Ø - - 224 - - 8.83 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 333 - - 13.12 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Ø - - 31,75 - - 1.25 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 159 - - 6.26 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - C - - O - - M - - P - - R - - E - - S - - S - - O - - R - - S - - MT/MTZ 18-3/4 - - MT/MTZ 22-3/4/6 - - MT/MTZ 28-3/4/6 - - - - S - U - - C - - T - - I - - O - - N - - - - R - - O - - T - - A - - L - - O - - C - - K - - 1" - - - - D - - I - - S - - C - - H - - A - - R - - G - - E - - - - R - - O - - T - - A - - L - - O - - C - - K - - 1" - - - - P - - T - - C - - - - C - - R - - A - - N - - K - - C - - A - - S - - E - - - - H - - E - - A - - T - - E - - R - - - - S - - C - - H - - R - - A - - D - - E - - R - - 1/4" - - - - B - - O - - L - - T - - - - H - - - - M - - 8 - - - - - 4 - - 0 - - G - - R - - O - - M - - M - - E - - T - - - - C - - O - - M - - P - - R - - E - - S - - S - - I - - O - - N - - - - N - - O - - T - - - - I - - N - - C - - L - - U - - D - - E - - D - - , - - A - - R - - O - - U - - N - - D - - - - 1 - - - - M - - M - - S - - I - - L - - E - - N - - T - - B - - L - - O - - C - - K - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/graphics-svg/src/test/res/data-uri-scheme-test-image.svg b/graphics-svg/src/test/res/data-uri-scheme-test-image.svg deleted file mode 100644 index a6356be..0000000 --- a/graphics-svg/src/test/res/data-uri-scheme-test-image.svg +++ /dev/null @@ -1,23 +0,0 @@ - - - - -]> - - - - - - - - - - - - - - - - diff --git a/graphics-svg/src/test/res/drawing.svg b/graphics-svg/src/test/res/drawing.svg deleted file mode 100644 index 77a6dc1..0000000 --- a/graphics-svg/src/test/res/drawing.svg +++ /dev/null @@ -1,9361 +0,0 @@ - - - - -]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - A - P - P - R - O - B - A - T - I - O - N - M - A - T - I - E - R - E - : - P - A - R - D - A - T - E - T - o - l - . - g - e - n - : - E - c - h - : - IND - M - O - D - I - F - I - C - A - T - I - O - N - S - - C - e - - p - l - a - n - - e - s - t - - l - a - - p - r - o - p - r - i - e - t - e - - d - e - - D - a - n - f - o - s - s - - C - o - m - m - e - r - c - i - a - l - - C - o - m - p - r - e - s - s - o - r - s - , - - t - o - u - t - e - - c - o - p - i - e - - o - u - - c - o - m - m - u - n - i - c - a - t - i - o - n - - a - - d - e - s - - t - i - e - r - s - e - s - t - - i - n - t - e - r - d - i - t - e - - s - a - n - s - - a - u - t - o - r - i - s - a - t - i - o - n - . - - T - h - i - s - - d - r - a - w - i - n - g - - i - s - - p - r - o - p - r - i - e - t - a - r - y - - a - n - d - - s - h - a - l - l - - n - o - t - - b - e - - c - o - p - i - e - d - - o - r - - i - t - s - c - o - n - t - e - n - t - s - - d - i - s - c - l - o - s - e - d - - t - o - - o - u - t - s - i - d - e - - p - a - r - t - i - e - s - - w - i - t - h - o - u - t - - t - h - e - - w - r - i - t - t - e - n - - c - o - n - s - e - n - t - - o - f - - D - a - n - f - o - s - s - - C - o - m - m - e - r - c - i - a - l - - C - o - m - p - r - e - s - s - o - r - s - 3D - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 518 - - 20.40 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 99 - 3.91 - [ - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 95 - 3.75 - [ - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 125 - 4.92 - [ - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 233 - 9.18 - [ - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 246 - 9.70 - [ - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 246 - 9.70 - [ - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 210 - 8.28 - [ - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 209 - 8.24 - [ - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 205 - 8.07 - [ - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 155 - 6.10 - [ - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 117 - 4.61 - [ - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Ø - - 352 - - 13.85 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 98 - 3.84 - [ - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 232 - 9.12 - [ - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 15° - - - - - - - - - - - - - - - 15° - - - - - - - - - - - - - - - 15° - - - - - - - - - - - - - - - 19 - .75 - [ - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 30 - 1.19 - [ - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 8504010 - - - - - - - - - A1 - - - - - - - - - 1/2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - D - a - n - f - o - s - s - - C - o - m - m - e - r - c - i - a - l - C - o - m - p - r - e - s - s - o - r - s - B - . - P - . - 3 - 3 - 1 - F - - - 0 - 1 - 6 - 0 - 3 - - T - r - e - v - o - u - x - - F - r - a - n - c - e - T - e - l - . - - : - F - a - x - : - + - 3 - 3 - - ( - 0 - ) - - 4 - - 7 - 4 - - 0 - 0 - - 2 - 8 - - 2 - 9 - + - 3 - 3 - - ( - 0 - ) - - 4 - - 7 - 4 - - 0 - 0 - - 5 - 2 - - 4 - 4 - - - - - - - - - - - - - - - - - - - 4 - - C - Y - L - I - N - D - R - E - S - - / - - V - E - - / - - B - A - S - S - E - - - - - - - - - 4 - - C - y - l - i - n - d - e - r - s - - / - - V - E - - / - - L - o - w - - - - - - - - - - - - - - - - - - - - - - - - - - - E - ADA - 23/06/05 - J - B - V - - DC 1020861 / 1050271 / 1050272 - - - - - - - - - - C - O - M - P - R - E - S - S - O - R - S - - M - T - / - M - T - Z - - 1 - 0 - 0 - - - 3 - / - 4 - / - 6 - / - 7 - / - 9 - M - T - / - M - T - Z - - 1 - 2 - 5 - - - 3 - / - 4 - / - 6 - / - 7 - / - 9 - L - T - Z - - 8 - 8 - - - 3 - / - 4 - / - 6 - / - 7 - / - 9 - L - T - Z - - 1 - 0 - 0 - - - 3 - / - 4 - / - 6 - / - 7 - / - 9 - N - T - Z - - 2 - 7 - 1 - - - 3 - / - 4 - N - T - Z - - 2 - 1 - 5 - - - 3 - / - 4 - V - T - Z - - 1 - 7 - 1 - - - G - / - H - V - T - Z - - 2 - 1 - 5 - - - G - / - H - - O - I - L - - E - Q - U - A - L - I - S - A - T - I - O - N - 3 - / - 8 - " - - - - - - - - T - H - R - E - A - D - E - D - - O - I - L - S - I - G - H - T - - G - L - A - S - S - - - - - - - - S - C - H - R - A - D - E - R - 1 - / - 4 - " - - - - - - - - S - U - C - T - I - O - N - - R - O - T - A - L - O - C - K - 1 - " - 3 - / - 4 - - - - - - - - D - I - S - C - H - A - R - G - E - - R - O - T - A - L - O - C - K - 1 - " - 1 - / - 4 - - - - - - - - P - T - C - C - R - A - N - K - C - A - S - E - - H - E - A - T - E - R - - - - - - - B - O - L - T - - H - - M - 1 - 2 - - - 5 - 0 - - - - - - - - G - R - O - M - M - E - T - - C - O - M - P - R - E - S - S - I - O - N - - N - O - T - - I - N - C - L - U - D - E - D - A - R - O - U - N - D - - 1 - - M - M - S - I - L - E - N - T - - B - L - O - C - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/graphics-svg/src/test/res/embed_image.svg b/graphics-svg/src/test/res/embed_image.svg deleted file mode 100644 index 92bc10a..0000000 --- a/graphics-svg/src/test/res/embed_image.svg +++ /dev/null @@ -1,5689 +0,0 @@ - - - - -]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - COMPRESSOR 1 CYLINDER - 8501031 - E - W - I - T - H - O - U - T - - O - I - L - - E - Q - U - A - L - I - S - A - T - I - O - N - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 25 - - .98 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 98 - - 3.85 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 68 - - 2.67 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 109 - - 4.29 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 15 - - .60 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 23 - - .90 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 17 - - .67 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 39 - - 1.52 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 118 - - 4.65 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 123 - - 4.84 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 68 - - 2.68 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 35° - - - - - - - - - - - - - - - - 263 - - 10.34 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 82 - - 3.22 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SUCTION - - D - - I - - S - - C - - H - - A - - R - - G - - E - - - - 142 - - 5.59 - - [ - - ] - - 142 - - 5.60 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Ø - - 224 - - 8.83 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 333 - - 13.12 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Ø - - 31,75 - - 1.25 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 159 - - 6.26 - - [ - - ] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - C - - O - - M - - P - - R - - E - - S - - S - - O - - R - - S - - MT/MTZ 18-3/4 - - MT/MTZ 22-3/4/6 - - MT/MTZ 28-3/4/6 - - - - S - U - - C - - T - - I - - O - - N - - - - R - - O - - T - - A - - L - - O - - C - - K - - 1" - - - - D - - I - - S - - C - - H - - A - - R - - G - - E - - - - R - - O - - T - - A - - L - - O - - C - - K - - 1" - - - - P - - T - - C - - - - C - - R - - A - - N - - K - - C - - A - - S - - E - - - - H - - E - - A - - T - - E - - R - - - - S - - C - - H - - R - - A - - D - - E - - R - - 1/4" - - - - B - - O - - L - - T - - - - H - - - - M - - 8 - - - - - 4 - - 0 - - G - - R - - O - - M - - M - - E - - T - - - - C - - O - - M - - P - - R - - E - - S - - S - - I - - O - - N - - - - N - - O - - T - - - - I - - N - - C - - L - - U - - D - - E - - D - - , - - A - - R - - O - - U - - N - - D - - - - 1 - - - - M - - M - - S - - I - - L - - E - - N - - T - - B - - L - - O - - C - - K - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/graphics-svg/src/test/res/embed_image.svgz b/graphics-svg/src/test/res/embed_image.svgz deleted file mode 100644 index fe74789bf077b4a3d25abea8afff53227976abd2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45950 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 CIsN_s diff --git a/graphics-svg/src/test/res/missing.svg b/graphics-svg/src/test/res/missing.svg deleted file mode 100644 index d540986..0000000 --- a/graphics-svg/src/test/res/missing.svg +++ /dev/null @@ -1,1090 +0,0 @@ - - - - -]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 12 - - - - 14 - - - - 11 - - - - N - - - - 2 - - - - 1 - - - - L1 - - - - - - - - - - - - - - - - - - - diff --git a/graphics-svg/src/test/res/missing.svgz b/graphics-svg/src/test/res/missing.svgz deleted file mode 100644 index 051d5e7956ba16b8d05f9fe530a9d10959fb431d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15968 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 OfB!#Z+0lW|jsXDCTVXN) diff --git a/graphics-svg/src/test/res/round_path.svg b/graphics-svg/src/test/res/round_path.svg deleted file mode 100644 index b7e9e05..0000000 --- a/graphics-svg/src/test/res/round_path.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - -]> - - - - - - - \ No newline at end of file diff --git a/graphics-svg/src/test/resources/org/xbib/graphics/svg/test/test.svg b/graphics-svg/src/test/resources/org/xbib/graphics/svg/test/test.svg new file mode 100644 index 0000000..f04b690 --- /dev/null +++ b/graphics-svg/src/test/resources/org/xbib/graphics/svg/test/test.svg @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + Bar Chart + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Shoe + Car + Travel + Computer + + 0 + 10 + 20 + 30 + 40 + 50 + 60 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +