/** * Creates a <tt>GraphicsNode</tt> according to the specified parameters. * * @param ctx the bridge context to use * @param e the element that describes the graphics node to build * @return a graphics node that represents the specified element */ public GraphicsNode createGraphicsNode(BridgeContext ctx, Element e) { // 'requiredFeatures', 'requiredExtensions' and 'systemLanguage' if (!SVGUtilities.matchUserAgent(e, ctx.getUserAgent())) { return null; } CompositeGraphicsNode cgn = new CompositeGraphicsNode(); // 'transform' String s = e.getAttributeNS(null, SVG_TRANSFORM_ATTRIBUTE); if (s.length() != 0) { cgn.setTransform(SVGUtilities.convertTransform(e, SVG_TRANSFORM_ATTRIBUTE, s, ctx)); } // 'visibility' cgn.setVisible(CSSUtilities.convertVisibility(e)); // 'text-rendering' and 'color-rendering' RenderingHints hints = null; hints = CSSUtilities.convertColorRendering(e, hints); hints = CSSUtilities.convertTextRendering(e, hints); if (hints != null) { cgn.setRenderingHints(hints); } // first child holds the flow region nodes CompositeGraphicsNode cgn2 = new CompositeGraphicsNode(); cgn.add(cgn2); // second child is the text node FlowTextNode tn = (FlowTextNode) instantiateGraphicsNode(); tn.setLocation(getLocation(ctx, e)); // specify the text painter to use if (ctx.getTextPainter() != null) { tn.setTextPainter(ctx.getTextPainter()); } textNode = tn; cgn.add(tn); associateSVGContext(ctx, e, cgn); // traverse the children to add SVGContext Node child = getFirstChild(e); while (child != null) { if (child.getNodeType() == Node.ELEMENT_NODE) { addContextToChild(ctx, (Element) child); } child = getNextSibling(child); } return cgn; }
/** * Creates a <code>Paint</code> according to the specified parameters. * * @param ctx the bridge context to use * @param paintElement the element that defines a Paint * @param paintedElement the element referencing the paint * @param paintedNode the graphics node on which the Paint will be applied * @param opacity the opacity of the Paint to create */ public Paint createPaint( BridgeContext ctx, Element paintElement, Element paintedElement, GraphicsNode paintedNode, float opacity) { Element clrDef = null; for (Node n = paintElement.getFirstChild(); n != null; n = n.getNextSibling()) { if ((n.getNodeType() != Node.ELEMENT_NODE)) continue; Element ref = (Element) n; if ( // (ref instanceof SVGTests) && SVGUtilities.matchUserAgent(ref, ctx.getUserAgent())) { clrDef = ref; break; } } if (clrDef == null) return Color.black; Bridge bridge = ctx.getBridge(clrDef); if (bridge == null || !(bridge instanceof PaintBridge)) return Color.black; return ((PaintBridge) bridge).createPaint(ctx, clrDef, paintedElement, paintedNode, opacity); }
/** Fills the given AttributedStringBuffer. */ protected void fillAttributedStringBuffer( BridgeContext ctx, Element element, boolean top, Integer bidiLevel, Map initialAttributes, AttributedStringBuffer asb, List lnLocs) { // 'requiredFeatures', 'requiredExtensions', 'systemLanguage' & // 'display="none". if ((!SVGUtilities.matchUserAgent(element, ctx.getUserAgent())) || (!CSSUtilities.convertDisplay(element))) { return; } String s = XMLSupport.getXMLSpace(element); boolean preserve = s.equals(SVG_PRESERVE_VALUE); boolean prevEndsWithSpace; Element nodeElement = element; int elementStartChar = asb.length(); if (top) { endLimit = startLen = asb.length(); } if (preserve) { endLimit = startLen; } Map map = initialAttributes == null ? new HashMap() : new HashMap(initialAttributes); initialAttributes = getAttributeMap(ctx, element, null, bidiLevel, map); Object o = map.get(TextAttribute.BIDI_EMBEDDING); Integer subBidiLevel = bidiLevel; if (o != null) { subBidiLevel = (Integer) o; } int lineBreak = -1; if (lnLocs.size() != 0) { lineBreak = ((Integer) lnLocs.get(lnLocs.size() - 1)).intValue(); } for (Node n = getFirstChild(element); n != null; n = getNextSibling(n)) { if (preserve) { prevEndsWithSpace = false; } else { int len = asb.length(); if (len == startLen) { prevEndsWithSpace = true; } else { prevEndsWithSpace = (asb.getLastChar() == ' '); int idx = lnLocs.size() - 1; if (!prevEndsWithSpace && (idx >= 0)) { Integer i = (Integer) lnLocs.get(idx); if (i.intValue() == len) { prevEndsWithSpace = true; } } } } switch (n.getNodeType()) { case Node.ELEMENT_NODE: // System.out.println("Element: " + n); if (!SVG_NAMESPACE_URI.equals(n.getNamespaceURI())) break; nodeElement = (Element) n; String ln = n.getLocalName(); if (ln.equals(SVG12Constants.SVG_FLOW_LINE_TAG)) { int before = asb.length(); fillAttributedStringBuffer( ctx, nodeElement, false, subBidiLevel, initialAttributes, asb, lnLocs); // System.out.println("Line: " + asb.length() + // " - '" + asb + "'"); lineBreak = asb.length(); lnLocs.add(new Integer(lineBreak)); if (before != lineBreak) { initialAttributes = null; } } else if (ln.equals(SVG12Constants.SVG_FLOW_SPAN_TAG) || ln.equals(SVG12Constants.SVG_ALT_GLYPH_TAG)) { int before = asb.length(); fillAttributedStringBuffer( ctx, nodeElement, false, subBidiLevel, initialAttributes, asb, lnLocs); if (asb.length() != before) { initialAttributes = null; } } else if (ln.equals(SVG_A_TAG)) { if (ctx.isInteractive()) { NodeEventTarget target = (NodeEventTarget) nodeElement; UserAgent ua = ctx.getUserAgent(); SVGAElementBridge.CursorHolder ch; ch = new SVGAElementBridge.CursorHolder(CursorManager.DEFAULT_CURSOR); target.addEventListenerNS( XMLConstants.XML_EVENTS_NAMESPACE_URI, SVG_EVENT_CLICK, new SVGAElementBridge.AnchorListener(ua, ch), false, null); target.addEventListenerNS( XMLConstants.XML_EVENTS_NAMESPACE_URI, SVG_EVENT_MOUSEOVER, new SVGAElementBridge.CursorMouseOverListener(ua, ch), false, null); target.addEventListenerNS( XMLConstants.XML_EVENTS_NAMESPACE_URI, SVG_EVENT_MOUSEOUT, new SVGAElementBridge.CursorMouseOutListener(ua, ch), false, null); } int before = asb.length(); fillAttributedStringBuffer( ctx, nodeElement, false, subBidiLevel, initialAttributes, asb, lnLocs); if (asb.length() != before) { initialAttributes = null; } } else if (ln.equals(SVG_TREF_TAG)) { String uriStr = XLinkSupport.getXLinkHref((Element) n); Element ref = ctx.getReferencedElement((Element) n, uriStr); s = TextUtilities.getElementContent(ref); s = normalizeString(s, preserve, prevEndsWithSpace); if (s.length() != 0) { int trefStart = asb.length(); Map m = new HashMap(); getAttributeMap(ctx, nodeElement, null, bidiLevel, m); asb.append(s, m); int trefEnd = asb.length() - 1; TextPaintInfo tpi; tpi = (TextPaintInfo) elemTPI.get(nodeElement); tpi.startChar = trefStart; tpi.endChar = trefEnd; } } break; case Node.TEXT_NODE: case Node.CDATA_SECTION_NODE: s = n.getNodeValue(); s = normalizeString(s, preserve, prevEndsWithSpace); if (s.length() != 0) { asb.append(s, map); if (preserve) { endLimit = asb.length(); } initialAttributes = null; } } } if (top) { boolean strippedSome = false; while ((endLimit < asb.length()) && (asb.getLastChar() == ' ')) { int idx = lnLocs.size() - 1; int len = asb.length(); if (idx >= 0) { Integer i = (Integer) lnLocs.get(idx); if (i.intValue() >= len) { i = new Integer(len - 1); lnLocs.set(idx, i); idx--; while (idx >= 0) { i = (Integer) lnLocs.get(idx); if (i.intValue() < len - 1) break; lnLocs.remove(idx); idx--; } } } asb.stripLast(); strippedSome = true; } if (strippedSome) { Iterator iter = elemTPI.values().iterator(); while (iter.hasNext()) { TextPaintInfo tpi = (TextPaintInfo) iter.next(); if (tpi.endChar >= asb.length()) { tpi.endChar = asb.length() - 1; if (tpi.startChar > tpi.endChar) tpi.startChar = tpi.endChar; } } } } int elementEndChar = asb.length() - 1; TextPaintInfo tpi = (TextPaintInfo) elemTPI.get(element); tpi.startChar = elementStartChar; tpi.endChar = elementEndChar; }