protected void fillAttributedStringBuffer()

in batik-bridge/src/main/java/org/apache/batik/bridge/SVGTextElementBridge.java [866:1041]


    protected void fillAttributedStringBuffer(BridgeContext ctx,
                                              Element element,
                                              boolean top,
                                              TextPath textPath,
                                              Integer bidiLevel,
                                              Map initialAttributes,
                                              AttributedStringBuffer asb) {
        // '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 = 0;
        }
        if (preserve) {
            endLimit = asb.length();
        }

        Map map = initialAttributes == null
                ? new HashMap()
                : new HashMap(initialAttributes);
        initialAttributes =
            getAttributeMap(ctx, element, textPath, bidiLevel, map);
        Object o = map.get(TextAttribute.BIDI_EMBEDDING);
        Integer subBidiLevel = bidiLevel;
        if (o != null) {
            subBidiLevel = (Integer) o;
        }

        for (Node n = getFirstChild(element);
             n != null;
             n = getNextSibling(n)) {

            if (preserve) {
                prevEndsWithSpace = false;
            } else {
                if (asb.length() == 0) {
                    prevEndsWithSpace = true;
                } else {
                    prevEndsWithSpace = (asb.getLastChar() == ' ');
                }
            }

            switch (n.getNodeType()) {
            case Node.ELEMENT_NODE:
                if (!SVG_NAMESPACE_URI.equals(n.getNamespaceURI()))
                    break;

                nodeElement = (Element)n;

                String ln = n.getLocalName();

                if (ln.equals(SVG_TSPAN_TAG) ||
                    ln.equals(SVG_ALT_GLYPH_TAG)) {
                    int before = asb.count;
                    fillAttributedStringBuffer(ctx,
                                               nodeElement,
                                               false,
                                               textPath,
                                               subBidiLevel,
                                               initialAttributes,
                                               asb);
                    if (asb.count != before) {
                        initialAttributes = null;
                    }
                } else if (ln.equals(SVG_TEXT_PATH_TAG)) {
                    SVGTextPathElementBridge textPathBridge
                        = (SVGTextPathElementBridge)ctx.getBridge(nodeElement);
                    TextPath newTextPath
                        = textPathBridge.createTextPath(ctx, nodeElement);
                    if (newTextPath != null) {
                        int before = asb.count;
                        fillAttributedStringBuffer(ctx,
                                                   nodeElement,
                                                   false,
                                                   newTextPath,
                                                   subBidiLevel,
                                                   initialAttributes,
                                                   asb);
                        if (asb.count != 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 = initialAttributes == null
                                ? new HashMap()
                                : new HashMap(initialAttributes);
                        getAttributeMap
                            (ctx, nodeElement, textPath, bidiLevel, m);
                        asb.append(s, m);
                        int trefEnd = asb.length() - 1;
                        TextPaintInfo tpi;
                        tpi = (TextPaintInfo)elemTPI.get(nodeElement);
                        tpi.startChar = trefStart;
                        tpi.endChar   = trefEnd;
                        initialAttributes = null;
                    }
                } else if (ln.equals(SVG_A_TAG)) {
                    NodeEventTarget target = (NodeEventTarget)nodeElement;
                    UserAgent ua = ctx.getUserAgent();
                    SVGAElementBridge.CursorHolder ch;
                    ch = new SVGAElementBridge.CursorHolder
                        (CursorManager.DEFAULT_CURSOR);
                    EventListener l;
                    l = new SVGAElementBridge.AnchorListener(ua, ch);
                    target.addEventListenerNS
                        (XMLConstants.XML_EVENTS_NAMESPACE_URI,
                         SVG_EVENT_CLICK, l, false, null);
                    ctx.storeEventListenerNS
                        (target, XMLConstants.XML_EVENTS_NAMESPACE_URI,
                         SVG_EVENT_CLICK, l, false);

                    int before = asb.count;
                    fillAttributedStringBuffer(ctx,
                                               nodeElement,
                                               false,
                                               textPath,
                                               subBidiLevel,
                                               initialAttributes,
                                               asb);
                    if (asb.count != before) {
                        initialAttributes = null;
                    }
                }
                break;
            case Node.TEXT_NODE:                     // fall-through is intended
            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() == ' ')) {
                asb.stripLast();
                strippedSome = true;
            }
            if (strippedSome) {
                for (Object o1 : elemTPI.values()) {
                    TextPaintInfo tpi = (TextPaintInfo) o1;
                    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;
    }