123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172 |
- /**
- * Copyright (c) 2006-2016, JGraph Ltd
- * Copyright (c) 2006-2016, Gaudenz Alder
- */
- package com.mxgraph.io.vsdx;
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.UnsupportedEncodingException;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.LinkedHashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
- import java.util.logging.Logger;
- import java.util.zip.Deflater;
- import javax.xml.parsers.DocumentBuilder;
- import javax.xml.parsers.DocumentBuilderFactory;
- import org.apache.commons.codec.binary.Base64;
- import org.apache.commons.lang3.StringUtils;
- import org.w3c.dom.Element;
- import org.w3c.dom.Node;
- import org.w3c.dom.NodeList;
- import com.mxgraph.io.vsdx.theme.Color;
- import com.mxgraph.model.mxCell;
- import com.mxgraph.model.mxGeometry;
- import com.mxgraph.online.Utils;
- import com.mxgraph.util.mxConstants;
- import com.mxgraph.util.mxPoint;
- import com.mxgraph.util.mxResources;
- import com.mxgraph.view.mxGraph;
- /**
- * This class is a wrapper for one Shape Element.<br/>
- * This class is responsible for retrieve all the properties of the shape and add it
- * to the graph. If a property is not found in the shape element but it is an instance
- * of a Master, the property is taken from the masterShape element. If the property
- * is not found neither in the masterShape , and it has a reference to a stylesheet
- * the property is taken from there.
- */
- public class VsdxShape extends Shape
- {
- private static final String ARROW_NO_FILL_MARKER = "0";
- /**
- * Number of d.p. to round non-integers to
- */
- static public int maxDp = 2;
-
- // For debugging to switch off shape matching by name
- static public boolean USE_SHAPE_MATCH = true;
- /**
- * Whether or not to assume HTML labels
- */
- public boolean htmlLabels = true;
- /**
- * Master Shape referenced by the shape.
- */
- protected Shape masterShape;
- /**
- * Master element referenced by the shape.
- */
- protected mxVsdxMaster master;
- /**
- * If the shape is a sub shape, this is a reference to its root shape, otherwise null
- */
- protected VsdxShape rootShape = this;
- public double parentHeight;
-
- /**
- * The prefix of the shape name
- */
- protected String shapeName = null;
-
- /**
- * Whether this cell is a vertex
- */
- protected boolean vertex = true;
-
- protected Map<Integer, VsdxShape> childShapes = new HashMap<Integer, VsdxShape>();
-
- protected static DocumentBuilder docBuilder = null;
-
- public static final Set<String> OFFSET_ARRAY = new HashSet<String>(Arrays.asList(
- new String[] {"Organizational unit",
- "Domain 3D"}
- ));
- public static final String stencilTemplate = "<shape h=\"htemplate\" w=\"wtemplate\" aspect=\"variable\" strokewidth=\"inherit\"><connections></connections><background></background><foreground></foreground></shape>";
-
- public static final float[] arrowSizes = {2, 3, 5, 7, 9, 22, 45};
-
- public static final Map<Integer, String> arrowTypes;
-
- static
- {
- try
- {
- mxResources.add("com/mxgraph/io/vdx/resources/edgeNameU");
- mxResources.add("com/mxgraph/io/vdx/resources/nameU");
-
- DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
- docBuilder = docFactory.newDocumentBuilder();
- }
- catch (Exception e)
- {
- // todo
- }
-
- arrowTypes = new HashMap<Integer, String>();
- arrowTypes.put(0, mxConstants.NONE);
- arrowTypes.put(1, mxConstants.ARROW_OPEN);
- arrowTypes.put(2, "blockThin");
- arrowTypes.put(3, mxConstants.ARROW_OPEN);
- arrowTypes.put(4, mxConstants.ARROW_BLOCK);
- arrowTypes.put(5, mxConstants.ARROW_CLASSIC);
- arrowTypes.put(10, mxConstants.ARROW_OVAL);
- arrowTypes.put(13, mxConstants.ARROW_BLOCK);
-
- arrowTypes.put(14, ARROW_NO_FILL_MARKER + mxConstants.ARROW_BLOCK);
- arrowTypes.put(17, ARROW_NO_FILL_MARKER + mxConstants.ARROW_CLASSIC);
- arrowTypes.put(20, ARROW_NO_FILL_MARKER + mxConstants.ARROW_OVAL);
- arrowTypes.put(22, ARROW_NO_FILL_MARKER + "diamond");
-
- arrowTypes.put(23, "dash");
- arrowTypes.put(24, "ERone");
- arrowTypes.put(25, "ERmandOne");
- arrowTypes.put(27, "ERmany");
- arrowTypes.put(28, "ERoneToMany");
- arrowTypes.put(29, "ERzeroToMany");
- arrowTypes.put(30, "ERzeroToOne");
-
- //approximations
- arrowTypes.put(6, mxConstants.ARROW_BLOCK);
- arrowTypes.put(7, mxConstants.ARROW_OPEN);
- arrowTypes.put(8, mxConstants.ARROW_CLASSIC);
-
- arrowTypes.put(9, "openAsync");
- arrowTypes.put(11, "diamond");
-
- arrowTypes.put(12, mxConstants.ARROW_OPEN);
-
- arrowTypes.put(15, ARROW_NO_FILL_MARKER + mxConstants.ARROW_BLOCK);
- arrowTypes.put(16, ARROW_NO_FILL_MARKER + mxConstants.ARROW_BLOCK);
- arrowTypes.put(18, ARROW_NO_FILL_MARKER + mxConstants.ARROW_BLOCK);
- arrowTypes.put(19, ARROW_NO_FILL_MARKER + mxConstants.ARROW_CLASSIC);
- arrowTypes.put(21, ARROW_NO_FILL_MARKER + "diamond");
- arrowTypes.put(26, "ERmandOne");
-
- arrowTypes.put(31, ARROW_NO_FILL_MARKER + mxConstants.ARROW_OVAL);
- arrowTypes.put(32, ARROW_NO_FILL_MARKER + mxConstants.ARROW_OVAL);
- arrowTypes.put(33, ARROW_NO_FILL_MARKER + mxConstants.ARROW_OVAL);
- arrowTypes.put(34, ARROW_NO_FILL_MARKER + mxConstants.ARROW_OVAL);
- arrowTypes.put(35, mxConstants.ARROW_OVAL);
- arrowTypes.put(36, mxConstants.ARROW_OVAL);
- arrowTypes.put(37, mxConstants.ARROW_OVAL);
- arrowTypes.put(38, mxConstants.ARROW_OVAL);
-
- arrowTypes.put(39, mxConstants.ARROW_BLOCK);
- arrowTypes.put(40, ARROW_NO_FILL_MARKER + mxConstants.ARROW_BLOCK);
-
- arrowTypes.put(41, ARROW_NO_FILL_MARKER + mxConstants.ARROW_OVAL);
- arrowTypes.put(42, mxConstants.ARROW_OVAL);
-
- arrowTypes.put(43, mxConstants.ARROW_OPEN);
- arrowTypes.put(44, mxConstants.ARROW_OPEN);
- arrowTypes.put(45, mxConstants.ARROW_OPEN);
- }
- private final static Logger LOGGER = Logger.getLogger(VsdxShape.class.getName());
- /**
- * Create a new instance of mxVdxShape.
- * This method get the references to the master element, master shape
- * and stylesheet.
- * @param shape
- */
- public VsdxShape(mxVsdxPage page, Element shape, boolean vertex, Map<String, mxVsdxMaster> masters, mxVsdxMaster master, mxVsdxModel model)
- {
- super(shape, model);
-
- String masterId = this.getMasterId();
- String masterShapeLocal = this.getShapeMasterId();
-
- if (masterId != null)
- {
- this.master = masters.get(masterId);
- }
- else
- {
- this.master = master;
- }
- if (this.master != null)
- {
- // Check if the master ID corresponds to the one passed in. If it doesn't, or doesn't
- // exist on this shape, this shape is within a group that has that master
-
- if (masterId == null && masterShapeLocal != null)
- {
- this.masterShape = this.master.getSubShape(masterShapeLocal);
- }
- else
- {
- this.masterShape = this.master.getMasterShape();
- }
- }
- if (this.debug != null && this.masterShape != null)
- {
- this.masterShape.debug = this.debug;
- }
-
- String name = getNameU();
- int index = name.lastIndexOf(".");
-
- if (index != -1)
- {
- name = name.substring(0, index);
- }
-
- this.shapeName = name;
-
- // Get sub-shapes
- NodeList shapesList = shape.getElementsByTagName(mxVsdxConstants.SHAPES);
-
- if (shapesList != null && shapesList.getLength() > 0)
- {
- Element shapesElement = (Element) shapesList.item(0);
- this.childShapes = page.parseShapes(shapesElement, this.master, false);
- }
-
- for (Map.Entry<Integer, VsdxShape> entry : childShapes.entrySet())
- {
- entry.getValue().setRootShape(this);
- }
-
- double rotation = this.calcRotation();
- this.rotation = rotation * 100/100;
- this.rotation = this.rotation % 360.0;
-
- this.vertex = vertex;
-
- mxVsdxTheme theme = model.getThemes().get(page.getCellIntValue("ThemeIndex", 33));
- int variant = page.getCellIntValue("VariationColorIndex", 0);
-
- setThemeAndVariant(theme, variant);
-
- //process shape geometry
- if (masterShape != null)
- {
- masterShape.processGeomList(null);
- processGeomList(masterShape.getGeomList());
- //recalculate width and height using master data
- if (this.width == 0) this.width = getScreenNumericalValue(getCellElement(mxVsdxConstants.WIDTH), 0);
-
- if (this.height == 0) this.height = getScreenNumericalValue(getCellElement(mxVsdxConstants.HEIGHT), 0);
- }
- else
- {
- processGeomList(null);
- }
- }
-
- /**
- * Locates the first entry for the specified attribute string in the shape hierarchy.
- * The order is to look locally, then delegate the request to the master shape
- * if it doesn't exist locally
- * @param key The key of the shape to find
- * @return the Element that first resolves to that shape key or null or none is found
- */
- public Element getShapeNode(String key)
- {
- Element elem = this.cellElements.get(key);
-
- if (elem == null && this.masterShape != null)
- {
- return this.masterShape.getCellElement(key);
- }
-
- return elem;
- }
- /**
- * Returns the value of the Text element.<br/>
- * If the shape has no text, it is obtained from the master shape.
- * @return Text label of the shape.
- */
- public String getTextLabel()
- {
- NodeList txtChildren = getTextChildren();
- if (txtChildren == null && masterShape != null)
- {
- txtChildren = masterShape.getTextChildren();
- }
- if (this.htmlLabels)
- {
- if (txtChildren != null)
- {
- // Collect text into same formatting paragraphs. If there's one paragraph, use the new system, otherwise
- // leave it to the old one.
- if (this.paragraphs == null)
- {
- initLabels(txtChildren);
- }
-
- if (this.paragraphs.size() == 0)
- {
- // valid way to have an empty label override a master value "<text />"
- return "";
- }
- else if (this.paragraphs.size() == 1)
- {
- return createHybridLabel(this.paragraphs.keySet().iterator().next());
- }
- else
- {
- return getHtmlTextContent(txtChildren);
- }
- }
- }
- else
- {
- String text = this.getText();
-
- if (text == null && masterShape != null)
- {
- return masterShape.getText();
- }
- else
- {
- return text;
- }
- }
-
- return null;
- }
- /**
- * Initialises the text labels
- * @param children the text Elements
- */
- protected void initLabels(NodeList children)
- {
- // Lazy init
- paragraphs = new LinkedHashMap<String,Paragraph>();
- String ch = null;
- String pg = null;
- String fld = null;
- for (int index = 0; index < children.getLength(); index++)
- {
- String value = null;
- Node node = children.item(index);
- String nodeName = node.getNodeName();
-
- switch (nodeName)
- {
- case "cp":
- {
- Element elem = (Element)node;
- ch = elem.getAttribute("IX");
- }
- break;
- case "tp":
- {
- // TODO
- Element elem = (Element)node;
- elem.getAttribute("IX");
- }
- break;
- case "pp":
- {
- Element elem = (Element)node;
- pg = elem.getAttribute("IX");
- }
- break;
- case "fld":
- {
- Element elem = (Element)node;
- fld = elem.getAttribute("IX");
- break;
- }
- case "#text":
- {
- value = StringUtils.chomp(node.getTextContent());
-
- // Assumes text is always last
- // null key is allowed
- Paragraph para = paragraphs.get(pg);
-
- if (para == null)
- {
- para = new Paragraph(value, ch, pg, fld);
- paragraphs.put(pg, para);
- }
- else
- {
- para.addText(value, ch, fld);
- }
- }
- }
- }
- }
- /**
- *
- * @param index
- * @return
- */
- protected String createHybridLabel(String index)
- {
- Paragraph para = this.paragraphs.get(index);
-
- // Paragraph
- this.styleMap.put(mxConstants.STYLE_ALIGN, getHorizontalAlign(index, false));
- this.styleMap.put(mxConstants.STYLE_SPACING_LEFT, getIndentLeft(index));
- this.styleMap.put(mxConstants.STYLE_SPACING_RIGHT, getIndentRight(index));
- this.styleMap.put(mxConstants.STYLE_SPACING_TOP, getSpBefore(index));
- this.styleMap.put(mxConstants.STYLE_SPACING_BOTTOM, getSpAfter(index));
- //this.styleMap.put("text-indent", getIndentFirst(index));
- this.styleMap.put(mxConstants.STYLE_VERTICAL_ALIGN, getAlignVertical());
-
- this.styleMap.put("fontColor", getTextColor(index));
- this.styleMap.put("fontSize", String.valueOf(Double.parseDouble(this.getTextSize(index))));
- this.styleMap.put("fontFamily", getTextFont(index));
-
- // Character
- int fontStyle = isBold(index) ? mxConstants.FONT_BOLD : 0;
- fontStyle |= isItalic(index) ? mxConstants.FONT_ITALIC : 0;
- fontStyle |= isUnderline(index) ? mxConstants.FONT_UNDERLINE : 0;
- this.styleMap.put("fontStyle", String.valueOf(fontStyle));
-
- this.styleMap.put(mxConstants.STYLE_TEXT_OPACITY, getTextOpacity(index));
- int numValues = para.numValues();
- String result = null;
-
- for (int i = 0; i < numValues; i++)
- {
- String value = para.getValue(i);
-
- if (value.isEmpty() && this.fields != null)
- {
- String fieldIx = para.getField(i);
-
- if (fieldIx != null)
- {
- value = this.fields.get(fieldIx);
-
- if (value == null && masterShape != null && masterShape.fields != null)
- {
- value = masterShape.fields.get(fieldIx);
- }
- }
- }
-
- if (value != null)
- {
- result = result == null ? value : result + value;
- }
- }
-
- return result;
- }
-
- /**
- * Checks if a nameU is for big connectors.
- * @param nameU NameU attribute.
- * @return Returns <code>true</code> if a nameU is for big connectors.
- */
- public boolean isConnectorBigNameU(String nameU)
- {
- return nameU.startsWith("60 degree single")
- || nameU.startsWith("45 degree single")
- || nameU.startsWith("45 degree double")
- || nameU.startsWith("60 degree double")
- || nameU.startsWith("45 degree tail")
- || nameU.startsWith("60 degree tail")
- || nameU.startsWith("45 degree tail")
- || nameU.startsWith("60 degree tail")
- || nameU.startsWith("Flexi-arrow 2")
- || nameU.startsWith("Flexi-arrow 1")
- || nameU.startsWith("Flexi-arrow 3")
- || nameU.startsWith("Double flexi-arrow")
- || nameU.startsWith("Fancy arrow");
- }
- /**
- * Checks if the shape represents a vertex.
- * @return Returns <code>true</code> if the shape represents a vertex.
- */
- public boolean isVertex()
- {
- return vertex;
- }
- /**
- * Returns the coordinates of the top left corner of the Shape.
- * When a coordinate is not found, it is taken from masterShape.
- * @param parentHeight Height of the parent cell of the shape.
- * @param rotation whether to allow for cell rotation
- * @return mxPoint that represents the coordinates
- */
- public mxPoint getOriginPoint(double parentHeight, boolean rotation)
- {
- double px = this.getPinX();
- double py = this.getPinY();
- double lpy = this.getLocPinY();
- double lpx = this.getLocPinX();
- double w = getScreenNumericalValue(this.getShapeNode(mxVsdxConstants.WIDTH), 0);
- double h = getScreenNumericalValue(this.getShapeNode(mxVsdxConstants.HEIGHT), 0);
- double x = px - lpx;
- double y = parentHeight - ((py) + (h - lpy));
- // If the location pins are not in the center of the vertex we
- // need to translate the origin
- if (rotation && (lpy != h/2 || lpx != w/2))
- {
- if (this.rotation != 0)
- {
- double vecX = w/2 - lpx;
- double vecY = lpy - h/2;
-
- double cos = Math.cos(Math.toRadians(360 - this.rotation));
- double sin = Math.sin(Math.toRadians(360 - this.rotation));
-
- return new mxPoint(x + vecX - (vecX * cos - vecY * sin), (vecX * sin + vecY * cos) + y -vecY);
- }
- }
- return new mxPoint(x, y);
- }
- /**
- * Returns the width and height of the Shape expressed like an mxPoint.<br/>
- * x = width<br/>
- * y = height<br/>
- * When a dimension is not found, it is taken from masterShape.
- * @return mxPoint that represents the dimensions of the shape.
- */
- public mxPoint getDimensions()
- {
- double w = getScreenNumericalValue(this.getShapeNode(mxVsdxConstants.WIDTH), 0);
- double h = getScreenNumericalValue(this.getShapeNode(mxVsdxConstants.HEIGHT), 0);
- return new mxPoint(w, h);
- }
- /**
- * Returns the value of the pinX element.
- * @return The shape pinX element
- */
- public double getPinX()
- {
- return getScreenNumericalValue(this.getShapeNode(mxVsdxConstants.PIN_X), 0);
- }
- /**
- * Returns the value of the pinY element in pixels.
- * @return Numerical value of the pinY element.
- */
- public double getPinY()
- {
- return getScreenNumericalValue(this.getShapeNode(mxVsdxConstants.PIN_Y), 0);
- }
- /**
- * Returns the value of the locPinX element in pixels.
- * @return Numerical value of the pinY element.
- */
- public double getLocPinX()
- {
- return getScreenNumericalValue(this.getShapeNode(mxVsdxConstants.LOC_PIN_X), 0);
- }
- /**
- * Returns the value of the locPinY element in pixels.
- * @return Numerical value of the locPinY element.
- */
- public double getLocPinY()
- {
- return getScreenNumericalValue(this.getShapeNode(mxVsdxConstants.LOC_PIN_Y), 0);
- }
- /**
- * Returns the opacity of the Shape.<br/>
- * @return Double in the range of (transparent = 0)..(100 = opaque)
- */
- private double getOpacity(String key)
- {
- double opacity = 100;
- if (this.isGroup())
- {
- opacity = 0;
- }
- opacity = getValueAsDouble(this.getCellElement(key), 0);
- opacity = 100 - opacity * 100;
- opacity = Math.max(opacity, 0);
- opacity = Math.min(opacity, 100);
- return opacity;
- }
- /**
- * Returns the background color for apply in the gradient.<br/>
- * If no gradient must be applicated, returns an empty string.
- * @return hexadecimal representation of the color.
- */
- private String getGradient()
- {
- String gradient = "";
- String fillPattern = this.getValue(this.getCellElement(mxVsdxConstants.FILL_PATTERN), "0");
- if (fillPattern.equals("25") || fillPattern.equals("27") || fillPattern.equals("28") || fillPattern.equals("30"))
- {
- gradient = this.getColor(this.getCellElement(mxVsdxConstants.FILL_BKGND));
- }
- else
- {
- mxVsdxTheme theme = getTheme();
-
- if (theme != null)
- {
- int styleFillClr = Integer.parseInt(this.getValue(this.getCellElement("QuickStyleFillColor"), "1"));
- int styleFillMtx = Integer.parseInt(this.getValue(this.getCellElement("QuickStyleFillMatrix"), "0"));
- Color gradColor = theme.getFillGraientColor(styleFillClr, styleFillMtx);
- if (gradColor != null) gradient = gradColor.toHexStr();
- }
- }
- return gradient;
- }
- /**
- * Returns the direction of the gradient.<br/>
- * If no gradient has to be applied, returns an empty string.
- * @return Direction.(east, west, north or south)
- */
- private String getGradientDirection()
- {
- String direction = "";
- String fillPattern = this.getValue(this.getCellElement(mxVsdxConstants.FILL_PATTERN), "0");
- if (fillPattern.equals("25"))
- {
- direction = mxConstants.DIRECTION_EAST;
- }
- else if (fillPattern.equals("27"))
- {
- direction = mxConstants.DIRECTION_WEST;
- }
- else if (fillPattern.equals("28"))
- {
- direction = mxConstants.DIRECTION_SOUTH;
- }
- else if (fillPattern.equals("30"))
- {
- direction = mxConstants.DIRECTION_NORTH;
- }
- return direction;
- }
- /**
- * Returns the rotation of the shape.<br/>
- * @return Rotation of the shape in degrees.
- */
- public double calcRotation()
- {
- double rotation = Double.valueOf(this.getValue(this.getCellElement(mxVsdxConstants.ANGLE), "0"));
- rotation = Math.toDegrees(rotation);
- rotation = rotation % 360;
- rotation = rotation * 100/100;
- return 360 - rotation;
- }
- /**
- * Used to pass in a parents rotation to the child
- * @param parentRotation the rotation of the parent
- */
- public void propagateRotation(double parentRotation)
- {
- this.rotation += parentRotation;
- this.rotation %= 360;
- this.rotation = this.rotation * 100/100;
- }
- /**
- * Returns the top spacing of the label in pixels.<br/>
- * The property may to be defined in master shape or text stylesheet.<br/>
- * @return Top spacing in double precision.
- */
- public double getTopSpacing()
- {
- double topMargin = this.getTextTopMargin();
- topMargin = (topMargin / 2 - 2.8) * 100/100;
- return topMargin;
- }
- /**
- * Returns the bottom spacing of the label in pixels.<br/>
- * The property may to be defined in master shape or text stylesheet.<br/>
- * @return Bottom spacing in double precision.
- */
- public double getBottomSpacing()
- {
- double bottomMargin = this.getTextBottomMargin();
- bottomMargin = (bottomMargin / 2 - 2.8) * 100/100;
- return bottomMargin;
- }
- /**
- * Returns the left spacing of the label in pixels.<br/>
- * The property may to be defined in master shape or text stylesheet.<br/>
- * @return Left spacing in double precision.
- */
- public double getLeftSpacing()
- {
- double leftMargin = this.getTextLeftMargin();
- leftMargin = (leftMargin / 2 - 2.8) * 100/100;
- return leftMargin;
- }
- /**
- * Returns the right spacing of the label in pixels.<br/>
- * The property may to be defined in master shape or text stylesheet.<br/>
- * @return Right spacing in double precision.
- */
- public double getRightSpacing()
- {
- double rightMargin = this.getTextRightMargin();
- rightMargin = (rightMargin / 2 - 2.8) * 100/100;
- return rightMargin;
- }
- /**
- * Checks if the label must be rotated.<br/>
- * The property may to be defined in master shape or text stylesheet.<br/>
- * @return Returns <code>true<code/> if the label should remain horizontal.
- */
- public boolean getLabelRotation()
- {
- boolean hor = true;
- //Defines rotation.
- double rotation = this.calcRotation();
- double angle = Double.valueOf(this.getValue(this.getCellElement(mxVsdxConstants.TXT_ANGLE), "0"));
-
- angle = Math.toDegrees(angle);
- angle = angle - rotation;
- if (!(Math.abs(angle) < 45 || Math.abs(angle) > 270))
- {
- hor = false;
- }
- return hor;
- }
- /**
- * Analyzes the shape and returns a string with the style.
- * @return style read from the shape.
- */
- public Map<String, String> getStyleFromShape()
- {
- styleMap.put("vsdxID", this.getId().toString());
-
- // Rotation.
- String labelRotation = getLabelRotation() ? "1" : "0";
- this.rotation = Math.round(this.rotation);
- if (!labelRotation.equals("1") && this.rotation != 90 && this.rotation != 270)
- {
- styleMap.put(mxConstants.STYLE_HORIZONTAL, labelRotation);
- }
- if (this.rotation != 0)
- {
- styleMap.put(mxConstants.STYLE_ROTATION, Double.toString(this.rotation));
- }
- // Fill color
- String fillcolor = getFillColor();
- if (!fillcolor.equals(""))
- {
- styleMap.put(mxConstants.STYLE_FILLCOLOR, fillcolor);
- }
- else
- {
- styleMap.put(mxConstants.STYLE_FILLCOLOR, "none");
- }
-
- Integer id = this.getId();
-
- this.styleDebug("ID = " + id + " , Fill Color = " + fillcolor);
- //Defines gradient
- String gradient = getGradient();
- if (!gradient.equals(""))
- {
- styleMap.put(mxConstants.STYLE_GRADIENTCOLOR, gradient);
- String gradientDirection = getGradientDirection();
- if (!gradientDirection.equals("") && !gradientDirection.equals(mxConstants.DIRECTION_SOUTH))
- {
- styleMap.put(mxConstants.STYLE_GRADIENT_DIRECTION, gradientDirection);
- }
- }
- else
- {
- styleMap.put(mxConstants.STYLE_GRADIENTCOLOR, "none");
- }
- double opacity = this.getOpacity(mxVsdxConstants.FILL_FOREGND_TRANS);
- if (opacity < 100)
- {
- styleMap.put(mxConstants.STYLE_FILL_OPACITY, Double.toString(opacity));
- }
- opacity = this.getOpacity(mxVsdxConstants.LINE_COLOR_TRANS);
- if (opacity < 100)
- {
- styleMap.put(mxConstants.STYLE_STROKE_OPACITY, Double.toString(opacity));
- }
-
- Map<String, String> form = getForm();
- if (form.containsKey(mxConstants.STYLE_SHAPE) &&
- (form.get(mxConstants.STYLE_SHAPE).startsWith("image;")))
- {
- styleMap.put(mxConstants.STYLE_WHITE_SPACE, "wrap");
- }
- styleMap.putAll(form);
- //Defines line Pattern
- if (isDashed())
- {
- styleMap.put(mxConstants.STYLE_DASHED, "1");
-
- String dashPattern = getDashPattern();
-
- if (dashPattern != null)
- {
- styleMap.put(mxConstants.STYLE_DASH_PATTERN, dashPattern);
- }
- }
-
- String color = getStrokeColor();
- double tr = this.getStrokeTransparency();
-
- this.styleDebug("ID = " + id + " , Color = " + color + " , stroke transparency = " + tr);
- if (!color.equals("") && tr != 1)
- {
- styleMap.put(mxConstants.STYLE_STROKECOLOR, color);
- }
- else
- {
- //styleMap.put(mxConstants.STYLE_STROKECOLOR, "none");
- }
- //Defines the line width
- double lWeight = getLineWidth() * 100/100;
- if (lWeight != 1)
- {
- styleMap.put(mxConstants.STYLE_STROKEWIDTH, Double.toString(lWeight));
- }
- /** SHADOW **/
- if (isShadow())
- {
- styleMap.put(mxConstants.STYLE_SHADOW, mxVsdxConstants.TRUE);
- }
- //Defines label top spacing
- double topMargin = getTopSpacing() * 100/100;
- if (topMargin != 0)
- {
- styleMap.put(mxConstants.STYLE_SPACING_TOP, Double.toString(topMargin));
- }
- //Defines label bottom spacing
- double bottomMargin = getBottomSpacing() * 100/100;
- if (bottomMargin != 0)
- {
- styleMap.put(mxConstants.STYLE_SPACING_BOTTOM, Double.toString(bottomMargin));
- }
- //Defines label left spacing
- double leftMargin = getLeftSpacing() * 100/100;
- if (leftMargin != 0)
- {
- styleMap.put(mxConstants.STYLE_SPACING_LEFT, Double.toString(leftMargin));
- }
- //Defines label right spacing
- double rightMargin = getRightSpacing() * 100/100;
- if(rightMargin !=0)
- {
- styleMap.put(mxConstants.STYLE_SPACING_RIGHT, Double.toString(rightMargin));
- }
- String direction = getDirection(form);
- if (direction != mxConstants.DIRECTION_EAST)
- {
- styleMap.put(mxConstants.STYLE_DIRECTION, direction);
- }
-
- Element xForm = (Element) shape.getElementsByTagName(mxVsdxConstants.X_FORM).item(0);
-
- if (xForm != null)
- {
- Node flipX = xForm.getElementsByTagName(mxVsdxConstants.FLIP_X).item(0);
- Node flipY = xForm.getElementsByTagName(mxVsdxConstants.FLIP_Y).item(0);
-
- if (flipX != null && flipX.getTextContent().equals("1"))
- {
- styleMap.put(mxConstants.STYLE_FLIPH, "1");
- }
-
- if (flipY != null && flipY.getTextContent().equals("1"))
- {
- styleMap.put(mxConstants.STYLE_FLIPV, "1");
- }
- }
-
- resolveCommonStyles();
- return this.styleMap;
- }
- private String getDashPattern() {
- ArrayList<Double> pattern = null;
-
- String linePattern = this.getValue(this.getCellElement(mxVsdxConstants.LINE_PATTERN), "0");
- if (linePattern.equals("Themed"))
- {
- mxVsdxTheme theme = getTheme();
-
- if (theme != null)
- {
- int styleLineMtx = Integer.parseInt(this.getValue(this.getCellElement("QuickStyleLineMatrix"), "0"));
- pattern = isVertex()? theme.getLineDashPattern(styleLineMtx) : theme.getConnLineDashPattern(styleLineMtx);
- }
- }
- else
- {
- pattern = getLineDashPattern(Integer.parseInt(linePattern));
- }
-
- if (pattern != null && !pattern.isEmpty())
- {
- StringBuilder str = new StringBuilder();
-
- for (Double len : pattern)
- {
- str.append(String.format("%.2f ", len));
- }
- return str.toString().trim();
- }
- return null;
- }
- /**
- * Checks if the lines of the shape are dashed.<br/>
- * The property may to be defined in master shape or line stylesheet.<br/>
- * @return Returns <code>true</code> if the lines of the shape are dashed.
- */
- public boolean isDashed()
- {
- String linePattern = this.getValue(this.getCellElement(mxVsdxConstants.LINE_PATTERN), "0");
- if (linePattern.equals("Themed"))
- {
- mxVsdxTheme theme = getTheme();
-
- if (theme != null)
- {
- int styleLineMtx = Integer.parseInt(this.getValue(this.getCellElement("QuickStyleLineMatrix"), "0"));
- return isVertex()? theme.isLineDashed(styleLineMtx) : theme.isConnLineDashed(styleLineMtx);
- }
- }
- else if (!(linePattern.equals("0") || linePattern.equals("1")))
- {
- return true;
- }
-
- return false;
- }
- /**
- * Returns the line width.<br/>
- * The property may to be defined in master shape or line stylesheet.<br/>
- * @return Line width in pixels.
- */
- public double getLineWidth()
- {
- //if an edge has a fill geometry, then the line width matches the min of the shape width & height
- if (!isVertex() && geomList != null && !geomList.isNoFill())
- {
- return Math.min(height, width);
- }
- String lineWeight = getValue(this.getCellElement(mxVsdxConstants.LINE_WEIGHT), "0");
-
- double lWeight = 0;
- try
- {
- if (lineWeight.equals("Themed"))
- {
- mxVsdxTheme theme = getTheme();
-
- if (theme != null)
- {
- int styleLineMtx = Integer.parseInt(this.getValue(this.getCellElement("QuickStyleLineMatrix"), "0"));
- lWeight = (isVertex()? theme.getLineWidth(styleLineMtx) : theme.getConnLineWidth(styleLineMtx)) / 10000.0;
- }
- }
- else
- {
- lWeight = Double.parseDouble(lineWeight);
- lWeight = getScreenNumericalValue(lWeight);
- }
- }
- catch (Exception e)
- {
- // ignore
- }
-
- //Value is fixed for weight < 1
- if (lWeight < 1)
- {
- lWeight *= 2;
- }
-
- return lWeight;
- }
- /**
- * Returns the start arrow size.<br/>
- * The property may to be defined in master shape or line stylesheet.<br/>
- * Determines the value in pixels of each arrow size category in .vdx.
- * @return Size in pixels.
- */
- public float getStartArrowSize()
- {
- String baSize = getValue(this.getCellElement(mxVsdxConstants.BEGIN_ARROW_SIZE), "4");
-
- try
- {
- int size = 4;
-
- if (baSize.equals("Themed"))
- {
- mxVsdxTheme theme = getTheme();
-
- if (theme != null)
- {
- int styleLineMtx = Integer.parseInt(this.getValue(this.getCellElement("QuickStyleLineMatrix"), "0"));
- size = isVertex()? theme.getStartSize(styleLineMtx) : theme.getConnStartSize(styleLineMtx);
- }
- }
- else
- {
- size = Integer.valueOf(baSize);
- }
-
- return VsdxShape.arrowSizes[size];
- }
- catch (Exception e)
- {
- // ignore
- }
-
- return 4;
- }
- /**
- * Returns the end arrow size.<br/>
- * The property may to be defined in master shape or line stylesheet.<br/>
- * Determines the value in pixels of each arrow size category in .vdx.
- * @return Size in pixels.
- */
- public float getFinalArrowSize()
- {
- String eaSize = getValue(this.getCellElement(mxVsdxConstants.END_ARROW_SIZE), "4");
- try
- {
- int size = 4;
-
- if (eaSize.equals("Themed"))
- {
- mxVsdxTheme theme = getTheme();
-
- if (theme != null)
- {
- int styleLineMtx = Integer.parseInt(this.getValue(this.getCellElement("QuickStyleLineMatrix"), "0"));
- size = isVertex()? theme.getEndSize(styleLineMtx) : theme.getConnEndSize(styleLineMtx);
- }
- }
- else
- {
- size = Integer.valueOf(eaSize);
- }
-
- return VsdxShape.arrowSizes[size];
- }
- catch (Exception e)
- {
- // ignore
- }
-
- return 4;
- }
- /**
- * Returns whether the cell is Rounded.<br/>
- * The property may to be defined in master shape or line stylesheet.<br/>
- * @return Returns <code>true</code> if the cell is Rounded.
- */
- public boolean isRounded()
- {
- String val = getValue(this.getCellElement(mxVsdxConstants.ROUNDING), "0");
- return Double.valueOf(val) > 0;
- }
- /**
- * Return if the line has shadow.<br/>
- * The property may to be defined in master shape or line stylesheet.<br/>
- * @return Returns <code>mxVdxConstants.TRUE</code> if the line has shadow.
- */
- public boolean isShadow()
- {
- // https://msdn.microsoft.com/en-us/library/office/jj230454.aspx TODO
- // double shdwShow = this.getNumericalValue(this.getStyleNode(mxVdxConstants.SHDW_PATTERN), 0);
- String shdw = this.getValue(this.getCellElement(mxVsdxConstants.SHDW_PATTERN), "0");
-
- if (shdw.equals("Themed"))
- {
- // TODO get value from theme
- }
- else if (!shdw.equals("0"))
- {
- return true;
- }
- return false;
- }
- /**
- * Returns the style of the edge. (Orthogonal or straight)
- * @return Edge Style.
- */
- public Map<String, String> getEdgeStyle(Map<String, String> edgeShape)
- {
- Map<String, String> result = new HashMap<String, String>();
- String edgeName = edgeShape.get(mxConstants.STYLE_SHAPE);
- if (edgeName.equals("mxgraph.lean_mapping.electronic_info_flow_edge"))
- {
- result.put(mxConstants.STYLE_EDGE, mxConstants.NONE);
- return result;
- }
- else
- {
- result.put(mxConstants.STYLE_EDGE, mxConstants.EDGESTYLE_ELBOW);
- return result;
- }
- // else
- // {
- // result.put(mxConstants.STYLE_EDGE, mxConstants.NONE);
- // return result;
- // }
- }
- /**
- * Returns the master's Id of the Shape.
- * @return Master's ID of the shape, null if has not a master.
- */
- public String getMasterId()
- {
- if (shape.hasAttribute(mxVsdxConstants.MASTER))
- {
- return shape.getAttribute(mxVsdxConstants.MASTER);
- }
- else
- {
- return null;
- }
- }
- /**
- * Returns the masterShape's Id of the shape.
- * @return Master Shape's ID of the shape, null if has not a master shape.
- */
- public String getShapeMasterId()
- {
- if (shape.hasAttribute(mxVsdxConstants.MASTER_SHAPE))
- {
- return shape.getAttribute(mxVsdxConstants.MASTER_SHAPE);
- }
- else
- {
- return null;
- }
- }
- /**
- * Checks if a shape contains other shapes inside.
- * @return Returns <code>true</code> if a shape contains other shapes inside.
- */
- public boolean isGroup()
- {
- return shape.getAttribute("Type").equals("Group");
- }
- /**
- * Checks if a shape contains other shapes inside.
- * @return Returns <code>true</code> if a shape contains other shapes inside.
- */
- public static String getType(Element shape)
- {
- return shape.getAttribute("Type");
- }
- public mxVsdxMaster getMaster()
- {
- return master;
- }
- /**
- * Returns the NameU attribute.
- * @return Value of the NameU attribute.
- */
- public String getNameU()
- {
- String result = shape.getAttribute(mxVsdxConstants.NAME_U);
-
- if ((result == null || result.equals("")) && masterShape != null)
- {
- result = masterShape.getNameU();
- }
-
- return result;
- }
-
- /**
- * Returns the master name of the shape
- * @return Master name of the shape
- */
- public String getMasterName()
- {
- return shapeName;
- }
-
- public void setLabelOffset(mxCell vertex, String style)
- {
- String nameU = "";
- String masterNameU = "";
- if (shape.hasAttribute(mxVsdxConstants.NAME_U))
- {
- nameU = shape.getAttribute(mxVsdxConstants.NAME_U);
- }
- if (this.getMaster() != null && this.getMaster().getMasterElement() != null)
- {
- if (this.getMaster().getMasterElement().hasAttribute(mxVsdxConstants.NAME_U))
- {
- masterNameU = this.getMaster().getMasterElement().getAttribute(mxVsdxConstants.NAME_U);
- }
- }
- //check for shape name/type, because of different (shape specific) treatment of each
- if (nameU.startsWith("Organizational unit")
- || masterNameU.startsWith("Organizational unit"))
- {
- Element control = (Element) shape.getElementsByTagName(mxVsdxConstants.CONTROL).item(0);
- Element xEl = null;
- String xS = "0.0";
- Element yEl = null;
- String yS = "-0.4";
- if (control != null)
- {
- xEl = (Element) control.getElementsByTagName(mxVsdxConstants.X).item(0);
-
- if (xEl.hasAttribute("F"))
- {
- xS = xEl.getAttribute("F");
- }
- else
- {
- xS = xEl.getTextContent();
- }
-
- yEl = (Element) control.getElementsByTagName(mxVsdxConstants.Y).item(0);
-
- if (yEl.hasAttribute("F"))
- {
- yS = yEl.getAttribute("F");
- }
- else
- {
- yS = yEl.getTextContent();
- }
- }
- mxGeometry geometry = vertex.getGeometry();
- //clean the formula strings and hope it will work with a specific algorithm
- xS = xS.replace("Width/2+", "");
- xS = xS.replace("DL", "");
- yS = yS.replace("Height*", "");
- if (xS.equals("Inh"))
- {
- xS = "0.0";
- }
- if (yS.equals("Inh"))
- {
- yS = "-0.4";
- }
- if (yS.contains("txtHeight"))
- {
- yS = "-0.4";
- }
- String[] styleArray = style.split(";");
- String tabHeight = "";
- for (int i = 0; i < styleArray.length; i++)
- {
- String currStyle = styleArray[i];
- currStyle = currStyle.trim();
- if(currStyle.startsWith("tabHeight="))
- {
- tabHeight = currStyle.replace("tabHeight=", "");
- }
- }
- if (tabHeight.equals(""))
- {
- tabHeight = "20";
- }
- Double tH = Double.valueOf(tabHeight);
- Double x = Double.parseDouble(xS);
- Double y = Double.parseDouble(yS);
- Double h = geometry.getHeight();
- Double xFinal = geometry.getWidth() * 0.1 + x * 100;
- Double yFinal = h - h * y - tH / 2;
- mxPoint offset = new mxPoint(xFinal, yFinal);
- vertex.getGeometry().setOffset(offset);
- }
- else if (nameU.startsWith("Domain 3D")
- || masterNameU.startsWith("Domain 3D"))
- {
- Element control = (Element) shape.getElementsByTagName(mxVsdxConstants.CONTROL).item(0);
- Element xEl = null;
- String xS = "0.0";
- Element yEl = null;
- String yS = "-0.4";
- if (control != null)
- {
- xEl = (Element) control.getElementsByTagName(mxVsdxConstants.X).item(0);
- xS = xEl.getAttribute("F");
- yEl = (Element) control.getElementsByTagName(mxVsdxConstants.Y).item(0);
- yS = yEl.getAttribute("F");
- }
- mxGeometry geometry = vertex.getGeometry();
- //clean the formula strings and hope it will work with a specific algorithm
- xS = xS.replace("Width/2+", "");
- xS = xS.replace("DL", "");
- yS = yS.replace("Height*", "");
- if (xS.equals("Inh") || xS.equals(""))
- {
- xS = "0.0";
- }
- if (yS.equals("Inh") || yS.equals(""))
- {
- yS = "-0.4";
- }
- if (yS.contains("txtHeight"))
- {
- yS = "-0.4";
- }
- Double x = Double.parseDouble(xS);
- Double y = Double.parseDouble(yS);
- Double h = geometry.getHeight();
- Double xFinal = geometry.getWidth() * 0.1 + x * 100;
- Double yFinal = h - h * y;
- mxPoint offset = new mxPoint(xFinal, yFinal);
- vertex.getGeometry().setOffset(offset);
- }
- }
-
- /**
- * Returns the constant that represents the Shape.
- * @return String that represent the form.
- */
- public Map<String, String> getForm()
- {
- Map<String, String> result = new HashMap<String, String>();
-
- this.styleDebug("Looking to match shape = " + shapeName);
- if (shapeName != null && !shapeName.equals("") && VsdxShape.USE_SHAPE_MATCH)
- {
- String trans = mxResources.get(shapeName);
-
- if (trans != null && !trans.equals(""))
- {
- this.styleDebug("Translation = " + trans);
- result.put(mxConstants.STYLE_SHAPE, trans);
- return result;
- }
- }
-
- if (this.isVertex())
- {
- try
- {
- String type = VsdxShape.getType(this.getShape());
- // String foreignType = "";
- this.styleDebug("shape type = " + type);
- //The master may contain the foreign object data
- if (this.imageData != null || (mxVsdxConstants.FOREIGN.equals(type) && masterShape != null && masterShape.imageData != null))
- {
- Map<String, String> imageData = this.imageData != null? this.imageData : masterShape.imageData;
-
- result.put("shape", "image");
- result.put("aspect", "fixed");
- String iType = imageData.get("iType");
- String iData = imageData.get("iData");
-
- result.put("image", "data:image/" + iType + "," + iData);
- return result;
- }
-
- //Shape inherit master geometry and can change some of it or override it completely. So, no need to parse the master instead of the shape itself
- String parsedGeom = this.parseGeom();
- if (parsedGeom.equals(""))
- {
- this.styleDebug("No geom found");
- return result;
- }
-
- String stencil = Utils.encodeURIComponent(parsedGeom, "UTF-8");
-
- byte[] bytes = stencil.getBytes("UTF-8");
- Deflater deflater = new Deflater(Deflater.BEST_COMPRESSION, true);
- deflater.setInput(bytes);
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-
- deflater.finish();
-
- byte[] buffer = new byte[1024];
-
- while (!deflater.finished())
- {
- int count = deflater.deflate(buffer);
- outputStream.write(buffer, 0, count);
- }
-
- try
- {
- outputStream.close();
- }
- catch (IOException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
- byte[] output = outputStream.toByteArray();
- deflater.end();
-
- byte[] encoded = Base64.encodeBase64(output);
- String enc = new String(encoded, "UTF-8");
-
- result.put(mxConstants.STYLE_SHAPE, "stencil(" + enc + ")");
- }
- catch (UnsupportedEncodingException e)
- {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- else
- {
- return getEdgeStyle();
- }
-
- return result;
- }
- /**
- * Checks if a shape may to be imported like an Off page reference.
- * @return Returns <code>true</code> if a shape may to be imported like an Off page reference.
- */
- public boolean isOff_page_reference()
- {
- String name = getNameU();
- if (name.equals("Off-page reference") || name.equals("Lined/Shaded process"))
- {
- return true;
- }
- return false;
- }
- /**
- * Checks if a shape may to be imported like an External process.
- * @return Returns <code>true</code> if a shape may to be imported like an External process.
- */
- public boolean isExternal_process()
- {
- return (shapeName.equals("External process"));
- }
- /**
- * Returns the direction of the shape.
- * @param form Form of the shape.
- * @return Direction(south, north, east and south)
- */
- public String getDirection(Map<String, String> form)
- {
- String offsetS = (String) mxResources.get("mxOffset" + shapeName);
-
- if (offsetS == null || offsetS.equals("0") || offsetS.equals(""))
- {
- return mxConstants.DIRECTION_EAST;
- }
- else if (offsetS.equals("1"))
- {
- return mxConstants.DIRECTION_SOUTH;
- }
- else if (offsetS.equals("2"))
- {
- return mxConstants.DIRECTION_WEST;
- }
- else if (offsetS.equals("3"))
- {
- return mxConstants.DIRECTION_NORTH;
- }
- return mxConstants.DIRECTION_EAST;
- }
-
- /**
- * Checks if a shape may to be imported like a Sub-process.
- * This method is approximated.
- * @return Returns <code>true</code> if a shape may to be imported like a
- * Sub-process.
- */
- public boolean isSubproces()
- {
- return shapeName.equals("Subproces");
- }
- /**
- * @return style map containing the proper shape and style (if needed) of a Visio "dynamic connector" edge
- */
- public Map<String, String> getEdgeStyle()
- {
- Map<String, String> result = new HashMap<String, String>();
- result.put("edgeStyle", "none");
- return result;
- //result.put("edgeStyle", "orthogonalEdgeStyle");
- //return result;
- //result.put("curved", "1");
- //return result;
- //return null;
- }
-
- public Map<Integer, VsdxShape> getChildShapes()
- {
- return childShapes;
- }
- public void setChildShapes(Map<Integer, VsdxShape> childShapes)
- {
- this.childShapes = childShapes;
- }
-
- public boolean isDisplacedLabel()
- {
- String txtPinXF = this.getAttribute(mxVsdxConstants.TEXT_X_FORM, mxVsdxConstants.TXT_PIN_X, "F", "");
- String txtPinYF = this.getAttribute(mxVsdxConstants.TEXT_X_FORM, mxVsdxConstants.TXT_PIN_Y, "F", "");
- String txtWidthF = this.getAttribute(mxVsdxConstants.TEXT_X_FORM, mxVsdxConstants.TXT_WIDTH, "F", "");
- String txtHeightF = this.getAttribute(mxVsdxConstants.TEXT_X_FORM, mxVsdxConstants.TXT_HEIGHT, "F", "");
- if (masterShape != null)
- {
- if (txtPinXF == "" || txtPinXF.toLowerCase().equals("inh"))
- {
- txtPinXF = masterShape.getAttribute(mxVsdxConstants.TEXT_X_FORM, mxVsdxConstants.TXT_PIN_X, "F", "");
- }
- if (txtPinYF == "" || txtPinYF.toLowerCase().equals("inh"))
- {
- txtPinYF = masterShape.getAttribute(mxVsdxConstants.TEXT_X_FORM, mxVsdxConstants.TXT_PIN_Y, "F", "");
- }
- if (txtWidthF == "" || txtWidthF.toLowerCase().equals("inh"))
- {
- txtWidthF = masterShape.getAttribute(mxVsdxConstants.TEXT_X_FORM, mxVsdxConstants.TXT_WIDTH, "F", "");
- }
- if (txtHeightF == "" || txtHeightF.toLowerCase().equals("inh"))
- {
- txtHeightF = masterShape.getAttribute(mxVsdxConstants.TEXT_X_FORM, mxVsdxConstants.TXT_HEIGHT, "F", "");
- }
- }
- if (txtPinXF.toLowerCase().equals("width*0.5") &&
- txtPinYF.toLowerCase().equals("height*0.5") &&
- txtWidthF.toLowerCase().equals("width*1") &&
- txtHeightF.toLowerCase().equals("height*1"))
- {
- return false;
- }
- else if (txtPinXF.toLowerCase().startsWith("width*") &&
- txtPinYF.toLowerCase().startsWith("height*") &&
- txtWidthF.toLowerCase().startsWith("width*") &&
- txtHeightF.toLowerCase().startsWith("height*"))
- // else if (txtPinXF.toLowerCase().startsWith("width*") &&
- // txtPinYF.toLowerCase().startsWith("height*"))
- {
- return true;
- }
- else if (txtPinXF.toLowerCase().startsWith("controls.row_") ||
- txtPinYF.toLowerCase().startsWith("controls.row_"))
- {
- return true;
- }
- return false;
- }
-
- public boolean isRotatedLabel()
- {
- String txtAngleValue = this.getAttribute(mxVsdxConstants.TEXT_X_FORM, mxVsdxConstants.TXT_ANGLE, "V", "");
- if (masterShape != null)
- {
- if (txtAngleValue.equals(""))
- {
- txtAngleValue = masterShape.getAttribute(mxVsdxConstants.TEXT_X_FORM, mxVsdxConstants.TXT_ANGLE, "V", "");
- }
- }
- if (!txtAngleValue.equals("0") && !txtAngleValue.equals("0.0") && !txtAngleValue.equals(""))
- {
- return true;
- }
- return false;
- }
-
- public void setRootShape(VsdxShape shape)
- {
- this.rootShape = shape;
- }
- public VsdxShape getRootShape()
- {
- return this.rootShape;
- }
-
- // Edge specific methods
-
- /**
- * Returns the coordinates of the begin point of an Edge Shape.
- * @param parentHeight Height of the parent of the shape.
- * @return mxPoint that represents the coordinates.
- */
- public mxPoint getStartXY(double parentHeight)
- {
- double startX = getScreenNumericalValue(this.getCellElement(mxVsdxConstants.BEGIN_X), 0);
- double startY = parentHeight - getScreenNumericalValue(this.getCellElement(mxVsdxConstants.BEGIN_Y), 0);
- return new mxPoint(startX, startY);
- }
- /**
- * Returns the coordinates of the end point of an Edge Shape.
- * @param parentHeight Height of the parent of the shape.
- * @return mxPoint that represents the coordinates.
- */
- public mxPoint getEndXY(double parentHeight)
- {
- double endX = getScreenNumericalValue(this.getCellElement(mxVsdxConstants.END_X), 0);
- double endY = parentHeight- getScreenNumericalValue(this.getCellElement(mxVsdxConstants.END_Y), 0);
- return new mxPoint(endX, endY);
- }
-
- /**
- * Returns the list of routing points of a edge shape.
- * @param parentHeight Height of the parent of the shape.
- * @return List of mxPoint that represents the routing points.
- */
- public List<mxPoint> getRoutingPoints(double parentHeight, mxPoint startPoint, double rotation/*, boolean flibX, boolean flibY*/)
- {
- if (geomList != null)
- {
- return geomList.getRoutingPoints(parentHeight, startPoint, rotation);
- }
- return null;
- }
- /**
- * Returns the list of control points of a edge shape.
- * @param parentHeight Height of the parent of the shape.
- * @return List of mxPoint that represents the control points.
- */
- public List<mxPoint> getControlPoints(double parentHeight)
- {
- mxPoint startXY = getStartXY(parentHeight);
- mxPoint endXY = getEndXY(parentHeight);
- ArrayList<mxPoint> pointList = new ArrayList<mxPoint>();
-
- if (shape != null)
- {
- NodeList geomList = shape.getElementsByTagName(mxVsdxConstants.GEOM);
- if (geomList.getLength() > 0)
- {
- Element firstGeom = (Element) geomList.item(0);
- Element firstNURBS = (Element) firstGeom.getElementsByTagName(mxVsdxConstants.NURBS_TO).item(0);
- Element firstE = (Element) firstNURBS.getElementsByTagName("E").item(0);
-
- if (firstE != null)
- {
- String f = firstE.getAttribute("F");
- f = f.replaceAll("NURBS\\(", "");
- f = f.replaceAll("\\)", "");
- f = f.replaceAll(",", " ");
- f = f.replaceAll("\\s\\s", " ");
- String[] pointsS = f.split(" ");
- double[] pointsRaw = new double[pointsS.length];
-
- for (int i = 0; i < pointsS.length; i++)
- {
- pointsRaw[i] = Double.parseDouble(pointsS[i]);
- }
-
- for (int i = 2; i + 4 < pointsS.length; i = i + 4)
- {
- mxPoint currPoint = new mxPoint();
- double rawX = pointsRaw[i + 2];
- double rawY = pointsRaw[i + 3];
- double width = Math.abs(endXY.getX() - startXY.getX());
- double widthFixed = Math.min(100, width);
- double heightFixed = 100;
- double finalX = 0;
-
- finalX = startXY.getX() + widthFixed * rawX;
- currPoint.setX(finalX);
- currPoint.setY(startXY.getY() - heightFixed * rawY);
- pointList.add(currPoint);
- }
-
- return pointList;
- }
- else
- {
- return null;
- }
- }
- }
- return null;
- }
-
- /**
- * Analyzes a edge shape and returns a string with the style.
- * @return style read from the edge shape.
- */
- public Map<String, String> getStyleFromEdgeShape(double parentHeight)
- {
- styleMap.put("vsdxID", this.getId().toString());
- // Rotation.
- // double rotation = this.getRotation();
- // rotation = Math.round(rotation);
- //
- // String rotationString = getLabelRotation() ? "1" : "0";
- //
- // if (!rotationString.equals("1") && rotation != 90 && rotation != 270)
- // {
- // styleMap.put(mxConstants.STYLE_HORIZONTAL, rotationString);
- // }
- //
- // if (rotation != 0 && rotation != 360)
- // {
- // rotation = rotation * 100/100;
- //
- // styleMap.put(mxConstants.STYLE_ROTATION, Double.toString(rotation));
- // }
- //Defines Edge Shape
- Map<String, String> edgeShape = getForm();
- if (edgeShape != null && !edgeShape.equals(""))
- {
- styleMap.putAll(edgeShape);
- }
- //Defines Pattern
- if (isDashed())
- {
- styleMap.put(mxConstants.STYLE_DASHED, "1");
-
- String dashPattern = getDashPattern();
-
- if (dashPattern != null)
- {
- styleMap.put(mxConstants.STYLE_DASH_PATTERN, dashPattern);
- }
- }
- //Defines Begin Arrow
- String startArrow = getEdgeMarker(true);
- if(startArrow != null)
- {
- if (startArrow.startsWith(ARROW_NO_FILL_MARKER))
- {
- startArrow = startArrow.substring(ARROW_NO_FILL_MARKER.length());
- styleMap.put(mxConstants.STYLE_STARTFILL, "0");
- }
- styleMap.put(mxConstants.STYLE_STARTARROW, startArrow);
- }
- //Defines End Arrow
- String endArrow = getEdgeMarker(false);
- if(endArrow != null)
- {
- if (endArrow.startsWith(ARROW_NO_FILL_MARKER))
- {
- endArrow = endArrow.substring(ARROW_NO_FILL_MARKER.length());
- styleMap.put(mxConstants.STYLE_ENDFILL, "0");
- }
- styleMap.put(mxConstants.STYLE_ENDARROW, endArrow);
- }
- //Defines the start arrow size.
- float saSize = getStartArrowSize() * 100/100;
- if (saSize != 6)
- {
- styleMap.put(mxConstants.STYLE_STARTSIZE, Float.toString(saSize));
- }
- //Defines the end arrow size.
- float faSize = getFinalArrowSize() * 100/100;
- if (faSize != 6)
- {
- styleMap.put(mxConstants.STYLE_ENDSIZE, Float.toString(faSize));
- }
- //Defines the line width
- double lWeight = getLineWidth() * 100/100;
- if (lWeight != 1.0)
- {
- styleMap.put(mxConstants.STYLE_STROKEWIDTH, Double.toString(lWeight));
- }
-
- // Color
- String color = getStrokeColor();
- if (!color.equals(""))
- {
- styleMap.put(mxConstants.STYLE_STROKECOLOR, color);
- }
- // Shadow
- if (isShadow())
- {
- styleMap.put(mxConstants.STYLE_SHADOW, mxVsdxConstants.TRUE);
- }
- if (isConnectorBigNameU(getNameU()))
- {
- styleMap.put(mxConstants.STYLE_SHAPE, mxConstants.SHAPE_ARROW);
- String fillcolor = getFillColor();
- if (!fillcolor.equals(""))
- {
- styleMap.put(mxConstants.STYLE_FILLCOLOR, fillcolor);
- }
- }
- //Defines label top spacing
- double topMargin = getTopSpacing() * 100/100;
- styleMap.put(mxConstants.STYLE_SPACING_TOP, Double.toString(topMargin));
- //Defines label bottom spacing
- double bottomMargin = getBottomSpacing() * 100/100;
- styleMap.put(mxConstants.STYLE_SPACING_BOTTOM, Double.toString(bottomMargin));
- //Defines label left spacing
- double leftMargin = getLeftSpacing() * 100/100;
- styleMap.put(mxConstants.STYLE_SPACING_LEFT, Double.toString(leftMargin));
- //Defines label right spacing
- double rightMargin = getRightSpacing() * 100/100;
- styleMap.put(mxConstants.STYLE_SPACING_RIGHT, Double.toString(rightMargin));
- //Defines label vertical align
- String verticalAlign = getAlignVertical();
- styleMap.put(mxConstants.STYLE_VERTICAL_ALIGN, verticalAlign);
- //Defines Label Rotation
- // styleMap.put(mxConstants.STYLE_HORIZONTAL, getLabelRotation());
- styleMap.put("html", "1");
-
- resolveCommonStyles();
- // System.out.println(this.getId());
- // System.out.println(Arrays.toString(styleMap.entrySet().toArray()));
- return this.styleMap;
- }
-
- /**
- * Analyzes a edge shape and returns a string with the style.
- * @return style read from the edge shape.
- */
- public Map<String, String> resolveCommonStyles()
- {
- /** LABEL BACKGROUND COLOR **/
- String lbkgnd = this.getTextBkgndColor(this.getCellElement(mxVsdxConstants.TEXT_BKGND));
- if (!lbkgnd.equals(""))
- {
- this.styleMap.put(mxConstants.STYLE_LABEL_BACKGROUNDCOLOR, lbkgnd);
- }
-
- /** ROUNDING **/
- this.styleMap.put(mxConstants.STYLE_ROUNDED, isRounded() ? mxVsdxConstants.TRUE : mxVsdxConstants.FALSE);
-
- return styleMap;
- }
- /**
- * Returns the arrow of the line.
- * @return Type of arrow.
- */
- public String getEdgeMarker(boolean start)
- {
- String marker = this.getValue(this.getCellElement(start ? mxVsdxConstants.BEGIN_ARROW : mxVsdxConstants.END_ARROW), "0");
- int val = 0;
- try
- {
- if (marker.equals("Themed"))
- {
- mxVsdxTheme theme = getTheme();
-
- if (theme != null)
- {
- int styleLineMtx = Integer.parseInt(this.getValue(this.getCellElement("QuickStyleLineMatrix"), "0"));
- val = isVertex()? theme.getEdgeMarker(start, styleLineMtx) : theme.getConnEdgeMarker(start, styleLineMtx);
-
- }
- }
- else
- {
- val = Integer.parseInt(marker);
- }
- }
- catch (Exception e)
- {
- // ignore
- }
- String type = VsdxShape.arrowTypes.get(val);
-
- if (val > 0 && type == null)
- {
- //if arrow head type is not supported, use the open arrow instead
- type = VsdxShape.arrowTypes.get(1);
- }
-
- return type;
- }
-
- /**
- * Locates the first entry for the specified style string in the style hierarchy.
- * The order is to look locally, then delegate the request to the relevant parent style
- * if it doesn't exist locally
- * @param key The key of the style to find
- * @return the Element that first resolves to that style key or null or none is found
- */
- protected Element getCellElement(String key)
- {
- Element elem = super.getCellElement(key);
-
- if (elem == null && this.masterShape != null)
- {
- return this.masterShape.getCellElement(key);
- }
-
- return elem;
- }
-
- protected Element getCellElement(String cellKey, String index, String sectKey)
- {
- Element elem = super.getCellElement(cellKey, index, sectKey);
-
- if (elem == null && this.masterShape != null)
- {
- return this.masterShape.getCellElement(cellKey, index, sectKey);
- }
-
- return elem;
- }
-
- /**
- * Creates a sub shape for <b>shape</b> that contains the label. Used internally, when the label is positioned by an anchor.
- * @param graph
- * @param shape the shape we want to create the label for
- * @param parent
- * @param parentHeight
- * @return label sub-shape
- */
- public mxCell createLabelSubShape(mxGraph graph, mxCell parent)
- {
- double txtWV = getScreenNumericalValue(getShapeNode(mxVsdxConstants.TXT_WIDTH), getWidth());
- double txtHV = getScreenNumericalValue(getShapeNode(mxVsdxConstants.TXT_HEIGHT), getHeight());
- double txtLocPinXV = getScreenNumericalValue(getShapeNode(mxVsdxConstants.TXT_LOC_PIN_X), txtWV / 2.0);
- double txtLocPinYV = getScreenNumericalValue(getShapeNode(mxVsdxConstants.TXT_LOC_PIN_Y), txtHV / 2.0);
- double txtPinXV =getScreenNumericalValue(getShapeNode(mxVsdxConstants.TXT_PIN_X), txtLocPinXV);
- double txtPinYV = getScreenNumericalValue(getShapeNode(mxVsdxConstants.TXT_PIN_Y), txtLocPinYV);
- double txtAngleV = getValueAsDouble(getShapeNode(mxVsdxConstants.TXT_ANGLE), 0);
- String textLabel = getTextLabel();
- if (textLabel != null && !textLabel.isEmpty())
- {
- Map<String, String> styleMap = new HashMap<String, String>(getStyleMap());
- styleMap.put(mxConstants.STYLE_FILLCOLOR, mxConstants.NONE);
- styleMap.put(mxConstants.STYLE_STROKECOLOR, mxConstants.NONE);
- styleMap.put(mxConstants.STYLE_GRADIENTCOLOR, mxConstants.NONE);
-
- //We don't need to override these attributes in order to properly align the text
- if (!styleMap.containsKey("align")) styleMap.put("align", "center");
- if (!styleMap.containsKey("verticalAlign")) styleMap.put("verticalAlign", "middle");
- if (!styleMap.containsKey("whiteSpace")) styleMap.put("whiteSpace", "wrap");
-
- // Doesn't make sense to set a shape, it's not rendered and doesn't affect the text perimeter
- styleMap.remove("shape");
- //styleMap.put("html", "1");
- if (txtAngleV != 0)
- {
- double labRot = txtAngleV * 180 / Math.PI;
- labRot = Math.round((labRot + getRotation()) * 100.0) / 100.0;
- if (labRot != 0.0)
- {
- styleMap.put("rotation", Double.toString(labRot));
- }
- }
- String style = "text;"
- + mxVsdxUtils.getStyleString(styleMap, "=");
- double y = parent.getGeometry().getHeight() - (txtPinYV + txtHV - txtLocPinYV);
- double x = txtPinXV - txtLocPinXV;
- mxCell v1 = (mxCell) graph.insertVertex(parent, null, textLabel, x, y, txtWV, txtHV, style + ";html=1;");
- return v1;
- }
- return null;
- }
- public mxPoint getLblEdgeOffset(mxPoint beginXY, mxPoint endXY, List<mxPoint> points)
- {
- //currently, edges with multiple segments are not supported
- //TODO use the code from https://github.com/jgraph/mxgraph/blob/master/javascript/src/js/view/mxGraphView.js#L1953 to calculate mxGraph label offset instead of the default mid point (width/2, height/2)
- if (points == null || points.isEmpty() || (points.size() == 1 && points.get(0).equals(endXY)))
- {
- //Calculate the text offset
- double txtWV = getScreenNumericalValue(getShapeNode(mxVsdxConstants.TXT_WIDTH), getWidth());
- double txtHV = getScreenNumericalValue(getShapeNode(mxVsdxConstants.TXT_HEIGHT), getHeight());
- double txtLocPinXV = getScreenNumericalValue(getShapeNode(mxVsdxConstants.TXT_LOC_PIN_X), 0);
- double txtLocPinYV = getScreenNumericalValue(getShapeNode(mxVsdxConstants.TXT_LOC_PIN_Y), 0);
- double txtPinXV = getScreenNumericalValue(getShapeNode(mxVsdxConstants.TXT_PIN_X), 0);
- double txtPinYV = getScreenNumericalValue(getShapeNode(mxVsdxConstants.TXT_PIN_Y), 0);
-
- double y = getHeight()/2 - (txtPinYV - txtLocPinYV + txtHV/2);
- double x = txtPinXV - txtLocPinXV + txtWV/2 - getWidth()/2;
-
- return new mxPoint(x, y);
- }
- else
- {
- return null;
- }
- }
- }
|