/** * Carries out preprocessing that makes JEuclid handle the document better. * * @param doc Document */ static void preprocessForJEuclid(Document doc) { // underbrace and overbrace NodeList list = doc.getElementsByTagName("mo"); for (int i = 0; i < list.getLength(); i++) { Element mo = (Element) list.item(i); String parentName = ((Element) mo.getParentNode()).getTagName(); if (parentName == null) { continue; } if (parentName.equals("munder") && isTextChild(mo, "\ufe38")) { mo.setAttribute("stretchy", "true"); mo.removeChild(mo.getFirstChild()); mo.appendChild(doc.createTextNode("\u23df")); } else if (parentName.equals("mover") && isTextChild(mo, "\ufe37")) { mo.setAttribute("stretchy", "true"); mo.removeChild(mo.getFirstChild()); mo.appendChild(doc.createTextNode("\u23de")); } } // menclose for long division doesn't allow enough top padding. Oh, and // <mpadded> isn't implemented. And there isn't enough padding to left of // the bar either. Solve by adding an <mover> with just an <mspace> over# // the longdiv, contained within an mrow that adds a <mspace> before it. list = doc.getElementsByTagName("menclose"); for (int i = 0; i < list.getLength(); i++) { Element menclose = (Element) list.item(i); // Only for longdiv if (!"longdiv".equals(menclose.getAttribute("notation"))) { continue; } Element mrow = doc.createElementNS(WebMathsService.NS, "mrow"); Element mover = doc.createElementNS(WebMathsService.NS, "mover"); Element mspace = doc.createElementNS(WebMathsService.NS, "mspace"); Element mspaceW = doc.createElementNS(WebMathsService.NS, "mspace"); boolean previousElement = false; for (Node previous = menclose.getPreviousSibling(); previous != null; previous = previous.getPreviousSibling()) { if (previous.getNodeType() == Node.ELEMENT_NODE) { previousElement = true; break; } } if (previousElement) { mspaceW.setAttribute("width", "4px"); } menclose.getParentNode().insertBefore(mrow, menclose); menclose.getParentNode().removeChild(menclose); mrow.appendChild(mspaceW); mrow.appendChild(mover); mover.appendChild(menclose); mover.appendChild(mspace); } }
/** used for cut and paste. */ public void addObjectFromClipboard(String a_value) throws CircularIncludeException { Reader reader = new StringReader(a_value); Document document = null; try { document = UJAXP.getDocument(reader); } catch (Exception e) { e.printStackTrace(); return; } // try-catch Element root = document.getDocumentElement(); if (!root.getNodeName().equals("clipboard")) { return; } // if Node child; for (child = root.getFirstChild(); child != null; child = child.getNextSibling()) { if (!(child instanceof Element)) { continue; } // if Element element = (Element) child; IGlyphFactory factory = GlyphFactory.getFactory(); if (XModule.isMatch(element)) { EModuleInvoke module = (EModuleInvoke) factory.createXModule(element); addModule(module); continue; } // if if (XContour.isMatch(element)) { EContour contour = (EContour) factory.createXContour(element); addContour(contour); continue; } // if if (XInclude.isMatch(element)) { EIncludeInvoke include = (EIncludeInvoke) factory.createXInclude(element); addInclude(include); continue; } // if } // while }
/** * Process a track element. This should return a single track, but could return multiple tracks * since the uniqueness of the track id is not enforced. * * @param session * @param element * @param additionalInformation * @return */ private List<Track> processTrack( Session session, Element element, HashMap additionalInformation) { String id = getAttribute(element, SessionAttribute.ID.getText()); // TODo -- put in utility method, extacts attributes from element **Definitely need to do this HashMap<String, String> tAttributes = new HashMap(); HashMap<String, String> drAttributes = null; NamedNodeMap tNodeMap = element.getAttributes(); for (int i = 0; i < tNodeMap.getLength(); i++) { Node node = tNodeMap.item(i); String value = node.getNodeValue(); if (value != null && value.length() > 0) { tAttributes.put(node.getNodeName(), value); } } if (element.hasChildNodes()) { drAttributes = new HashMap(); Node childNode = element.getFirstChild(); Node sibNode = childNode.getNextSibling(); String sibName = sibNode.getNodeName(); if (sibName.equals(SessionElement.DATA_RANGE.getText())) { NamedNodeMap drNodeMap = sibNode.getAttributes(); for (int i = 0; i < drNodeMap.getLength(); i++) { Node node = drNodeMap.item(i); String value = node.getNodeValue(); if (value != null && value.length() > 0) { drAttributes.put(node.getNodeName(), value); } } } } // Get matching tracks. List<Track> matchedTracks = trackDictionary.get(id); if (matchedTracks == null) { log.info("Warning. No tracks were found with id: " + id + " in session file"); } else { for (final Track track : matchedTracks) { // Special case for sequence & gene tracks, they need to be removed before being placed. if (version >= 4 && track == geneTrack || track == seqTrack) { igv.removeTracks(Arrays.asList(track)); } track.restorePersistentState(tAttributes); if (drAttributes != null) { DataRange dr = track.getDataRange(); dr.restorePersistentState(drAttributes); track.setDataRange(dr); } } trackDictionary.remove(id); } NodeList elements = element.getChildNodes(); process(session, elements, additionalInformation); return matchedTracks; }
@Override protected void initChildren(Element eThis) throws OmException { Node nPrevious = eThis.getPreviousSibling(); if (nPrevious != null && nPrevious instanceof Text) { String sText = ((Text) nPrevious).getData(); if (sText.length() > 0 && Character.isWhitespace(sText.charAt(sText.length() - 1))) bSpaceBefore = true; } Node nAfter = eThis.getNextSibling(); if (nAfter != null && nAfter instanceof Text) { String sText = ((Text) nAfter).getData(); if (sText.length() > 0 && Character.isWhitespace(sText.charAt(0))) bSpaceAfter = true; } List<Place> lPlaces = new LinkedList<Place>(); int iPlace = 0; StringBuffer sbText = new StringBuffer(); for (Node n = eThis.getFirstChild(); n != null; n = n.getNextSibling()) { if (n instanceof Element) { Element eplace = (Element) n; if (!eplace.getTagName().equals("eplace")) throw new OmFormatException("<equation> may only contain text and <eplace> tags"); Element[] aeChildren = XML.getChildren(eplace); QComponent qcChild; boolean bImplicit = false; if (aeChildren.length != 1) // Treats more than one child as inside <t> { qcChild = getQDocument().build(this, eplace, "t"); bImplicit = true; } else // Treats single child as specific component (auto-sizing works) qcChild = getQDocument().build(this, aeChildren[0], null); addChild(qcChild); // Must be stored in standard child array so it // can be found etc. // See if width/height is specified int iWidth, iHeight; if (eplace.hasAttribute("width") && eplace.hasAttribute("height")) { try { iWidth = Integer.parseInt(eplace.getAttribute("width")); iHeight = Integer.parseInt(eplace.getAttribute("height")); } catch (NumberFormatException nfe) { throw new OmFormatException("<equation> <eplace>: width= and height= must be integers"); } } else { Dimension d = qcChild.getApproximatePixelSize(); if (d == null) throw new OmFormatException( "<equation> <eplace>: Except for components that support automatic " + "size estimation and fixing, <eplace> must include width= and height="); iWidth = d.width; iHeight = d.height; } Place p = new Place(); p.sID = "p" + (iPlace++); p.qc = qcChild; p.iWidth = iWidth; p.iHeight = iHeight; p.bImplicit = bImplicit; if (!eplace.hasAttribute("label")) throw new OmFormatException("<equation> <eplace>: Must include label="); if (eplace.hasAttribute("label")) p.sLabel = eplace.getAttribute("label"); else p.sLabel = null; if (eplace.hasAttribute("for")) p.sLabelFor = eplace.getAttribute("for"); else if (qcChild instanceof Labelable) p.sLabelFor = qcChild.getID(); lPlaces.add(p); // Add in the equation format text representing the placeholder sbText.append("\\placeholder{" + p.sID + "}{" + p.iWidth + "," + p.iHeight + "}"); } else if (n instanceof Text) { sbText.append(n.getNodeValue()); } } sEquation = sbText.toString(); apPlaces = lPlaces.toArray(new Place[0]); }
/** * creates a new image * * @param svgHandle a svg handle * @param resourceId the id of the resource from which the image will be created */ protected void createNewImage(SVGHandle svgHandle, String resourceId) { if (svgHandle != null && resourceId != null && !resourceId.equals("")) { Element resourceElement = null; resourceElement = svgHandle.getScrollPane().getSVGCanvas().getDocument().getElementById(resourceId); final String fresourceId = resourceId; if (resourceElement != null) { final SVGHandle fhandle = svgHandle; // creating the canvas and setting its properties final JSVGCanvas canvas = new JSVGCanvas() { @Override public void dispose() { removeKeyListener(listener); removeMouseMotionListener(listener); removeMouseListener(listener); disableInteractions = true; selectableText = false; userAgent = null; bridgeContext.dispose(); super.dispose(); } }; // the element to be added Element elementToAdd = null; canvas.setDocumentState(JSVGComponent.ALWAYS_STATIC); canvas.setDisableInteractions(true); // creating the new document final String svgNS = SVGDOMImplementation.SVG_NAMESPACE_URI; final SVGDocument doc = (SVGDocument) resourceElement.getOwnerDocument().cloneNode(false); // creating the root element final Element root = (Element) doc.importNode(resourceElement.getOwnerDocument().getDocumentElement(), false); doc.appendChild(root); // removing all the attributes of the root element NamedNodeMap attributes = doc.getDocumentElement().getAttributes(); for (int i = 0; i < attributes.getLength(); i++) { if (attributes.item(i) != null) { doc.getDocumentElement().removeAttribute(attributes.item(i).getNodeName()); } } // adding the new attributes for the root root.setAttributeNS(null, "width", imageSize.width + ""); root.setAttributeNS(null, "height", imageSize.height + ""); root.setAttributeNS(null, "viewBox", "0 0 " + imageSize.width + " " + imageSize.height); // the defs element that will contain the cloned resource node final Element defs = (Element) doc.importNode(resourceElement.getParentNode(), true); root.appendChild(defs); if (resourceElement.getNodeName().equals("linearGradient") || resourceElement.getNodeName().equals("radialGradient") || resourceElement.getNodeName().equals("pattern")) { // the rectangle that will be drawn final Element rect = doc.createElementNS(svgNS, "rect"); rect.setAttributeNS(null, "x", "0"); rect.setAttributeNS(null, "y", "0"); rect.setAttributeNS(null, "width", imageSize.width + ""); rect.setAttributeNS(null, "height", imageSize.height + ""); elementToAdd = rect; // setting that the rectangle uses the resource String id = resourceElement.getAttribute("id"); if (id == null) { id = ""; } rect.setAttributeNS(null, "style", "fill:url(#" + id + ");"); // getting the cloned resource node Node cur = null; Element clonedResourceElement = null; String id2 = ""; for (cur = defs.getFirstChild(); cur != null; cur = cur.getNextSibling()) { if (cur instanceof Element) { id2 = ((Element) cur).getAttribute("id"); if (id2 != null && id.equals(id2)) { clonedResourceElement = (Element) cur; } } } if (clonedResourceElement != null) { // getting the root element of the initial resource // element Element initialRoot = resourceElement.getOwnerDocument().getDocumentElement(); // getting the width and height of the initial root // element double initialWidth = 0, initialHeight = 0; try { initialWidth = EditorToolkit.getPixelledNumber(initialRoot.getAttributeNS(null, "width")); initialHeight = EditorToolkit.getPixelledNumber(initialRoot.getAttributeNS(null, "height")); } catch (DOMException ex) { ex.printStackTrace(); } if (resourceElement.getNodeName().equals("linearGradient")) { if (resourceElement.getAttributeNS(null, "gradientUnits").equals("userSpaceOnUse")) { double x1 = 0, y1 = 0, x2 = 0, y2 = 0; // normalizing the values for the vector to fit // the rectangle try { x1 = Double.parseDouble(resourceElement.getAttributeNS(null, "x1")); y1 = Double.parseDouble(resourceElement.getAttributeNS(null, "y1")); x2 = Double.parseDouble(resourceElement.getAttributeNS(null, "x2")); y2 = Double.parseDouble(resourceElement.getAttributeNS(null, "y2")); x1 = x1 / initialWidth * imageSize.width; y1 = y1 / initialHeight * imageSize.height; x2 = x2 / initialWidth * imageSize.width; y2 = y2 / initialHeight * imageSize.height; } catch (NumberFormatException | DOMException ex) { ex.printStackTrace(); } clonedResourceElement.setAttributeNS(null, "x1", format.format(x1)); clonedResourceElement.setAttributeNS(null, "y1", format.format(y1)); clonedResourceElement.setAttributeNS(null, "x2", format.format(x2)); clonedResourceElement.setAttributeNS(null, "y2", format.format(y2)); } } else if (resourceElement.getNodeName().equals("radialGradient")) { if (resourceElement.getAttributeNS(null, "gradientUnits").equals("userSpaceOnUse")) { double cx = 0, cy = 0, r = 0, fx = 0, fy = 0; // normalizing the values for the circle to fit // the rectangle try { cx = Double.parseDouble(resourceElement.getAttributeNS(null, "cx")); cy = Double.parseDouble(resourceElement.getAttributeNS(null, "cy")); r = Double.parseDouble(resourceElement.getAttributeNS(null, "r")); fx = Double.parseDouble(resourceElement.getAttributeNS(null, "fx")); fy = Double.parseDouble(resourceElement.getAttributeNS(null, "fy")); cx = cx / initialWidth * imageSize.width; cy = cy / initialHeight * imageSize.height; r = r / (Math.abs( Math.sqrt(Math.pow(initialWidth, 2) + Math.pow(initialHeight, 2)))) * Math.abs( Math.sqrt( Math.pow(imageSize.width, 2) + Math.pow(imageSize.width, 2))); fx = fx / initialWidth * imageSize.width; fy = fy / initialHeight * imageSize.height; } catch (NumberFormatException | DOMException ex) { ex.printStackTrace(); } clonedResourceElement.setAttributeNS(null, "cx", format.format(cx)); clonedResourceElement.setAttributeNS(null, "cy", format.format(cy)); clonedResourceElement.setAttributeNS(null, "r", format.format(r)); clonedResourceElement.setAttributeNS(null, "fx", format.format(fx)); clonedResourceElement.setAttributeNS(null, "fy", format.format(fy)); } } else if (resourceElement.getNodeName().equals("pattern")) { if (resourceElement.getAttributeNS(null, "patternUnits").equals("userSpaceOnUse")) { double x = 0, y = 0, w = 0, h = 0; // normalizing the values for the vector to fit // the rectangle try { String xString = resourceElement.getAttributeNS(null, "x"); if (!xString.equals("")) { x = Double.parseDouble(xString); } String yString = resourceElement.getAttributeNS(null, "y"); if (!yString.equals("")) { y = Double.parseDouble(yString); } String wString = resourceElement.getAttributeNS(null, "w"); if (!wString.equals("")) { w = Double.parseDouble(wString); } String hString = resourceElement.getAttributeNS(null, "h"); if (!hString.equals("")) { h = Double.parseDouble(hString); } x = x / initialWidth * imageSize.width; y = y / initialHeight * imageSize.height; w = w / initialWidth * imageSize.width; h = h / initialHeight * imageSize.height; } catch (NumberFormatException | DOMException ex) { ex.printStackTrace(); } clonedResourceElement.setAttributeNS(null, "x", format.format(x)); clonedResourceElement.setAttributeNS(null, "y", format.format(y)); clonedResourceElement.setAttributeNS(null, "width", format.format(w)); clonedResourceElement.setAttributeNS(null, "height", format.format(h)); } } } } else if (resourceElement.getNodeName().equals("marker")) { // the line that will be drawn final Element line = doc.createElementNS(svgNS, "line"); line.setAttributeNS(null, "x1", (((double) imageSize.width) / 2) + ""); line.setAttributeNS(null, "y1", (((double) imageSize.height) / 2) + ""); line.setAttributeNS(null, "x2", ((double) imageSize.width / 2) + ""); line.setAttributeNS(null, "y2", imageSize.height + ""); elementToAdd = line; // setting that the line uses the resource String id = resourceElement.getAttribute("id"); if (id == null) id = ""; line.setAttributeNS( null, "style", "stroke:none;fill:none;marker-start:url(#" + id + ");"); } root.appendChild(elementToAdd); // adding a rendering listener to the canvas GVTTreeRendererAdapter gVTTreeRendererAdapter = new GVTTreeRendererAdapter() { @Override public void gvtRenderingCompleted(GVTTreeRendererEvent evt) { Image bufferedImage = canvas.getOffScreen(); if (bufferedImage != null) { Graphics g = bufferedImage.getGraphics(); Color borderColor = MetalLookAndFeel.getSeparatorForeground(); g.setColor(borderColor); g.drawRect(0, 0, imageSize.width - 1, imageSize.height - 1); } setImage(fhandle, fresourceId, bufferedImage); // refreshing the panels that have been created when no // image was available for them Image image = null; for (ResourceRepresentation resourceRepresentation : new LinkedList<ResourceRepresentation>(resourceRepresentationList)) { if (resourceRepresentation != null) { resourceRepresentation.refreshRepresentation(); image = resourceRepresentation.getImage(); if (image != null) { resourceRepresentationList.remove(resourceRepresentation); } } } canvas.removeGVTTreeRendererListener(this); canvas.stopProcessing(); canvas.dispose(); } }; canvas.addGVTTreeRendererListener(gVTTreeRendererAdapter); // setting the document for the canvas canvas.setSVGDocument(doc); canvas.setBackground(Color.white); canvas.setBounds(1, 1, imageSize.width, imageSize.height); } } }