443 lines
16 KiB
Java
443 lines
16 KiB
Java
/*
|
|
* 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");
|
|
|
|
/*
|
|
<v:group style="WIDTH: 1270px; POSITION: absolute; HEIGHT: 705px" coordsize="889,493" coordorigin="-445,-247">
|
|
<svgElement preserveAspectRatio="none" viewBox="-445.9 -221.9 891.8 443.8" height="634" width="1274" id="workspace" focusable="true">
|
|
*/
|
|
|
|
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<Polyline> polylines = g.getPolyline();
|
|
final List<com.wisemapping.xml.svgmap.Polyline> svgPolylines = svgElement.getPolyline();
|
|
for (Polyline vmlPolyline : polylines) {
|
|
final com.wisemapping.xml.svgmap.Polyline svgPolyline = convert(vmlPolyline);
|
|
svgPolylines.add(svgPolyline);
|
|
}
|
|
|
|
final List<Line> vmlLines = g.getLine();
|
|
final List<com.wisemapping.xml.svgmap.Line> svgLines = svgElement.getLine();
|
|
for (Line vmlLine : vmlLines) {
|
|
final com.wisemapping.xml.svgmap.Line svgPolyline = convert(vmlLine);
|
|
svgLines.add(svgPolyline);
|
|
}
|
|
|
|
// Convert Topics ...
|
|
final List<Group> vmlTopics = g.getGroup();
|
|
final List<G> 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) {
|
|
/**
|
|
* <v:group style="LEFT: 222px; WIDTH: 100px; CURSOR: move; POSITION: absolute; TOP: -53px; HEIGHT: 100px" coordsize="100,100">
|
|
* <g transform="translate(225, -52) scale(1, 1)" height="100" width="100" focusable="true" preserveAspectRatio="none">
|
|
*/
|
|
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<Roundrect> 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<Rect> 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<Line> 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<Oval> 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<Shape> 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) {
|
|
|
|
/**
|
|
* <v:oval style="LEFT: 5px; VISIBILITY: hidden; WIDTH: 6px; POSITION: absolute; TOP: 5px; HEIGHT: 6px"
|
|
* coordsize="21600,21600" fillcolor="#e0e5ef" stroked="t" strokecolor="#023bb9" strokeweight="6762emu">
|
|
* <v:stroke dashstyle="solid"></v:stroke>
|
|
* <v:fill></v:fill>
|
|
* </v:oval>
|
|
*
|
|
*
|
|
* SVG:
|
|
* <ellipse stroke="#023BB9" visibility="hidden" fill="#E0E5EF" stroke-width="0.5px" cy="3" cx="3" ry="3" rx="3"
|
|
* height="6" width="6"></ellipse>
|
|
*/
|
|
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:
|
|
* <v:line style="POSITION: absolute" from="0,0" to="157,-150" fillcolor="white" stroked="t" strokecolor="#495879"
|
|
* strokeweight="1px">
|
|
* <:stroke dashstyle="solid"></v:stroke>
|
|
* </v:line>
|
|
*
|
|
* SVG:
|
|
* <line y2="14" x2="49" y1="14" x1="-1" visibility="hidden" style="cursor: move;" stroke="#495879"
|
|
stroke-width="1px"></line>
|
|
*/
|
|
|
|
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) {
|
|
/**
|
|
* <v:shape
|
|
* style="Z-INDEX: 10; LEFT: 9px; WIDTH: 130px; CURSOR: default; POSITION: absolute; TOP: 9px; HEIGHT: 1px; antialias: true"
|
|
* coordsize="100,100">
|
|
* <v:textbox
|
|
* style="MARGIN-TOP: 0.187pt; LEFT: auto; FONT: bold 19px verdana; MARGIN-LEFT: 0.25pt; OVERFLOW: visible; WIDTH: 138.531pt; COLOR: #023bb9; POSITION: absolute; TOP: auto; HEIGHT: 0.343pt"
|
|
* xFontScale="1.4" xTextSize="100.1,16.0" inset="0,0,0,0">
|
|
* <SPAN style="WIDTH: 100%; HEIGHT: 100%">
|
|
* <SPAN>Central Topic</SPAN>
|
|
* </SPAN>
|
|
* </v:textbox>
|
|
* </v:shape>
|
|
* SVG:
|
|
* <text x="9" y="19" style="cursor: default;" fill="#023BB9" font-weight="bold" font-style="normal"
|
|
* font-size="13.4375" font-family="verdana" focusable="true">Central Topic
|
|
* </text>
|
|
*/
|
|
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:
|
|
* <v:roundrect style="LEFT: 0px; WIDTH: 62px; CURSOR: move; POSITION: absolute; TOP: 0px; HEIGHT: 23px"
|
|
* arcsize="9830f" coordsize="21600,21600" fillcolor="#e0e5ef" stroked="t" strokecolor="#023bb9"
|
|
* strokeweight="6762emu">
|
|
* <v:stroke dashstyle="solid"></v:stroke>
|
|
* <v:fill></v:fill>
|
|
* </v:roundrect>
|
|
*
|
|
* SVG:
|
|
* <rect style="cursor: move;" fill="#E0E5EF" stroke="#023BB9" stroke-width="0.5px" y="0" x="0" ry="2.7" rx="2.7"
|
|
* height="18" width="68"></rect>
|
|
*
|
|
*/
|
|
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) {
|
|
|
|
/*
|
|
* <v:polyline style="POSITION: absolute" rPoints="167.1, 100.0 177.1, 100.0 177.1, 130.5 182.1, 135.5 230.6, 135.5"
|
|
* filled="f" strokecolor="#495879" strokeweight=".75pt">
|
|
* <v:stroke opacity="1" dashstyle="solid"></v:stroke>
|
|
* </v:polyline>
|
|
*
|
|
* <polyline points="173.5,100 183.5,100 183.5,129 188.5,134 240,134" stroke-opacity="1" stroke="#495879"
|
|
* stroke-width="1px" fill="none"></polyline>
|
|
*/
|
|
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);
|
|
}
|
|
|
|
}
|