Attachment 'svgpathnormalizer.xsl'

Download

   1 <?xml version="1.0" encoding="ISO-8859-1"?>
   2 
   3 <!--
   4     SVG path normalizer
   5 
   6     This converts <rect>, <circle>, <ellipse>, <line>, <polygon>,
   7     and <polyline> elements into equivalent <path> elements.
   8 
   9     Copyright (c) 2006 Awarix, Inc. All rights reserved.
  10 
  11     Redistribution and use in source and binary forms, with or without
  12     modification, are permitted provided that the following conditions are met:
  13 
  14         * Redistributions of source code must retain the above copyright
  15           notice, this list of conditions and the following disclaimer.
  16         * Redistributions in binary form must reproduce the above copyright
  17           notice, this list of conditions and the following disclaimer in the
  18           documentation and/or other materials provided with the distribution.
  19         * Neither the name Awarix nor the names of its contributors may be used
  20           to endorse or promote products derived from this software without
  21           specific prior written permission.
  22 
  23     THIS SOFTWARE IS PROVIDED BY AWARIX AND CONTRIBUTORS ``AS IS'' AND ANY
  24     EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  25     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  26     DISCLAIMED. IN NO EVENT SHALL AWARIX AND CONTRIBUTORS BE LIABLE FOR ANY
  27     DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  28     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  29     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  30     ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  31     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33 
  34     $Id: svgpathnormalizer.xsl 11021 2006-10-20 01:41:34Z archie $
  35 -->
  36 
  37 <xsl:transform version="1.0"
  38   xmlns="http://www.w3.org/2000/svg"
  39   xmlns:svg="http://www.w3.org/2000/svg"
  40   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  41 
  42     <xsl:variable name="revision">$Id: svgpathnormalizer.xsl 11021 2006-10-20 01:41:34Z archie $</xsl:variable>
  43 
  44     <xsl:output method="xml" encoding="UTF-8" indent="yes" media-type="text/svg+xml"/>
  45 
  46     <xsl:template match="/">
  47         <xsl:copy>
  48             <xsl:value-of select="'&#10;'"/>
  49             <xsl:comment> Paths converted via Awarix SVG path normalizer. </xsl:comment>
  50             <xsl:value-of select="'&#10;'"/>
  51             <xsl:comment> Copyright (c) 2006 Awarix, Inc. All rights reserved. </xsl:comment>
  52             <xsl:value-of select="'&#10;'"/>
  53             <xsl:comment><xsl:value-of select="concat(' ', $revision, ' ')"/></xsl:comment>
  54             <xsl:value-of select="'&#10;'"/>
  55             <xsl:value-of select="'&#10;'"/>
  56             <xsl:apply-templates select="@*|node()"/>
  57         </xsl:copy>
  58     </xsl:template>
  59 
  60     <!--
  61         <rect> elements
  62     -->
  63     <xsl:template match="svg:rect">
  64 
  65         <!-- Compute effective x and y per SVG spec -->
  66         <xsl:variable name="x">
  67             <xsl:choose>
  68                 <xsl:when test="not(@x)">0</xsl:when>
  69                 <xsl:otherwise><xsl:value-of select="@x"/></xsl:otherwise>
  70             </xsl:choose>
  71         </xsl:variable>
  72         <xsl:variable name="y">
  73             <xsl:choose>
  74                 <xsl:when test="not(@y)">0</xsl:when>
  75                 <xsl:otherwise><xsl:value-of select="@y"/></xsl:otherwise>
  76             </xsl:choose>
  77         </xsl:variable>
  78 
  79         <!-- Compute effective rx and ry per SVG spec -->
  80         <xsl:variable name="rx0">
  81             <xsl:choose>
  82                 <xsl:when test="not(@rx) and not(@ry)"><xsl:value-of select="'0'"/></xsl:when>
  83                 <xsl:when test="not(@rx) and @ry"><xsl:value-of select="@ry"/></xsl:when>
  84                 <xsl:otherwise><xsl:value-of select="@rx"/></xsl:otherwise>
  85             </xsl:choose>
  86         </xsl:variable>
  87         <xsl:variable name="ry0">
  88             <xsl:choose>
  89                 <xsl:when test="not(@rx) and not(@ry)"><xsl:value-of select="'0'"/></xsl:when>
  90                 <xsl:when test="@rx and not(@ry)"><xsl:value-of select="@rx"/></xsl:when>
  91                 <xsl:otherwise><xsl:value-of select="@ry"/></xsl:otherwise>
  92             </xsl:choose>
  93         </xsl:variable>
  94         <xsl:variable name="rx">
  95             <xsl:choose>
  96                 <xsl:when test="$rx0 &gt; @width div 2"><xsl:value-of select="@width div 2"/></xsl:when>
  97                 <xsl:otherwise><xsl:value-of select="$rx0"/></xsl:otherwise>
  98             </xsl:choose>
  99         </xsl:variable>
 100         <xsl:variable name="ry">
 101             <xsl:choose>
 102                 <xsl:when test="$ry0 &gt; @height div 2"><xsl:value-of select="@height div 2"/></xsl:when>
 103                 <xsl:otherwise><xsl:value-of select="$ry0"/></xsl:otherwise>
 104             </xsl:choose>
 105         </xsl:variable>
 106 
 107         <!-- Emit an equivalent path element -->
 108         <path>
 109             <!-- Copy generic attributes -->
 110             <xsl:apply-templates select="@*[namespace-uri(.)
 111               or (local-name(.) != 'x' and local-name(.) != 'y'
 112                and local-name(.) != 'rx' and local-name(.) != 'ry'
 113                and local-name(.) != 'width' and local-name(.) != 'height')]"/>
 114 
 115             <!-- Emit path description -->
 116             <xsl:attribute name="d">
 117                 <xsl:choose>
 118                     <xsl:when test="$rx = 0 and $ry = 0">       <!-- no rounded corners -->
 119                         <xsl:value-of select="concat(
 120                             'M', $x, ',', $y,
 121                             ' h', @width,
 122                             ' v', @height,
 123                             ' h', -number(@width),
 124                             ' z')"/>
 125                     </xsl:when>
 126                     <xsl:otherwise>
 127                         <xsl:value-of select="concat(
 128                             'M', $x + $rx, ',', $y,
 129                             ' h', @width - 2 * $rx,
 130                             ' A', $rx, ',', $ry, ' 0 0 1 ', $x + @width, ',', $y + $ry,
 131                             ' v', @height - 2 * $ry,
 132                             ' A', $rx, ',', $ry, ' 0 0 1 ', $x + @width - $rx, ',', $y + @height,
 133                             ' h', -number(@width - 2 * $rx),
 134                             ' A', $rx, ',', $ry, ' 0 0 1 ', $x, ',', $y + @height - $ry,
 135                             ' v', -number(@height - 2 * $ry),
 136                             ' A', $rx, ',', $ry, ' 0 0 1 ', $x + $rx, ',', $y)"/>
 137                     </xsl:otherwise>
 138                 </xsl:choose>
 139             </xsl:attribute>
 140         </path>
 141     </xsl:template>
 142 
 143     <!--
 144         <circle> and <ellipse> elements
 145     -->
 146     <xsl:template match="svg:circle | svg:ellipse">
 147 
 148         <!-- Compute effective cx and cy per SVG spec -->
 149         <xsl:variable name="cx">
 150             <xsl:choose>
 151                 <xsl:when test="not(@cx)">0</xsl:when>
 152                 <xsl:otherwise><xsl:value-of select="@cx"/></xsl:otherwise>
 153             </xsl:choose>
 154         </xsl:variable>
 155         <xsl:variable name="cy">
 156             <xsl:choose>
 157                 <xsl:when test="not(@cy)">0</xsl:when>
 158                 <xsl:otherwise><xsl:value-of select="@cy"/></xsl:otherwise>
 159             </xsl:choose>
 160         </xsl:variable>
 161 
 162         <!-- Compute rx and ry -->
 163         <xsl:variable name="rx">
 164             <xsl:choose>
 165                 <xsl:when test="local-name(.) = 'circle'"><xsl:value-of select="@r"/></xsl:when>
 166                 <xsl:otherwise><xsl:value-of select="@rx"/></xsl:otherwise>
 167             </xsl:choose>
 168         </xsl:variable>
 169         <xsl:variable name="ry">
 170             <xsl:choose>
 171                 <xsl:when test="local-name(.) = 'circle'"><xsl:value-of select="@r"/></xsl:when>
 172                 <xsl:otherwise><xsl:value-of select="@ry"/></xsl:otherwise>
 173             </xsl:choose>
 174         </xsl:variable>
 175 
 176         <!-- Emit an equivalent path element -->
 177         <xsl:if test="$rx &gt; 0 and $ry &gt; 0">
 178             <path>
 179                 <!-- Copy generic attributes -->
 180                 <xsl:apply-templates select="@*[namespace-uri(.)
 181                   or (local-name(.) != 'r' 
 182                     and local-name(.) != 'cx' and local-name(.) != 'cy'
 183                     and local-name(.) != 'rx' and local-name(.) != 'ry')]"/>
 184 
 185                 <!-- Emit path description -->
 186                 <xsl:attribute name="d">
 187                     <xsl:value-of select="concat(
 188                         'M', $cx + $rx, ',', $cy, 
 189                         ' A', $rx, ',', $ry, ' 0 1 0 ', $cx - $rx, ',', $cy,
 190                         ' A', $rx, ',', $ry, ' 0 1 0 ', $cx + $rx, ',', $cy)"/>
 191                 </xsl:attribute>
 192             </path>
 193         </xsl:if>
 194     </xsl:template>
 195 
 196     <!--
 197         <line> elements
 198     -->
 199     <xsl:template match="svg:line">
 200 
 201         <!-- Compute effective x1, x2, y1, y2 per SVG spec -->
 202         <xsl:variable name="x1">
 203             <xsl:choose>
 204                 <xsl:when test="not(@x1)">0</xsl:when>
 205                 <xsl:otherwise><xsl:value-of select="@x1"/></xsl:otherwise>
 206             </xsl:choose>
 207         </xsl:variable>
 208         <xsl:variable name="x2">
 209             <xsl:choose>
 210                 <xsl:when test="not(@x2)">0</xsl:when>
 211                 <xsl:otherwise><xsl:value-of select="@x2"/></xsl:otherwise>
 212             </xsl:choose>
 213         </xsl:variable>
 214         <xsl:variable name="y1">
 215             <xsl:choose>
 216                 <xsl:when test="not(@y1)">0</xsl:when>
 217                 <xsl:otherwise><xsl:value-of select="@y1"/></xsl:otherwise>
 218             </xsl:choose>
 219         </xsl:variable>
 220         <xsl:variable name="y2">
 221             <xsl:choose>
 222                 <xsl:when test="not(@y2)">0</xsl:when>
 223                 <xsl:otherwise><xsl:value-of select="@y2"/></xsl:otherwise>
 224             </xsl:choose>
 225         </xsl:variable>
 226 
 227         <!-- Emit an equivalent path element -->
 228         <path>
 229             <!-- Copy generic attributes -->
 230             <xsl:apply-templates select="@*[namespace-uri(.)
 231               or (local-name(.) != 'x1' and local-name(.) != 'y1'
 232                and local-name(.) != 'x2' and local-name(.) != 'y2')]"/>
 233 
 234             <!-- Emit path description -->
 235             <xsl:attribute name="d">
 236                 <xsl:value-of select="concat('M', $x1, ',', $y1, ' L', $x2, ',', $y2)"/>
 237             </xsl:attribute>
 238         </path>
 239     </xsl:template>
 240 
 241     <!--
 242         <polyline> and <polygon> elements
 243     -->
 244     <xsl:template match="svg:polyline | svg:polygon">
 245 
 246         <!-- Emit an equivalent path element -->
 247         <xsl:variable name="points">
 248             <xsl:call-template name="normalizeList">
 249                 <xsl:with-param name="s" select="@points"/>
 250             </xsl:call-template>
 251         </xsl:variable>
 252         <xsl:if test="$points">
 253             <path>
 254                 <!-- Copy generic attributes -->
 255                 <xsl:apply-templates select="@*[namespace-uri(.) or local-name(.) != 'points']"/>
 256 
 257                 <!-- Emit path description -->
 258                 <xsl:attribute name="d">
 259                     <xsl:call-template name="pointsToPath">
 260                         <xsl:with-param name="points" select="$points"/>
 261                     </xsl:call-template>
 262                     <xsl:if test="local-name(.) = 'polygon'"> z</xsl:if>
 263                 </xsl:attribute>
 264             </path>
 265         </xsl:if>
 266     </xsl:template>
 267 
 268     <!-- Emit a normalized point list as a path -->
 269     <xsl:template name="pointsToPath">
 270         <xsl:param name="first" select="true()"/>
 271         <xsl:param name="points"/>
 272         <xsl:if test="$points">
 273             <xsl:choose>
 274                 <xsl:when test="$first">M</xsl:when>
 275                 <xsl:otherwise> L</xsl:otherwise>
 276             </xsl:choose>
 277             <xsl:variable name="x" select="substring-before($points, ' ')"/>
 278             <xsl:variable name="y" select="substring-after($points, ' ')"/>
 279             <xsl:value-of select="concat($x, ',')"/>
 280             <xsl:choose>
 281                 <xsl:when test="contains($y, ' ')">
 282                     <xsl:value-of select="substring-before($y, ' ')"/>
 283                     <xsl:call-template name="pointsToPath">
 284                         <xsl:with-param name="points" select="substring-after($y, ' ')"/>
 285                         <xsl:with-param name="first" select="false()"/>
 286                     </xsl:call-template>
 287                 </xsl:when>
 288                 <xsl:otherwise>
 289                     <xsl:value-of select="$y"/>
 290                 </xsl:otherwise>
 291             </xsl:choose>
 292         </xsl:if>
 293     </xsl:template>
 294 
 295     <!-- Normalize an SVG point list (one space between numbers, no commas) -->
 296     <xsl:template name="normalizeList">
 297         <xsl:param name="s"/>
 298         <xsl:choose>
 299             <xsl:when test="contains($s, ',')">
 300                 <xsl:call-template name="normalizeList">
 301                     <xsl:with-param name="s" select="substring-before($s, ',')"/>
 302                 </xsl:call-template>
 303                 <xsl:value-of select="' '"/>
 304                 <xsl:call-template name="normalizeList">
 305                     <xsl:with-param name="s" select="substring-after($s, ',')"/>
 306                 </xsl:call-template>
 307             </xsl:when>
 308             <xsl:otherwise>
 309                 <xsl:value-of select="normalize-space($s)"/>
 310             </xsl:otherwise>
 311         </xsl:choose>
 312     </xsl:template>
 313 
 314     <!-- Copy everything else unmodified -->
 315     <xsl:template match="@*|node()">
 316         <xsl:copy>
 317             <xsl:apply-templates select="@*|node()"/>
 318         </xsl:copy>
 319     </xsl:template>
 320 
 321 </xsl:transform>

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.

You are not allowed to attach a file to this page.