[xep-support] Next installment of CoolTools - Quick SVG to PDF Conversion

Kevin Brown kevin at renderx.com
Mon Nov 23 17:16:55 PST 2009


This was a quick project we put together for a CAD company that wanted to do
previews of SVG images in PDF. It's a simple style sheet that takes an SVG
as input and creates an FO as output sized to the dimensions of the SVG.

It works with SVGs that:

a) Have an explicit width and height set with explicit units (as in
width="2cm")
b) Have an explicit width and height set with implicit units (as in
width="600", implicit units in SVG being pixels)
c) Have no explicit width and height -- the page-width and page-height are
obtained from the viewBox attibute width and height (as in viewBox="100 100
500 600" results in page-width="500px" page-height="600px").

There are no real tricks here, just a little recursion to read through the
viewBox if needed and set page-width and page-height.

The input SVG must have the SVG namespace set or this will not work.

As with all CoolTools you can download a zip from the web at:

http://www.xportability.com/CoolTools/SVG2PDF.zip


Kevin Brown
Executive Vice President, Sales & Marketing
RenderX, Inc.
(650) 327-1000 Direct
(650) 328-8008 Fax
(925) 395-1772 Mobile
skype:kbrown01
kevin at renderx.com
sales at renderx.com
http://www.renderx.com 


**** Stylesheet for converting SVG to PDF with XSL FO and RenderX ****


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
  xmlns:svg="http://www.w3.org/2000/svg"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <xsl:template match="svg:svg">
    <fo:root>
      <fo:layout-master-set>
        <fo:simple-page-master master-name="SVGimage">
          <!-- SVG with width and height -->
          <xsl:choose>
            <xsl:when test="@width">
              <xsl:attribute name="page-width">
                <xsl:choose>
                  <!-- No units -->
                  <xsl:when test="number(@width)">
                    <xsl:value-of select="concat(@width,'px')"/>
                  </xsl:when>
                  <xsl:otherwise>
                    <!-- Units are on the width, use them -->
                    <xsl:value-of select="@width"/>
                  </xsl:otherwise>
                </xsl:choose>
              </xsl:attribute>
              <xsl:attribute name="page-height">
                <xsl:choose>
                  <!-- No units -->
                  <xsl:when test="number(@height)">
                    <xsl:value-of select="concat(@height,'px')"/>
                  </xsl:when>
                  <xsl:otherwise>
                    <!-- Units are on the width, use them -->
                    <xsl:value-of select="@height"/>
                  </xsl:otherwise>
                </xsl:choose>
              </xsl:attribute>
            </xsl:when>
            <xsl:otherwise>
              <!-- No width, height use viewport -->
              <xsl:call-template name="splitstring">
                <xsl:with-param name="list" select="@viewBox"/>
              </xsl:call-template>
            </xsl:otherwise>
          </xsl:choose>
          <fo:region-body/>
        </fo:simple-page-master>
      </fo:layout-master-set>
      <fo:page-sequence master-reference="SVGimage">
        <fo:flow flow-name="xsl-region-body">
          <fo:block line-height="0pt">
            <!-- Insert the SVG as instream object as is -->
            <fo:instream-foreign-object>
              <xsl:copy-of select="."/>
            </fo:instream-foreign-object>
          </fo:block>
        </fo:flow>
      </fo:page-sequence>
    </fo:root>
  </xsl:template>

  <xsl:template name="splitstring">
    <xsl:param name="list"/>
    <xsl:param name="loop" select="1"/>
    <xsl:variable name="newlist" select="concat(normalize-space($list), '
')"/>
    <xsl:variable name="first" select="substring-before($newlist, ' ')"/>
    <xsl:variable name="remaining" select="substring-after($newlist, ' ')"/>
    <xsl:if test="$loop = 3">
      <xsl:attribute name="page-width">
        <xsl:value-of select="concat($first,'px')"/>
      </xsl:attribute>
    </xsl:if>
    <xsl:if test="$loop = 4">
      <xsl:attribute name="page-height">
        <xsl:value-of select="concat($first,'px')"/>
      </xsl:attribute>
    </xsl:if>
    <xsl:if test="$remaining">
      <xsl:call-template name="splitstring">
        <xsl:with-param name="list" select="$remaining"/>
        <xsl:with-param name="loop" select="$loop + 1"/>
      </xsl:call-template>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

-------------------
(*) To unsubscribe, send a message with words 'unsubscribe xep-support'
in the body of the message to majordomo at renderx.com from the address
you are subscribed from.
(*) By using the Service, you expressly agree to these Terms of Service http://www.renderx.com/terms-of-service.html



More information about the Xep-support mailing list