protected void fillAttributedStringBuffer()

in batik-bridge/src/main/java/org/apache/batik/bridge/svg12/SVGFlowRootElementBridge.java [624:824]


    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);
        }

        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 == 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(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 >= len) {
                        i = len - 1;
                        lnLocs.set(idx, i);
                        idx--;
                        while (idx >= 0) {
                            i = (Integer)lnLocs.get(idx);
                            if (i < len-1)
                                break;
                            lnLocs.remove(idx);
                            idx--;
                        }
                    }
                }
                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;
    }