Пример #1
0
  /**
   * Transcodes the specified Document as an image in the specified output.
   *
   * @param document the document to transcode
   * @param uri the uri of the document or null if any
   * @param output the ouput where to transcode
   * @exception org.apache.batik.transcoder.TranscoderException if an error occurred while
   *     transcoding
   */
  protected void transcode(Document document, String uri, TranscoderOutput output)
      throws TranscoderException {

    if (!(document instanceof SVGOMDocument)) {
      throw new TranscoderException(Messages.formatMessage("notsvg", null));
    }

    BridgeContext ctx = new BridgeContext(userAgent);
    SVGOMDocument svgDoc = (SVGOMDocument) document;

    // build the GVT tree
    GraphicsNode gvtRoot = buildGVT(ctx, svgDoc);

    // get the 'width' and 'height' attributes of the SVG document
    width = (int) (ctx.getDocumentSize().getWidth() + 0.5);
    height = (int) (ctx.getDocumentSize().getHeight() + 0.5);

    SpriteGraphics2D swf2d = new SpriteGraphics2D(width, height);
    gvtRoot.paint(swf2d);
    tags = swf2d.getTags();

    // Override width and height based on the SWF-specific bounds of the sprite contents
    // However we have to correct co-ordinates back to pixels... TODO: Remove all TWIPS references!
    Rect bounds = swf2d.getBounds();
    width = (int) Math.rint((bounds.xMax - bounds.xMin) / 20.0);
    height = (int) Math.rint((bounds.yMax - bounds.yMin) / 20.0);
  }
    /**
     * Retrieves a Batik {@link GraphicsNode} for a given SVG.
     *
     * @param svgLocation an URL that specifies the SVG.
     * @return the corresponding GraphicsNode.
     * @throws IOException
     * @throws URISyntaxException
     */
    private GraphicsNode getGraphicNode(Document doc) {
      // instantiates objects needed for building the node
      UserAgent userAgent = new UserAgentAdapter();
      DocumentLoader loader = new DocumentLoader(userAgent);
      BridgeContext ctx = new BridgeContext(userAgent, loader);
      ctx.setDynamic(true);

      // creates node builder and builds node
      GVTBuilder builder = new GVTBuilder();
      return builder.build(ctx, doc);
    }
  /**
   * 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;
  }
 /** Reads color value from the document. */
 protected Color getColor(Element element, String attributeName) {
   if (getDocument() == null || getDocument() != element.getOwnerDocument()) {
     return null;
   }
   Color color = null;
   // Make sure that CSSEngine is available.
   BridgeContext ctx = transcoder.initCSSEngine();
   try {
     color = SVGUtils.toSWTColor(element, attributeName);
   } finally {
     if (ctx != null) {
       ctx.dispose();
     }
   }
   return color;
 }
  /**
   * Builds using the specified BridgeContext and element, the specified graphics node.
   *
   * @param ctx the bridge context to use
   * @param e the element that describes the graphics node to build
   * @param node the graphics node to build
   */
  public void buildGraphicsNode(BridgeContext ctx, Element e, GraphicsNode node) {
    CompositeGraphicsNode cgn = (CompositeGraphicsNode) node;

    // build flowRegion shapes
    boolean isStatic = !ctx.isDynamic();
    if (isStatic) {
      flowRegionNodes = new HashMap();
    } else {
      regionChangeListener = new RegionChangeListener();
    }
    CompositeGraphicsNode cgn2 = (CompositeGraphicsNode) cgn.get(0);
    GVTBuilder builder = ctx.getGVTBuilder();
    for (Node n = getFirstChild(e); n != null; n = getNextSibling(n)) {
      if (n instanceof SVGOMFlowRegionElement) {
        for (Node m = getFirstChild(n); m != null; m = getNextSibling(m)) {
          if (m.getNodeType() != Node.ELEMENT_NODE) {
            continue;
          }
          GraphicsNode gn = builder.build(ctx, (Element) m);
          if (gn != null) {
            cgn2.add(gn);
            if (isStatic) {
              flowRegionNodes.put(m, gn);
            }
          }
        }

        if (!isStatic) {
          AbstractNode an = (AbstractNode) n;
          XBLEventSupport es = (XBLEventSupport) an.initializeEventSupport();
          es.addImplementationEventListenerNS(
              SVG_NAMESPACE_URI, "shapechange", regionChangeListener, false);
        }
      }
    }

    // build text node
    GraphicsNode tn = (GraphicsNode) cgn.get(1);
    super.buildGraphicsNode(ctx, e, tn);

    // Drop references once static build is completed.
    flowRegionNodes = null;
  }
Пример #6
0
  private static void drawSvgToGraphics2D(Svg svg, Graphics2D g2, Dimension size)
      throws IOException {
    // Copied (and modified) from http://stackoverflow.com/a/12502943

    String parser = XMLResourceDescriptor.getXMLParserClassName();
    SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(parser);
    UserAgent userAgent = new UserAgentAdapter();
    DocumentLoader loader = new DocumentLoader(userAgent);
    BridgeContext ctx = new BridgeContext(userAgent, loader);
    ctx.setDynamicState(BridgeContext.DYNAMIC);
    GVTBuilder builder = new GVTBuilder();

    StringReader svgReader = new StringReader(svg.toString());
    SVGDocument parsedSvgDocument = factory.createSVGDocument(null, svgReader);
    GraphicsNode chartGfx = builder.build(ctx, parsedSvgDocument);
    Dimension actualSize = svg.getSize();
    double scaleWidth = 1.0 * size.width / actualSize.width;
    double scaleHeight = 1.0 * size.height / actualSize.height;
    chartGfx.setTransform(AffineTransform.getScaleInstance(scaleWidth, scaleHeight));

    chartGfx.paint(g2);
  }
  protected void gatherRegionInfo(
      BridgeContext ctx, Element rgn, float verticalAlign, List regions) {

    boolean isStatic = !ctx.isDynamic();
    for (Node n = getFirstChild(rgn); n != null; n = getNextSibling(n)) {

      if (n.getNodeType() != Node.ELEMENT_NODE) {
        continue;
      }

      GraphicsNode gn = isStatic ? (GraphicsNode) flowRegionNodes.get(n) : ctx.getGraphicsNode(n);
      Shape s = gn.getOutline();
      if (s == null) {
        continue;
      }

      AffineTransform at = gn.getTransform();
      if (at != null) {
        s = at.createTransformedShape(s);
      }
      regions.add(new RegionInfo(s, verticalAlign));
    }
  }
Пример #8
0
  /**
   * 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);
  }
Пример #9
0
  public Document(InputStream stream) throws IOException {
    f = new SAXSVGDocumentFactory(XMLResourceDescriptor.getXMLParserClassName());
    doc = f.createSVGDocument(null, stream);

    // Boot the CSS engine
    userAgent = new UserAgentAdapter();
    loader = new DocumentLoader(userAgent);
    ctx = new BridgeContext(userAgent, loader);
    ctx.setDynamicState(BridgeContext.DYNAMIC);
    builder = new GVTBuilder();
    rootGN = builder.build(ctx, doc);

    svgRoot = doc.getRootElement();
    vcss = (ViewCSS) doc.getDocumentElement();
  }
Пример #10
0
 protected GraphicsNode buildGVT(BridgeContext ctx, SVGOMDocument svgDoc)
     throws TranscoderException {
   GVTBuilder builder = new GVTBuilder();
   GraphicsNode gvtRoot;
   try {
     gvtRoot = builder.build(ctx, svgDoc);
     // dispatch an 'onload' event if needed
     if (ctx.isDynamic()) {
       BaseScriptingEnvironment se = new BaseScriptingEnvironment(ctx);
       se.loadScripts();
       se.dispatchSVGLoadEvent();
     }
   } catch (BridgeException ex) {
     throw new TranscoderException(ex);
   }
   return gvtRoot;
 }
Пример #11
0
  /** Printable implementation */
  public int print(Graphics _g, PageFormat pageFormat, int pageIndex) {
    //
    // On the first page, take a snapshot of the vector of
    // TranscodeInputs.
    //
    if (printedInputs == null) {
      printedInputs = (Vector) inputs.clone();
    }

    //
    // If we have already printed each page, return
    //
    if (pageIndex >= printedInputs.size()) {
      curIndex = -1;
      if (theCtx != null) theCtx.dispose();
      userAgent.displayMessage("Done");
      return NO_SUCH_PAGE;
    }

    //
    // Load a new document now if we are printing a new page
    //
    if (curIndex != pageIndex) {
      if (theCtx != null) theCtx.dispose();

      // The following call will invoke this class' transcode
      // method which takes a document as an input. That method
      // builds the GVT root tree.{
      try {
        width = (int) pageFormat.getImageableWidth();
        height = (int) pageFormat.getImageableHeight();
        super.transcode((TranscoderInput) printedInputs.elementAt(pageIndex), null);
        curIndex = pageIndex;
      } catch (TranscoderException e) {
        drawError(_g, e);
        return PAGE_EXISTS;
      }
    }

    // Cast to Graphics2D to access Java 2D features
    Graphics2D g = (Graphics2D) _g;
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g.setRenderingHint(
        RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    g.setRenderingHint(
        RenderingHintsKeyExt.KEY_TRANSCODING, RenderingHintsKeyExt.VALUE_TRANSCODING_PRINTING);

    //
    // Compute transform so that the SVG document fits on one page
    //
    AffineTransform t = g.getTransform();
    Shape clip = g.getClip();

    // System.err.println("X/Y: " + pageFormat.getImageableX() + ", " +
    //                    pageFormat.getImageableY());
    // System.err.println("W/H: " + width + ", " + height);
    // System.err.println("Clip: " + clip.getBounds2D());

    // Offset 0,0 to the start of the imageable Area.
    g.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
    //
    // Append transform to selected area
    //
    g.transform(curTxf);

    //
    // Delegate rendering to painter
    //
    try {
      root.paint(g);
    } catch (Exception e) {
      g.setTransform(t);
      g.setClip(clip);
      drawError(_g, e);
    }

    //
    // Restore transform and clip
    //
    g.setTransform(t);
    g.setClip(clip);

    // g.setPaint(Color.black);
    // g.drawString(uris[pageIndex], 30, 30);

    //
    // Return status indicated that we did paint a page
    //
    return PAGE_EXISTS;
  }
  /** 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;
  }