📄 svgparserandstore.java
字号:
/* * File: SVGParserAndStore.java * Project: MPI Linguistic Application * Date: 02 May 2007 * * Copyright (C) 2001-2007 Max Planck Institute for Psycholinguistics * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package mpi.eudico.client.annotator.svg;import mpi.eudico.server.corpora.clom.Transcription;import mpi.eudico.server.corpora.clomimpl.abstr.SVGAlignableAnnotation;import mpi.eudico.server.corpora.clomimpl.abstr.TierImpl;import mpi.eudico.server.corpora.clomimpl.abstr.TranscriptionImpl;import mpi.eudico.server.util.IoUtil;import mpi.util.LogUtil;import org.apache.batik.bridge.DocumentLoader;import org.apache.batik.bridge.UserAgentAdapter;//import org.apache.batik.css.engine.CSSStylableElement; //batik 1.5//import org.apache.batik.css.engine.SVGCSSEngine; //batik 1.5//import org.apache.batik.css.engine.value.Value; //batik 1.5import org.apache.batik.dom.AbstractNode;import org.apache.batik.dom.GenericAttrNS;import org.apache.batik.dom.svg.SVGGraphicsElement;import org.apache.batik.dom.svg.SVGOMCircleElement;import org.apache.batik.dom.svg.SVGOMDefsElement;import org.apache.batik.dom.svg.SVGOMDocument;import org.apache.batik.dom.svg.SVGOMElement;import org.apache.batik.dom.svg.SVGOMEllipseElement;import org.apache.batik.dom.svg.SVGOMGElement;import org.apache.batik.dom.svg.SVGOMLineElement;import org.apache.batik.dom.svg.SVGOMPathElement;import org.apache.batik.dom.svg.SVGOMRectElement;import org.apache.batik.dom.svg.SVGOMSymbolElement;import org.apache.batik.dom.svg.SVGOMUseElement;import org.w3c.dom.DOMException;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.NamedNodeMap;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import java.awt.Rectangle;import java.awt.Shape;import java.awt.geom.Ellipse2D;import java.awt.geom.Line2D;import java.awt.geom.RectangularShape;import java.io.File;import java.io.IOException;import java.util.Hashtable;import java.util.Iterator;import java.util.Vector;import java.util.logging.Logger;/** * Parses a .svg file referenced by an eaf Transcription and adds graphical * objects to annotation.<br> * It currently also stores a svg/graphics library for each parsed svg file. <br> * NB: this class should be in some other package, e.g. eudico.server.xxx or * mpi.alt.org.w3c.dom. * * @author Han Sloetjes * @version Aug 2005 Identity removed */public class SVGParserAndStore { private static Hashtable libraries = new Hashtable(4); private static Hashtable documents = new Hashtable(4); private static SVGParserAndStore parser = null; /** the current SVGDocument object */ private static SVGOMDocument svgDoc = null; /** Holds value of property DOCUMENT ME! */ private static final Logger LOG = Logger.getLogger(SVGParserAndStore.class.getName()); //private static SVGCSSEngine cssEngine = null; //batik 1.5 private SVGParserAndStore() { } /** * This class follows the Singleton pattern. The public methods are * synchronized and thus grab the lock for the class. * * @return the one instance of this class */ public static SVGParserAndStore getInstance() { if (parser == null) { parser = new SVGParserAndStore(); } return parser; } /** * Returns the symbols library for the specified Transcription. * * @param transcription the transcription * * @return a Hashtable with id strings as keys and shapes as entries */ public static Object getLibrary(Transcription transcription) { return libraries.get(transcription); } /** * Parses the svg file belonging to the transcription, if present. It * builds a library of symbols and adds shapes to annotation using the * svg id's in the annotations. * * @param transcription the transcription to parse */ public static synchronized void parse(Transcription transcription) { //start the parsing of the svg file referenced by the annotation String svgFileString = null; if (transcription instanceof TranscriptionImpl) { if (((TranscriptionImpl) transcription).getSVGFile() != null) { // there has been a check on this file in DobesTranscription svgFileString = ((TranscriptionImpl) transcription).getSVGFile(); LOG.info("Parse SVG file: " + svgFileString); } } if (svgFileString == null) { return; } UserAgentAdapter userAgent = new UserAgentAdapter(); DocumentLoader loader = new DocumentLoader(userAgent); //BridgeContext ctx = new BridgeContext(userAgent, loader); try { svgDoc = (SVGOMDocument) loader.loadDocument(svgFileString); documents.put(transcription, svgDoc); } catch (IOException ioe) { LOG.severe("Could not load the .svg file"); return; } //cssEngine = (SVGCSSEngine)svgDoc.getCSSEngine(); //batik 1.5 buildLibrary(transcription); createGraphicAnnotations(transcription); } /** * Loops over the tiers and annotation of this Transcription and tries to * create a Shape for each annotation with a reference to a svg element. * * @param transcription the Transcription to process */ private static void createGraphicAnnotations( final Transcription transcription) { Shape shape = null; Iterator it = transcription.getTiers().iterator(); while (it.hasNext()) { TierImpl tier = (TierImpl) it.next(); if ((tier.getLinguisticType() != null) && tier.getLinguisticType().hasGraphicReferences()) { //iter over the annotations Iterator annIt = tier.getAnnotations().iterator(); SVGAlignableAnnotation ann; while (annIt.hasNext()) { ann = (SVGAlignableAnnotation) annIt.next(); if (ann.getSVGElementID().length() > 0) { String id = ann.getSVGElementID(); SVGOMElement el = (SVGOMElement) svgDoc.getElementById(id); if (el == null) { continue; } int elX = parseToInt(el.getAttribute("x")); int elY = parseToInt(el.getAttribute("y")); if (el instanceof SVGOMUseElement) { shape = createShapeFromUseElement((SVGOMUseElement) el, elX, elY); } else { shape = createShapeFromElement(el, elX, elY); } if (shape != null) { ann.insertShape(shape); } //System.out.println("SVG id: " + id + " - shape: " + shape); } } } } } /** * Builds a library of Shape for use in an editor. Only objects within a * 'defs' tag are included in the library. * * @param transcription the Transcription to build this library for */ private static void buildLibrary(Transcription transcription) { SVGOMDocument svgDoc = (SVGOMDocument) documents.get(transcription); if (svgDoc == null) { return; } NodeList children = svgDoc.getRootElement().getChildNodes(); SVGOMDefsElement defsEl = null; for (int i = 0; i < children.getLength(); i++) { Node n = children.item(i); if (n.getNodeName().equals("defs")) { defsEl = (SVGOMDefsElement) n; break; } } if (defsEl == null) { return; } Hashtable symbols = new Hashtable(); children = defsEl.getChildNodes(); Node nextNode; for (int i = 0; i < children.getLength(); i++) { nextNode = children.item(i); Shape shape = null; if (nextNode.getNodeName().equals("symbol")) { SVGOMSymbolElement sym = (SVGOMSymbolElement) nextNode; int symX = parseToInt(sym.getAttribute("x")); int symY = parseToInt(sym.getAttribute("y")); NodeList symChilds = sym.getChildNodes(); for (int j = 0; j < symChilds.getLength(); j++) { if (symChilds.item(j) instanceof SVGOMUseElement) { SVGOMUseElement use = (SVGOMUseElement) symChilds.item(j); int useX = parseToInt(use.getAttribute("x")) + symX; int useY = parseToInt(use.getAttribute("y")) + symY; shape = createShapeFromUseElement(use, useX, useY); break; } else if (symChilds.item(j) instanceof SVGOMElement) { shape = createShapeFromElement((SVGOMElement) symChilds.item( j), symX, symY); // allow only one child for the time being break; } } } else if (nextNode.getNodeName().equals("g")) { SVGOMGElement gel = (SVGOMGElement) nextNode; int gX = parseToInt(gel.getAttribute("x")); int gY = parseToInt(gel.getAttribute("y")); shape = createShapeFromGElement(gel, gX, gY); //allow only one child for the time being break; } if (shape != null) { symbols.put(((SVGOMElement) nextNode).getId(), shape); } } libraries.put(transcription, symbols); } //end buildLibrary private static Shape createShapeFromElement(final SVGOMElement el, int transX, int transY) { if (el instanceof SVGOMGElement) { return createShapeFromGElement((SVGOMGElement) el, transX, transY); } if (el instanceof SVGOMRectElement) { return createShapeFromRectElement((SVGOMRectElement) el, transX, transY); } if (el instanceof SVGOMEllipseElement) { return createShapeFromEllipseElement((SVGOMEllipseElement) el, transX, transY); } if (el instanceof SVGOMCircleElement) { return createShapeFromCircleElement((SVGOMCircleElement) el, transX, transY); } if (el instanceof SVGOMPathElement) { return createShapeFromPathElement((SVGOMPathElement) el, transX, transY); } if (el instanceof SVGOMLineElement) { return createShapeFromLineElement((SVGOMLineElement) el, transX, transY); } return null; } private static Shape createShapeFromSymbolElement( final SVGOMSymbolElement el, int transX, int transY) { NodeList symChilds = el.getChildNodes(); int x = parseToInt(el.getAttribute("x")) + transX; int y = parseToInt(el.getAttribute("y")) + transY; for (int j = 0; j < symChilds.getLength(); j++) { if (symChilds.item(j) instanceof SVGOMUseElement) { SVGOMUseElement use = (SVGOMUseElement) symChilds.item(j); return createShapeFromUseElement(use, x, y); } else if (symChilds.item(j) instanceof SVGOMElement) { return createShapeFromElement((SVGOMElement) symChilds.item(j), x, y); } } return null; } private static Shape createShapeFromUseElement(final SVGOMUseElement el, int transX, int transY) { String href = ""; // batik 1.5 // href = el.getHref().getBaseVal(); //batik 1.5 // batik 1.1.1 //String href = el.getAttributeNS(null, "xlink:href"); //empty in batik 1.1.1 NamedNodeMap m = el.getAttributes(); //m.getNamedItem("xlink:href"); returns null for (int j = 0; j < m.getLength(); j++) { Node n = m.item(j); if (n instanceof GenericAttrNS) { GenericAttrNS ans = (GenericAttrNS) n; if (ans.getName().equals("xlink:href")) { //the first child of the xlink:href is the referenced node Node cn = ans.getFirstChild(); if (cn != null) { href = cn.getNodeValue(); } break; } } } if ((href != null) && (href.length() > 1)) { href = href.substring(1); // remove the # } else { return null; } int x = parseToInt(el.getAttribute("x")) + transX; int y = parseToInt(el.getAttribute("y")) + transY; SVGOMElement ref = (SVGOMElement) svgDoc.getElementById(href); if (ref instanceof SVGOMSymbolElement) { return createShapeFromSymbolElement((SVGOMSymbolElement) ref, x, y); } if (ref instanceof SVGOMElement) { return createShapeFromElement((SVGOMElement) ref, x, y); } return null; } private static Shape createShapeFromGElement(final SVGOMGElement el, int transX, int transY) { NodeList ch = el.getChildNodes(); int x = parseToInt(el.getAttribute("x")) + transX; int y = parseToInt(el.getAttribute("y")) + transY; for (int i = 0; i < ch.getLength(); i++) { Node n = ch.item(i); //allow only one shape for now if (n instanceof SVGOMUseElement) { return createShapeFromUseElement((SVGOMUseElement) n, x, y); } if (n instanceof SVGGraphicsElement) { return createShapeFromElement((SVGGraphicsElement) n, x, y); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -