/* * Copyright [2011] [wisemapping] * * Licensed under WiseMapping Public License, Version 1.0 (the "License"). * It is basically the Apache License, Version 2.0 (the "License") plus the * "powered by wisemapping" text requirement on every single page; * you may not use this file except in compliance with the License. * You may obtain a copy of the license at * * http://www.wisemapping.org/license * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.wisemapping.xml; import com.wisemapping.xml.svgmap.*; import com.wisemapping.xml.svgmap.ObjectFactory; import com.wisemapping.xml.vmlmap.*; import com.wisemapping.xml.vmlmap.Line; import com.wisemapping.xml.vmlmap.Polyline; import com.wisemapping.xml.vmlmap.Rect; import javax.xml.bind.JAXBException; import javax.xml.bind.JAXBContext; import javax.xml.bind.Unmarshaller; import javax.xml.bind.Marshaller; import java.io.InputStream; import java.io.OutputStream; import java.util.List; public class SvgToVMLConverter { private ObjectFactory svgObjectFactory; private static final int CORRECTION_HANDCODE = 5; private Object svgRootElem; public SvgToVMLConverter() { this.svgObjectFactory = new ObjectFactory(); } public void convert(final InputStream vmlDocument) throws JAXBException { final JAXBContext vmlContext = JAXBContext.newInstance("com.wisemapping.xml.vmlmap"); final Unmarshaller umarshaller = vmlContext.createUnmarshaller(); final Group rootElem = (Group) umarshaller.unmarshal(vmlDocument); this.svgRootElem = convert(rootElem); } private Svg convert(Group g) { final Svg svgElement = svgObjectFactory.createSvg(); svgElement.setPreserveAspectRatio("none"); /* */ final String coordorigin = g.getCoordorigin(); String coordSize = g.getCoordsize(); svgElement.setViewBox(coordorigin + ", " + coordSize); final Style style = Style.parse(g.getStyle()); float width = style.getWidth(); svgElement.setWidth(String.valueOf(width)); float height = style.getHeight(); svgElement.setHeight(String.valueOf(height)); // Convert connection lines ... final List polylines = g.getPolyline(); final List svgPolylines = svgElement.getPolyline(); for (Polyline vmlPolyline : polylines) { final com.wisemapping.xml.svgmap.Polyline svgPolyline = convert(vmlPolyline); svgPolylines.add(svgPolyline); } final List vmlLines = g.getLine(); final List svgLines = svgElement.getLine(); for (Line vmlLine : vmlLines) { final com.wisemapping.xml.svgmap.Line svgPolyline = convert(vmlLine); svgLines.add(svgPolyline); } // Convert Topics ... final List vmlTopics = g.getGroup(); final List svgTopics = svgElement.getG(); for (Group topic : vmlTopics) { G svgTopic = convertTopicGroup(topic); svgTopics.add(svgTopic); } // Convert connectors ... g.getOval(); return svgElement; } private G convertTopicGroup(final Group vmlTopic) { /** * * */ final G svgTopic = new G(); final String styleStr = vmlTopic.getStyle(); final Style style = Style.parse(styleStr); String transform = "translate(" + style.getLeft() + ", " + style.getTop() + ") scale(1, 1)"; svgTopic.setTransform(transform); float width = style.getWidth(); svgTopic.setWidth(String.valueOf(width)); float height = style.getHeight(); svgTopic.setHeight(String.valueOf(height)); svgTopic.setPreserveAspectRatio("none"); // Convert InnerShape ... final List roundrects = vmlTopic.getRoundrect(); float rectWidth = 0; float rectHeight = 0; for (Roundrect vmlRect : roundrects) { // Skip outerShape figure... final Fill vmlFill = vmlRect.getFill(); if (vmlFill == null || !"0".equals(vmlFill.getOpacity())) { final com.wisemapping.xml.svgmap.Rect svgRect = convert(vmlRect); svgTopic.setRect(svgRect); final Style rectStyle = Style.parse(vmlRect.getStyle()); rectWidth = rectStyle.getWidth(); rectHeight = rectStyle.getHeight(); } } final List vmlRects = vmlTopic.getRect(); for (Rect vmlRect : vmlRects) { // Skip outerShape figure... final Fill vmlFill = vmlRect.getFill(); if (vmlFill == null || !"0".equals(vmlFill.getOpacity())) { final com.wisemapping.xml.svgmap.Rect svgRect = convert(vmlRect); svgTopic.setRect(svgRect); final Style rectStyle = Style.parse(vmlRect.getStyle()); rectWidth = rectStyle.getWidth(); rectHeight = rectStyle.getHeight(); } } final List vmlLines = vmlTopic.getLine(); for (final Line vmlLine : vmlLines) { final String lineStyleStr = vmlLine.getStyle(); final Style lineStyle = Style.parse(lineStyleStr); if (lineStyle.isVisible()) { com.wisemapping.xml.svgmap.Line line = convert(vmlLine); svgTopic.setLine(line); } else { // Shape is line... final String from = vmlLine.getFrom(); String[] formPoints = from.split(","); final String to = vmlLine.getTo(); String[] toPoints = to.split(","); rectWidth = Float.parseFloat(formPoints[0]) - Float.parseFloat(toPoints[0]); rectWidth = Math.abs(rectWidth); rectHeight = Float.parseFloat(formPoints[1]); } } // Convert connection ovals.. final List vmlOvals = vmlTopic.getOval(); for (Oval vmlOval : vmlOvals) { // Skip outerShape figure... final Ellipse svgElipse = convert(vmlOval); if (svgElipse != null) { svgTopic.setEllipse(svgElipse); } } // Convert Text ... final List vmlTextShape = vmlTopic.getShape(); final Text svgText = convertTextShape(vmlTextShape.get(0), rectWidth, rectHeight); svgTopic.setText(svgText); return svgTopic; } private com.wisemapping.xml.svgmap.Rect convert(Rect vmlRect) { final com.wisemapping.xml.svgmap.Rect svgRect = new com.wisemapping.xml.svgmap.Rect(); final Style style = Style.parse(vmlRect.getStyle()); float width = style.getWidth(); svgRect.setWidth(String.valueOf(width)); float height = style.getHeight(); svgRect.setHeight(height); String top = style.getTop(); svgRect.setY(Float.parseFloat(top)); String left = style.getLeft(); svgRect.setX(Float.parseFloat(left)); // Fill properties ... final String fillColor = vmlRect.getFillcolor(); svgRect.setFill(fillColor); // Stroke properties ... final String strokeColor = vmlRect.getStrokecolor(); svgRect.setStroke(strokeColor); svgRect.setStrokeWidth("0.5px"); return svgRect; } private Ellipse convert(final Oval vmlOval) { /** * * * * * * * SVG: * */ final Style style = Style.parse(vmlOval.getStyle()); Ellipse svgElipse = null; if (style.isVisible()) { svgElipse = new Ellipse(); float width = style.getWidth(); svgElipse.setWidth(width); svgElipse.setRx(width / 2); float height = style.getHeight(); svgElipse.setHeight(height); svgElipse.setRy(height / 2); String top = style.getTop(); svgElipse.setCy(Float.parseFloat(top) + (width / 2)); String left = style.getLeft(); svgElipse.setCx(Float.parseFloat(left) + (height / 2)); // Fill properties ... final String fillColor = vmlOval.getFillcolor(); svgElipse.setFill(fillColor); // Stroke properties ... final String strokeColor = vmlOval.getStrokecolor(); svgElipse.setStroke(strokeColor); svgElipse.setStrokeWidth("0.5px"); } return svgElipse; } private com.wisemapping.xml.svgmap.Line convert(final Line vmlLine) { /** * VML: * * <:stroke dashstyle="solid"> * * * SVG: * */ com.wisemapping.xml.svgmap.Line svgLine = new com.wisemapping.xml.svgmap.Line(); final String from = vmlLine.getFrom(); final String[] fromPoints = from.split(","); svgLine.setX1(Float.parseFloat(fromPoints[0])); svgLine.setY1(Float.parseFloat(fromPoints[1])); final String to = vmlLine.getTo(); final String[] toPoints = to.split(","); svgLine.setX2(Float.parseFloat(toPoints[0])); svgLine.setY2(Float.parseFloat(toPoints[1])); String strokeweight = vmlLine.getStrokeweight(); svgLine.setStrokeWidth(strokeweight); String stokeColor = vmlLine.getStrokecolor(); svgLine.setStroke(stokeColor); return svgLine; } private Text convertTextShape(Shape vmlTextShape, float boxWidth, float boxHeigth) { /** * * * * Central Topic * * * * SVG: * Central Topic * */ final Text svgText = new Text(); Textbox vmlTextBox = vmlTextShape.getTextbox(); final String textBoxStyleStr = vmlTextBox.getStyle(); final Style textBoxStyle = Style.parse(textBoxStyleStr); // @todo: Take this hardcode from javascript ... float fontSize = textBoxStyle.getFontSize(); float scale = vmlTextBox.getXFontScale(); float svgFontSize = fontSize / scale; svgText.setFontSize(svgFontSize); // Set text properties... final String textValue = vmlTextBox.getSPAN().getSPAN(); svgText.setContent(textValue); final String color = textBoxStyle.getColor(); svgText.setFill(color); final String fontWidth = textBoxStyle.getFontWidth(); svgText.setFontWeight(fontWidth); // Positionate font... final String textSize = vmlTextBox.getXTextSize(); final String[] split = textSize.split(","); float textWidth = Float.valueOf(split[0]); float textHeight = Float.valueOf(split[1]); svgText.setX(boxWidth - textWidth); svgText.setY(boxHeigth - textHeight + CORRECTION_HANDCODE); return svgText; } private com.wisemapping.xml.svgmap.Rect convert(Roundrect vmlRect) { /* * VML: * * * * * * SVG: * * */ final com.wisemapping.xml.svgmap.Rect svgRect = new com.wisemapping.xml.svgmap.Rect(); final Style style = Style.parse(vmlRect.getStyle()); svgRect.setRy(2.7F); svgRect.setRx(2.7F); float width = style.getWidth(); svgRect.setWidth(String.valueOf(width)); float height = style.getHeight(); svgRect.setHeight(height); String top = style.getTop(); svgRect.setY(Float.parseFloat(top)); String left = style.getLeft(); svgRect.setX(Float.parseFloat(left)); // Fill properties ... final String fillColor = vmlRect.getFillcolor(); svgRect.setFill(fillColor); // Stroke properties ... final String strokeColor = vmlRect.getStrokecolor(); svgRect.setStroke(strokeColor); svgRect.setStrokeWidth("0.5px"); return svgRect; } private com.wisemapping.xml.svgmap.Polyline convert(Polyline vmlPolyline) { /* * * * * * */ final com.wisemapping.xml.svgmap.Polyline svgPolyline = svgObjectFactory.createPolyline(); final String rPoints = vmlPolyline.getXPoints(); svgPolyline.setPoints(rPoints); final String strokeColor = vmlPolyline.getStrokecolor(); svgPolyline.setStroke(strokeColor); // @todo: Take from SVG. svgPolyline.setFill("none"); svgPolyline.setStrokeWidth("1px"); svgPolyline.setStrokeOpacity("1"); return svgPolyline; } public void toXml(OutputStream os) throws JAXBException { final JAXBContext svgContext = JAXBContext.newInstance("com.wisemapping.xml.svgmap"); Marshaller m = svgContext.createMarshaller(); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); m.marshal(svgRootElem, os); } }