Add SVG Path parser from enthought. Added reserialization of path.
This commit is contained in:
parent
8ba1dfaf47
commit
5d7e3a075c
5 changed files with 522 additions and 3674 deletions
199
fulltests/gimp.svg
Normal file
199
fulltests/gimp.svg
Normal file
|
|
@ -0,0 +1,199 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://web.resource.org/cc/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="725.35999" height="522.71997" id="svg1306" sodipodi:version="0.32" inkscape:version="0.42" sodipodi:docname="wilber.svg">
|
||||||
|
version="1.0"
|
||||||
|
x="0.0000000"
|
||||||
|
y="0.0000000"
|
||||||
|
<defs id="defs1308">
|
||||||
|
<linearGradient id="linearGradient2998">
|
||||||
|
<stop style="stop-color: rgb(0, 0, 0); stop-opacity: 1;" offset="0.0000000" id="stop3000"/>
|
||||||
|
<stop style="stop-color: rgb(35, 23, 11); stop-opacity: 0;" offset="1.0000000" id="stop3004"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="linearGradient2233">
|
||||||
|
<stop style="stop-color: rgb(0, 0, 0); stop-opacity: 0;" offset="0.0000000" id="stop2235"/>
|
||||||
|
<stop id="stop2251" offset="0.50000000" style="stop-color: rgb(0, 0, 0); stop-opacity: 0;"/>
|
||||||
|
<stop style="stop-color: rgb(0, 0, 0); stop-opacity: 0.649485;" offset="1.0000000" id="stop2237"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="linearGradient11376">
|
||||||
|
<stop id="stop11378" offset="0.0000000" style="stop-color: rgb(255, 255, 255); stop-opacity: 1;"/>
|
||||||
|
<stop style="stop-color: rgb(255, 255, 255); stop-opacity: 0.824742;" offset="0.37500000" id="stop11382"/>
|
||||||
|
<stop id="stop11380" offset="1.0000000" style="stop-color: rgb(145, 145, 145); stop-opacity: 0;"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="linearGradient9839" inkscape:collect="always">
|
||||||
|
<stop id="stop9841" offset="0" style=""/>
|
||||||
|
<stop id="stop9843" offset="1" style="stop-color: rgb(0, 0, 0); stop-opacity: 0;"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="linearGradient9831">
|
||||||
|
<stop style="" offset="0" id="stop9833"/>
|
||||||
|
<stop style="stop-color: rgb(0, 0, 0); stop-opacity: 0;" offset="1" id="stop9835"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient inkscape:collect="always" id="linearGradient9810">
|
||||||
|
<stop style="stop-color: rgb(0, 0, 0); stop-opacity: 1;" offset="0" id="stop9812"/>
|
||||||
|
<stop style="stop-color: rgb(0, 0, 0); stop-opacity: 0;" offset="1" id="stop9814"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient inkscape:collect="always" id="linearGradient8197">
|
||||||
|
<stop style="stop-color: rgb(0, 0, 0); stop-opacity: 1;" offset="0" id="stop8199"/>
|
||||||
|
<stop style="stop-color: rgb(0, 0, 0); stop-opacity: 0;" offset="1" id="stop8201"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="linearGradient8178">
|
||||||
|
<stop style="stop-color: rgb(0, 0, 0); stop-opacity: 1;" offset="0" id="stop8180"/>
|
||||||
|
<stop style="stop-color: rgb(0, 0, 0); stop-opacity: 0;" offset="1" id="stop8182"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient inkscape:collect="always" id="linearGradient7423">
|
||||||
|
<stop style="stop-color: rgb(165, 155, 129); stop-opacity: 1;" offset="0" id="stop7425"/>
|
||||||
|
<stop style="stop-color: rgb(49, 46, 36); stop-opacity: 1;" offset="1" id="stop7427"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="linearGradient7417">
|
||||||
|
<stop id="stop7419" offset="0.0000000" style="stop-color: rgb(165, 155, 129); stop-opacity: 1;"/>
|
||||||
|
<stop id="stop7421" offset="1.0000000" style="stop-color: rgb(14, 11, 5); stop-opacity: 0;"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="linearGradient6677">
|
||||||
|
<stop id="stop6679" offset="0.0000000" style="stop-color: rgb(14, 11, 5); stop-opacity: 0.762887;"/>
|
||||||
|
<stop id="stop6681" offset="1" style="stop-color: rgb(14, 11, 5); stop-opacity: 0;"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="linearGradient6669">
|
||||||
|
<stop style="stop-color: rgb(14, 11, 5); stop-opacity: 1;" offset="0" id="stop6671"/>
|
||||||
|
<stop style="stop-color: rgb(14, 11, 5); stop-opacity: 0;" offset="1" id="stop6673"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="linearGradient6650">
|
||||||
|
<stop id="stop6652" offset="0.0000000" style="stop-color: rgb(0, 0, 0); stop-opacity: 1;"/>
|
||||||
|
<stop style="stop-color: rgb(50, 45, 38); stop-opacity: 1;" offset="0.70999998" id="stop6658"/>
|
||||||
|
<stop id="stop6654" offset="1.0000000" style="stop-color: rgb(192, 192, 192); stop-opacity: 1;"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="linearGradient5910">
|
||||||
|
<stop id="stop5912" offset="0" style="stop-color: rgb(255, 255, 255); stop-opacity: 1;"/>
|
||||||
|
<stop id="stop5914" offset="1.0000000" style="stop-color: rgb(133, 133, 133); stop-opacity: 1;"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="linearGradient5892">
|
||||||
|
<stop id="stop5894" offset="0.0000000" style="stop-color: rgb(255, 255, 255); stop-opacity: 0.670103;"/>
|
||||||
|
<stop id="stop5896" offset="1.0000000" style="stop-color: rgb(255, 255, 255); stop-opacity: 0;"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="linearGradient5837">
|
||||||
|
<stop style="stop-color: rgb(255, 255, 255); stop-opacity: 0.896907;" offset="0.0000000" id="stop5845"/>
|
||||||
|
<stop id="stop5841" offset="1.0000000" style="stop-color: rgb(255, 255, 255); stop-opacity: 0;"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="linearGradient5823">
|
||||||
|
<stop style="stop-color: rgb(255, 255, 255); stop-opacity: 0.608247;" offset="0.0000000" id="stop5825"/>
|
||||||
|
<stop style="stop-color: rgb(255, 255, 255); stop-opacity: 0;" offset="1.0000000" id="stop5827"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="linearGradient5813">
|
||||||
|
<stop style="stop-color: rgb(147, 147, 147); stop-opacity: 1;" offset="0.0000000" id="stop5815"/>
|
||||||
|
<stop style="stop-color: rgb(0, 0, 0); stop-opacity: 1;" offset="1.0000000" id="stop5817"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="linearGradient5786">
|
||||||
|
<stop style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" offset="0" id="stop5788"/>
|
||||||
|
<stop style="stop-color: rgb(76, 76, 76); stop-opacity: 1;" offset="1.0000000" id="stop5790"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient inkscape:collect="always" xlink:href="#linearGradient7423" id="linearGradient8960" gradientUnits="userSpaceOnUse" x1="-98.062012" y1="374.84985" x2="93.040863" y2="678.84985"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient6677" id="radialGradient8962" gradientUnits="userSpaceOnUse" cx="-272.00000" cy="598.00000" fx="-272.00000" fy="598.00000" r="68.000000"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient8197" id="radialGradient8964" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.00197438, 0.809592, -0.957805, 0.00233575, 289.313, 434.308)" cx="-274.16858" cy="297.64462" fx="-274.16858" fy="297.64462" r="296.31400"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient6650" id="radialGradient8966" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.00924176, 0.931116, -1.30281, 0.0129327, 682.203, 651.263)" cx="-95.354408" cy="620.34509" fx="-95.354408" fy="620.34509" r="186.62791"/>
|
||||||
|
<linearGradient inkscape:collect="always" xlink:href="#linearGradient5786" id="linearGradient8968" gradientUnits="userSpaceOnUse" x1="-67.000000" y1="496.25000" x2="-34.000000" y2="743.25000"/>
|
||||||
|
<linearGradient inkscape:collect="always" xlink:href="#linearGradient5910" id="linearGradient8970" gradientUnits="userSpaceOnUse" x1="-230.00000" y1="443.00000" x2="-124.50000" y2="713.50000"/>
|
||||||
|
<linearGradient inkscape:collect="always" xlink:href="#linearGradient5813" id="linearGradient8972" gradientUnits="userSpaceOnUse" x1="-240.06593" y1="673.20160" x2="-360.06592" y2="458.20160"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient5837" id="radialGradient8974" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427022, 0.447848, 0.592128, -0.333859, -512.031, 825.04)" cx="-325.86191" cy="518.95300" fx="-325.86191" fy="518.95300" r="47.137638"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient5823" id="radialGradient8976" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.888693, 0.559957, -0.669168, -0.758766, -292.24, 1082.84)" cx="-327.68088" cy="511.19781" fx="-327.68088" fy="511.19781" r="47.137638"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient5892" id="radialGradient8978" gradientUnits="userSpaceOnUse" gradientTransform="matrix(3.47572e-05, 2.39536, -2.39536, 2.91693e-05, 983.436, 934.389)" cx="-186.88370" cy="489.97964" fx="-186.88370" fy="489.97964" r="10.750000"/>
|
||||||
|
<linearGradient inkscape:collect="always" xlink:href="#linearGradient7423" id="linearGradient9008" gradientUnits="userSpaceOnUse" x1="-98.062012" y1="374.84985" x2="93.040863" y2="678.84985"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient6677" id="radialGradient9010" gradientUnits="userSpaceOnUse" cx="-272.00000" cy="598.00000" fx="-272.00000" fy="598.00000" r="68.000000"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient8197" id="radialGradient9012" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.00197438, 0.809592, -0.957805, 0.00233575, 289.313, 434.308)" cx="-274.16858" cy="297.64462" fx="-274.16858" fy="297.64462" r="296.31400"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient6650" id="radialGradient9014" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.00924176, 0.931116, -1.30281, 0.0129327, 682.203, 651.263)" cx="-95.354408" cy="620.34509" fx="-95.354408" fy="620.34509" r="186.62791"/>
|
||||||
|
<linearGradient inkscape:collect="always" xlink:href="#linearGradient5786" id="linearGradient9016" gradientUnits="userSpaceOnUse" x1="-67.000000" y1="496.25000" x2="-34.000000" y2="743.25000"/>
|
||||||
|
<linearGradient inkscape:collect="always" xlink:href="#linearGradient5910" id="linearGradient9018" gradientUnits="userSpaceOnUse" x1="-230.00000" y1="443.00000" x2="-124.50000" y2="713.50000"/>
|
||||||
|
<linearGradient inkscape:collect="always" xlink:href="#linearGradient5813" id="linearGradient9020" gradientUnits="userSpaceOnUse" x1="-240.06593" y1="673.20160" x2="-360.06592" y2="458.20160"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient5837" id="radialGradient9022" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427022, 0.447848, 0.592128, -0.333859, -512.031, 825.04)" cx="-325.86191" cy="518.95300" fx="-325.86191" fy="518.95300" r="47.137638"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient5823" id="radialGradient9024" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.888693, 0.559957, -0.669168, -0.758766, -292.24, 1082.84)" cx="-327.68088" cy="511.19781" fx="-327.68088" fy="511.19781" r="47.137638"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient5892" id="radialGradient9026" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-9.06847e-15, 2.72986, -2.72987, -6.36834e-06, 1147.33, 996.919)" cx="-186.88370" cy="489.97964" fx="-186.88370" fy="489.97964" r="10.750000"/>
|
||||||
|
<linearGradient inkscape:collect="always" xlink:href="#linearGradient7423" id="linearGradient9056" gradientUnits="userSpaceOnUse" x1="-98.062012" y1="374.84985" x2="93.040863" y2="678.84985"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient6677" id="radialGradient9058" gradientUnits="userSpaceOnUse" cx="-272.00000" cy="598.00000" fx="-272.00000" fy="598.00000" r="68.000000"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient8197" id="radialGradient9060" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.00197438, 0.809592, -0.957805, 0.00233575, 289.313, 434.308)" cx="-274.16858" cy="297.64462" fx="-274.16858" fy="297.64462" r="296.31400"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient6650" id="radialGradient9062" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.00924176, 0.931116, -1.30281, 0.0129327, 682.203, 651.263)" cx="-95.354408" cy="620.34509" fx="-95.354408" fy="620.34509" r="186.62791"/>
|
||||||
|
<linearGradient inkscape:collect="always" xlink:href="#linearGradient5786" id="linearGradient9064" gradientUnits="userSpaceOnUse" x1="-67.000000" y1="496.25000" x2="-34.000000" y2="743.25000"/>
|
||||||
|
<linearGradient inkscape:collect="always" xlink:href="#linearGradient5910" id="linearGradient9066" gradientUnits="userSpaceOnUse" x1="-230.00000" y1="443.00000" x2="-124.50000" y2="713.50000"/>
|
||||||
|
<linearGradient inkscape:collect="always" xlink:href="#linearGradient5813" id="linearGradient9068" gradientUnits="userSpaceOnUse" x1="-240.06593" y1="673.20160" x2="-360.06592" y2="458.20160"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient5837" id="radialGradient9070" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427022, 0.447848, 0.592128, -0.333859, -512.031, 825.04)" cx="-325.86191" cy="518.95300" fx="-325.86191" fy="518.95300" r="47.137638"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient5823" id="radialGradient9072" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.888693, 0.559957, -0.669168, -0.758766, -292.24, 1082.84)" cx="-327.68088" cy="511.19781" fx="-327.68088" fy="511.19781" r="47.137638"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient5892" id="radialGradient9074" gradientUnits="userSpaceOnUse" gradientTransform="matrix(3.47572e-05, 2.39536, -2.39536, 2.91693e-05, 983.436, 934.389)" cx="-186.88370" cy="489.97964" fx="-186.88370" fy="489.97964" r="10.750000"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient9810" id="radialGradient9820" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1, 0, 0, 0.720634, 0, 129.863)" spreadMethod="pad" cx="-29.641619" cy="464.84985" fx="-29.641619" fy="464.84985" r="362.68250"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient9810" id="radialGradient9822" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1, 0, 0, 0.720634, 0, 129.863)" spreadMethod="pad" cx="-29.641619" cy="464.84985" fx="-29.641619" fy="464.84985" r="362.68250"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient9839" id="radialGradient9827" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1, -4.62567e-23, -3.33341e-23, 0.720635, 0, 129.863)" spreadMethod="pad" cx="-45.723396" cy="608.31067" fx="-45.723396" fy="608.31067" r="362.68250"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient9810" id="radialGradient9829" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1, 0, 0, 0.720634, 0, 129.863)" spreadMethod="pad" cx="-29.641619" cy="464.84985" fx="-29.641619" fy="464.84985" r="362.68250"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient9831" id="radialGradient9837" cx="-45.723396" cy="593.22729" fx="-45.723396" fy="593.22729" r="324.55145" gradientTransform="matrix(1, 9.82106e-24, 7.90891e-24, 0.805301, 0, 90.5061)" gradientUnits="userSpaceOnUse"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient5823" id="radialGradient9847" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.948865, 0.611382, -0.714476, -0.828449, 104.541, 929.749)" cx="-327.68088" cy="511.19781" fx="-327.68088" fy="511.19781" r="47.137638"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient5837" id="radialGradient9851" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.427022, 0.447848, 0.592128, -0.333859, -119.709, 621.55)" cx="-325.86191" cy="518.95300" fx="-325.86191" fy="518.95300" r="47.137638"/>
|
||||||
|
<linearGradient inkscape:collect="always" xlink:href="#linearGradient5813" id="linearGradient9855" gradientUnits="userSpaceOnUse" x1="-240.06593" y1="673.20160" x2="-360.06592" y2="458.20160" gradientTransform="translate(392.322, -203.49)"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient6650" id="radialGradient9861" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.00924176, 0.931116, -1.30281, 0.0129327, 1074.53, 447.773)" cx="-95.354408" cy="620.34509" fx="-95.354408" fy="620.34509" r="186.62791"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient8197" id="radialGradient9864" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.00197438, 0.809592, -0.957805, 0.00233575, 681.634, 230.818)" cx="-274.16858" cy="297.64462" fx="-274.16858" fy="297.64462" r="296.31400"/>
|
||||||
|
<linearGradient inkscape:collect="always" xlink:href="#linearGradient7423" id="linearGradient9868" gradientUnits="userSpaceOnUse" x1="-98.062012" y1="374.84985" x2="93.040863" y2="678.84985" gradientTransform="translate(392.322, -203.49)"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient5823" id="radialGradient9914" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.610764, -0.550565, 0.623849, -0.813397, -456.371, 538.401)" cx="-326.66031" cy="500.71341" fx="-305.19946" fy="498.48129" r="47.137638"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient11376" id="radialGradient11374" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.594458, -0.468206, 0.513924, -0.795006, -400.277, 552.346)" cx="-326.66016" cy="500.71310" fx="-306.67374" fy="505.40457" r="47.137638"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient2233" id="radialGradient2249" cx="102.23784" cy="397.25247" fx="102.23784" fy="397.25247" r="35.011723" gradientTransform="matrix(2.0637, 1.33226, -2.2977, 3.5592, 792.325, -1159.98)" gradientUnits="userSpaceOnUse"/>
|
||||||
|
<radialGradient inkscape:collect="always" xlink:href="#linearGradient2998" id="radialGradient2996" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-0.0110724, 0.456938, -0.549581, -0.0133172, 550.239, 443.222)" cx="9.5432158" cy="756.36554" fx="9.5432158" fy="756.36554" r="186.62791"/>
|
||||||
|
<linearGradient inkscape:collect="always" xlink:href="#linearGradient7423" id="linearGradient1529" gradientUnits="userSpaceOnUse" gradientTransform="translate(392.322, -198.434)" x1="-98.062012" y1="374.84985" x2="93.040863" y2="678.84985"/>
|
||||||
|
<linearGradient inkscape:collect="always" xlink:href="#linearGradient7423" id="linearGradient1532" gradientUnits="userSpaceOnUse" gradientTransform="translate(392.322, -203.49)" x1="-98.062012" y1="374.84985" x2="93.040863" y2="678.84985"/>
|
||||||
|
</defs>
|
||||||
|
<sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="0.98905729" inkscape:cx="329.43391" inkscape:cy="148.58953" inkscape:current-layer="g1902" showgrid="true" inkscape:document-units="px" inkscape:grid-bbox="true" inkscape:window-width="1027" inkscape:window-height="693" inkscape:window-x="0" inkscape:window-y="25" showguides="true" inkscape:guide-bbox="true">
|
||||||
|
<sodipodi:guide orientation="horizontal" position="610.00000" id="guide11974"/>
|
||||||
|
<sodipodi:guide orientation="horizontal" position="-136.00000" id="guide11976"/>
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<metadata id="metadata1311">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||||
|
<cc:license rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/"/>
|
||||||
|
<dc:title>Wilber, the GIMP</dc:title>
|
||||||
|
<dc:date>10/23/05</dc:date>
|
||||||
|
<dc:creator>
|
||||||
|
<cc:Agent>
|
||||||
|
<dc:title>worthawholebean</dc:title>
|
||||||
|
</cc:Agent>
|
||||||
|
</dc:creator>
|
||||||
|
<dc:publisher>
|
||||||
|
<cc:Agent>
|
||||||
|
<dc:title>Inkscape</dc:title>
|
||||||
|
</cc:Agent>
|
||||||
|
</dc:publisher>
|
||||||
|
<dc:description>This is an SVG version of the original Wilber.</dc:description>
|
||||||
|
<dc:contributor>
|
||||||
|
<cc:Agent>
|
||||||
|
<dc:title>worthawholebean</dc:title>
|
||||||
|
</cc:Agent>
|
||||||
|
</dc:contributor>
|
||||||
|
</cc:Work>
|
||||||
|
<cc:License rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
|
||||||
|
<cc:permits rdf:resource="http://web.resource.org/cc/Reproduction"/>
|
||||||
|
<cc:permits rdf:resource="http://web.resource.org/cc/Distribution"/>
|
||||||
|
<cc:requires rdf:resource="http://web.resource.org/cc/Notice"/>
|
||||||
|
<cc:requires rdf:resource="http://web.resource.org/cc/Attribution"/>
|
||||||
|
<cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/>
|
||||||
|
<cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike"/>
|
||||||
|
</cc:License>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g inkscape:label="bg" id="layer4" inkscape:groupmode="layer"/>
|
||||||
|
<g inkscape:label="shdw" id="layer5" inkscape:groupmode="layer"/>
|
||||||
|
<g inkscape:groupmode="layer" inkscape:label="bot" id="layer1"/>
|
||||||
|
<g inkscape:label="mid" id="layer3" inkscape:groupmode="layer"/>
|
||||||
|
<g inkscape:label="top" id="layer2" inkscape:groupmode="layer">
|
||||||
|
<g id="g1902">
|
||||||
|
<g id="g1603">
|
||||||
|
<path style="fill: url(#linearGradient1532) rgb(0, 0, 0); fill-opacity: 1; fill-rule: evenodd; stroke: none; stroke-width: 1; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; stroke-dasharray: none; stroke-opacity: 1;" d="M 385.88362,201.47812 C 505.43501,223.44223 659.42238,159.82405 714.32160,-0.0015300000 C 767.48553,202.26527 611.38362,310.07599 611.38362,310.07599 C 545.68594,542.88219 229.08516,573.63413 74.259580,449.63414 L 121.19756,292.63413 C 150.07353,251.85894 167.02143,217.02859 208.32160,207.57212 C 208.32160,207.57212 168.65990,161.32509 121.69357,12.440270 C 211.69357,149.44027 323.87473,190.08578 385.88362,201.47812 z " id="path1932" sodipodi:nodetypes="cccccccs"/>
|
||||||
|
<path transform="matrix(1.07116, 0, 0, 1, 412.518, -199.49)" sodipodi:type="arc" style="fill: url(#radialGradient9010) rgb(0, 0, 0); fill-opacity: 1; stroke: none; stroke-width: 30; stroke-miterlimit: 4; stroke-dasharray: none; stroke-opacity: 1;" id="path1934" sodipodi:cx="-272.00000" sodipodi:cy="598.00000" sodipodi:rx="68.000000" sodipodi:ry="68.000000" d="M -204.00000 598.00000 A 68.000000 68.000000 0 1 1 -340.00000,598.00000 A 68.000000 68.000000 0 1 1 -204.00000 598.00000 z"/>
|
||||||
|
<path sodipodi:nodetypes="ccscs" id="path1936" d="M 385.88362,201.47812 C 505.43501,223.44223 659.42238,164.82405 714.32160,-0.0015300000 C 649.90356,227.13187 497.48814,312.46353 371.30643,277.40123 C 245.12472,242.33893 157.17674,250.88268 121.69357,12.440270 C 211.69357,149.44027 323.87473,190.08578 385.88362,201.47812 z " style="fill: url(#radialGradient9864) rgb(0, 0, 0); fill-opacity: 1; fill-rule: evenodd; stroke: none; stroke-width: 1; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; stroke-dasharray: none; stroke-opacity: 1;"/>
|
||||||
|
<path style="fill: url(#radialGradient9861) rgb(0, 0, 0); fill-opacity: 1; fill-rule: evenodd; stroke: none; stroke-width: 1px; stroke-linecap: butt; stroke-linejoin: miter; stroke-opacity: 1;" d="M 446.32160,358.51010 C 523.00811,548.75066 221.04253,542.84343 87.321600,459.51010 C 87.321600,459.51010 339.73245,511.61088 446.32160,358.51010 z " id="path1938" sodipodi:nodetypes="ccc"/>
|
||||||
|
<path sodipodi:type="arc" style="fill: url(#linearGradient9016) rgb(0, 0, 0); fill-opacity: 1; stroke: none; stroke-width: 1; stroke-miterlimit: 4; stroke-dasharray: none; stroke-opacity: 1;" id="path1940" sodipodi:cx="-51.750000" sodipodi:cy="499.75000" sodipodi:rx="83.750000" sodipodi:ry="83.750000" d="M 32.000000 499.75000 A 83.750000 83.750000 0 1 1 -135.50000,499.75000 A 83.750000 83.750000 0 1 1 32.000000 499.75000 z" transform="translate(392.822, -201.99)"/>
|
||||||
|
<path sodipodi:type="arc" style="fill: url(#linearGradient9018) rgb(0, 0, 0); fill-opacity: 1; stroke: none; stroke-width: 30; stroke-miterlimit: 4; stroke-dasharray: none; stroke-opacity: 1;" id="path1942" sodipodi:cx="-188.00000" sodipodi:cy="481.00000" sodipodi:rx="59.000000" sodipodi:ry="59.000000" d="M -129.00000 481.00000 A 59.000000 59.000000 0 1 1 -247.00000,481.00000 A 59.000000 59.000000 0 1 1 -129.00000 481.00000 z" transform="translate(391.322, -202.99)"/>
|
||||||
|
<path sodipodi:type="arc" style="fill: rgb(0, 0, 0); fill-opacity: 1; stroke: none; stroke-width: 1; stroke-miterlimit: 4; stroke-dasharray: none; stroke-opacity: 1;" id="path1944" sodipodi:cx="-38.750000" sodipodi:cy="520.25000" sodipodi:rx="35.750000" sodipodi:ry="35.750000" d="M -3.0000000 520.25000 A 35.750000 35.750000 0 1 1 -74.500000,520.25000 A 35.750000 35.750000 0 1 1 -3.0000000 520.25000 z" transform="translate(391.822, -204.99)"/>
|
||||||
|
<path style="fill: url(#linearGradient9855) rgb(0, 0, 0); fill-opacity: 1; fill-rule: evenodd; stroke: none; stroke-width: 1px; stroke-linecap: butt; stroke-linejoin: miter; stroke-opacity: 1;" d="M 136.32160,315.51010 C 73.262530,196.41910 -36.953840,284.17835 12.321600,387.51010 C 74.880900,518.69842 195.61094,427.48172 136.32160,315.51010 z " id="path1946" sodipodi:nodetypes="css"/>
|
||||||
|
<path sodipodi:type="arc" style="fill: rgb(0, 0, 0); fill-opacity: 1; stroke: none; stroke-width: 20; stroke-miterlimit: 4; stroke-dasharray: none; stroke-opacity: 1;" id="path1948" sodipodi:cx="-178.50000" sodipodi:cy="500.50000" sodipodi:rx="31.000000" sodipodi:ry="31.500000" d="M -147.50000 500.50000 A 31.000000 31.500000 0 1 1 -209.50000,500.50000 A 31.000000 31.500000 0 1 1 -147.50000 500.50000 z" transform="matrix(1.01613, 0, 0, 1.01587, 394.701, -211.934)"/>
|
||||||
|
<path sodipodi:type="arc" style="fill: rgb(255, 255, 255); fill-opacity: 1; stroke: rgb(255, 255, 255); stroke-width: 1; stroke-miterlimit: 4; stroke-dasharray: none; stroke-opacity: 1;" id="path1950" sodipodi:cx="-49.000000" sodipodi:cy="507.50000" sodipodi:rx="14.000000" sodipodi:ry="13.000000" d="M -35.000000 507.50000 A 14.000000 13.000000 0 1 1 -63.000000,507.50000 A 14.000000 13.000000 0 1 1 -35.000000 507.50000 z" transform="matrix(0.930968, 0, 0, 1, 388.914, -203.472)"/>
|
||||||
|
<path transform="translate(392.322, -203.49)" sodipodi:type="arc" style="fill: rgb(255, 255, 255); fill-opacity: 1; stroke: url(#radialGradient9026) rgb(0, 0, 0); stroke-width: 30; stroke-miterlimit: 4; stroke-dasharray: none; stroke-opacity: 1;" id="path1952" sodipodi:cx="-190.25000" sodipodi:cy="486.75000" sodipodi:rx="10.750000" sodipodi:ry="10.750000" d="M -179.50000 486.75000 A 10.750000 10.750000 0 1 1 -201.00000,486.75000 A 10.750000 10.750000 0 1 1 -179.50000 486.75000 z"/>
|
||||||
|
<path sodipodi:nodetypes="css" id="path1954" d="M 31.790805,261.49220 C -36.348714,317.47030 41.169697,374.80237 69.222032,351.31596 C 143.44775,289.17159 52.989655,244.07690 31.790805,261.49220 z " style="fill: url(#radialGradient11374) rgb(0, 0, 0); fill-opacity: 1; fill-rule: evenodd; stroke: none; stroke-width: 1px; stroke-linecap: butt; stroke-linejoin: miter; stroke-opacity: 1;"/>
|
||||||
|
<path sodipodi:nodetypes="cccc" id="path1494" d="M 129.40631,338.29051 C 129.40631,338.29051 124.81946,381.73155 82.534732,451.71997 C 140.70578,456.66260 165.49568,388.44502 146.00000,338.29051 L 129.40631,338.29051 z " style="fill: url(#radialGradient2249) rgb(0, 0, 0); fill-opacity: 1; fill-rule: evenodd; stroke: none; stroke-width: 1px; stroke-linecap: butt; stroke-linejoin: miter; stroke-opacity: 1;"/>
|
||||||
|
<path sodipodi:nodetypes="ccss" id="path2268" d="M 345.72439,511.60031 C 263.10369,523.48690 154.18206,501.17676 87.321600,459.51010 C 87.321600,459.51010 150.42431,472.53530 226.85067,466.42289 C 303.27702,460.31049 428.34509,499.71371 345.72439,511.60031 z " style="fill: url(#radialGradient2996) rgb(0, 0, 0); fill-opacity: 1; fill-rule: evenodd; stroke: none; stroke-width: 1px; stroke-linecap: butt; stroke-linejoin: miter; stroke-opacity: 1;"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g inkscape:groupmode="layer" id="g1443" inkscape:label="bg"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 27 KiB |
3662
fulltests/header.svg
3662
fulltests/header.svg
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 208 KiB |
48
scour.py
48
scour.py
|
|
@ -52,16 +52,6 @@
|
||||||
# - Reduce #RRGGBB format to #RGB format when possible
|
# - Reduce #RRGGBB format to #RGB format when possible
|
||||||
# https://bugs.edge.launchpad.net/ubuntu/+source/human-icon-theme/+bug/361667/
|
# https://bugs.edge.launchpad.net/ubuntu/+source/human-icon-theme/+bug/361667/
|
||||||
|
|
||||||
# Some notes to not forget:
|
|
||||||
# - removing empty nested groups also potentially loses some semantic information
|
|
||||||
# (i.e. the following button:
|
|
||||||
# <g>
|
|
||||||
# <rect .../>
|
|
||||||
# <text .../>
|
|
||||||
# </g>
|
|
||||||
# will be flattened)
|
|
||||||
|
|
||||||
|
|
||||||
# necessary to get true division
|
# necessary to get true division
|
||||||
from __future__ import division
|
from __future__ import division
|
||||||
|
|
||||||
|
|
@ -74,6 +64,8 @@ import math
|
||||||
import base64
|
import base64
|
||||||
import os.path
|
import os.path
|
||||||
import urllib
|
import urllib
|
||||||
|
import svg_regex
|
||||||
|
from svg_regex import svg_parser
|
||||||
|
|
||||||
APP = 'scour'
|
APP = 'scour'
|
||||||
VER = '0.10'
|
VER = '0.10'
|
||||||
|
|
@ -610,9 +602,41 @@ def repairStyle(node):
|
||||||
|
|
||||||
return num
|
return num
|
||||||
|
|
||||||
# does nothing at the moment but waste time
|
# This method will do the following:
|
||||||
|
# - parse the path data and reserialize
|
||||||
def cleanPath(element) :
|
def cleanPath(element) :
|
||||||
path = element.getAttribute('d')
|
path = svg_parser.parse(element.getAttribute('d'))
|
||||||
|
for (cmd,dataset) in path:
|
||||||
|
if not dataset == None:
|
||||||
|
for data in dataset:
|
||||||
|
pass
|
||||||
|
element.setAttribute('d', serializePath(path))
|
||||||
|
|
||||||
|
# - reserialize the path data with some cleanups:
|
||||||
|
# - removes scientific notation (exponents)
|
||||||
|
# - removes trailing zeros after the decimal
|
||||||
|
# - removes extraneous whitespace
|
||||||
|
# - adds commas between all values in a subcommand
|
||||||
|
def serializePath(pathObj):
|
||||||
|
pathStr = ""
|
||||||
|
# print pathObj
|
||||||
|
for (cmd,dataset) in pathObj:
|
||||||
|
pathStr += cmd
|
||||||
|
if not dataset == None:
|
||||||
|
for data in dataset:
|
||||||
|
try:
|
||||||
|
c = 0
|
||||||
|
for coord in data:
|
||||||
|
# if coord can be an integer without loss of precision, go for it
|
||||||
|
if int(coord) == coord: pathStr += str(int(coord))
|
||||||
|
else: pathStr += str(coord)
|
||||||
|
if c < len(data)-1:
|
||||||
|
pathStr += ','
|
||||||
|
c += 1
|
||||||
|
except TypeError:
|
||||||
|
pathStr += str(data)
|
||||||
|
pathStr += ' '
|
||||||
|
return pathStr
|
||||||
|
|
||||||
# converts raster references to inline images
|
# converts raster references to inline images
|
||||||
# NOTE: there are size limits to base64-encoding handling in browsers
|
# NOTE: there are size limits to base64-encoding handling in browsers
|
||||||
|
|
|
||||||
280
svg_regex.py
Normal file
280
svg_regex.py
Normal file
|
|
@ -0,0 +1,280 @@
|
||||||
|
# This software is OSI Certified Open Source Software.
|
||||||
|
# OSI Certified is a certification mark of the Open Source Initiative.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2006, Enthought, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright notice, this
|
||||||
|
# list of conditions and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
# this list of conditions and the following disclaimer in the documentation
|
||||||
|
# and/or other materials provided with the distribution.
|
||||||
|
# * Neither the name of Enthought, Inc. nor the names of its contributors may
|
||||||
|
# be used to endorse or promote products derived from this software without
|
||||||
|
# specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
""" Small hand-written recursive descent parser for SVG <path> data.
|
||||||
|
|
||||||
|
|
||||||
|
In [1]: from svg_regex import svg_parser
|
||||||
|
|
||||||
|
In [3]: svg_parser.parse('M 10,20 30,40V50 60 70')
|
||||||
|
Out[3]: [('M', [(10.0, 20.0), (30.0, 40.0)]), ('V', [50.0, 60.0, 70.0])]
|
||||||
|
|
||||||
|
In [4]: svg_parser.parse('M 0.6051.5') # An edge case
|
||||||
|
Out[4]: [('M', [(0.60509999999999997, 0.5)])]
|
||||||
|
|
||||||
|
In [5]: svg_parser.parse('M 100-200') # Another edge case
|
||||||
|
Out[5]: [('M', [(100.0, -200.0)])]
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
# Sentinel.
|
||||||
|
class _EOF(object):
|
||||||
|
def __repr__(self):
|
||||||
|
return 'EOF'
|
||||||
|
EOF = _EOF()
|
||||||
|
|
||||||
|
lexicon = [
|
||||||
|
('float', r'[-\+]?(?:(?:[0-9]*\.[0-9]+)|(?:[0-9]+\.))(?:[Ee][-\+]?[0-9]+)?'),
|
||||||
|
('int', r'[-\+]?[0-9]+'),
|
||||||
|
('command', r'[AaCcHhLlMmQqSsTtVvZz]'),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class Lexer(object):
|
||||||
|
""" Break SVG path data into tokens.
|
||||||
|
|
||||||
|
The SVG spec requires that tokens are greedy. This lexer relies on Python's
|
||||||
|
regexes defaulting to greediness.
|
||||||
|
|
||||||
|
This style of implementation was inspired by this article:
|
||||||
|
|
||||||
|
http://www.gooli.org/blog/a-simple-lexer-in-python/
|
||||||
|
"""
|
||||||
|
def __init__(self, lexicon):
|
||||||
|
self.lexicon = lexicon
|
||||||
|
parts = []
|
||||||
|
for name, regex in lexicon:
|
||||||
|
parts.append('(?P<%s>%s)' % (name, regex))
|
||||||
|
self.regex_string = '|'.join(parts)
|
||||||
|
self.regex = re.compile(self.regex_string)
|
||||||
|
|
||||||
|
def lex(self, text):
|
||||||
|
""" Yield (token_type, str_data) tokens.
|
||||||
|
|
||||||
|
The last token will be (EOF, None) where EOF is the singleton object
|
||||||
|
defined in this module.
|
||||||
|
"""
|
||||||
|
for match in self.regex.finditer(text):
|
||||||
|
for name, _ in self.lexicon:
|
||||||
|
m = match.group(name)
|
||||||
|
if m is not None:
|
||||||
|
yield (name, m)
|
||||||
|
break
|
||||||
|
yield (EOF, None)
|
||||||
|
|
||||||
|
svg_lexer = Lexer(lexicon)
|
||||||
|
|
||||||
|
|
||||||
|
class SVGPathParser(object):
|
||||||
|
""" Parse SVG <path> data into a list of commands.
|
||||||
|
|
||||||
|
Each distinct command will take the form of a tuple (command, data). The
|
||||||
|
`command` is just the character string that starts the command group in the
|
||||||
|
<path> data, so 'M' for absolute moveto, 'm' for relative moveto, 'Z' for
|
||||||
|
closepath, etc. The kind of data it carries with it depends on the command.
|
||||||
|
For 'Z' (closepath), it's just None. The others are lists of individual
|
||||||
|
argument groups. Multiple elements in these lists usually mean to repeat the
|
||||||
|
command. The notable exception is 'M' (moveto) where only the first element
|
||||||
|
is truly a moveto. The remainder are implicit linetos.
|
||||||
|
|
||||||
|
See the SVG documentation for the interpretation of the individual elements
|
||||||
|
for each command.
|
||||||
|
|
||||||
|
The main method is `parse(text)`. It can only consume actual strings, not
|
||||||
|
filelike objects or iterators.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, lexer=svg_lexer):
|
||||||
|
self.lexer = lexer
|
||||||
|
|
||||||
|
self.command_dispatch = {
|
||||||
|
'Z': self.rule_closepath,
|
||||||
|
'z': self.rule_closepath,
|
||||||
|
'M': self.rule_moveto_or_lineto,
|
||||||
|
'm': self.rule_moveto_or_lineto,
|
||||||
|
'L': self.rule_moveto_or_lineto,
|
||||||
|
'l': self.rule_moveto_or_lineto,
|
||||||
|
'H': self.rule_orthogonal_lineto,
|
||||||
|
'h': self.rule_orthogonal_lineto,
|
||||||
|
'V': self.rule_orthogonal_lineto,
|
||||||
|
'v': self.rule_orthogonal_lineto,
|
||||||
|
'C': self.rule_curveto3,
|
||||||
|
'c': self.rule_curveto3,
|
||||||
|
'S': self.rule_curveto2,
|
||||||
|
's': self.rule_curveto2,
|
||||||
|
'Q': self.rule_curveto2,
|
||||||
|
'q': self.rule_curveto2,
|
||||||
|
'T': self.rule_curveto1,
|
||||||
|
't': self.rule_curveto1,
|
||||||
|
'A': self.rule_elliptical_arc,
|
||||||
|
'a': self.rule_elliptical_arc,
|
||||||
|
}
|
||||||
|
|
||||||
|
self.number_tokens = set(['int', 'float'])
|
||||||
|
|
||||||
|
def parse(self, text):
|
||||||
|
""" Parse a string of SVG <path> data.
|
||||||
|
"""
|
||||||
|
next = self.lexer.lex(text).next
|
||||||
|
token = next()
|
||||||
|
return self.rule_svg_path(next, token)
|
||||||
|
|
||||||
|
def rule_svg_path(self, next, token):
|
||||||
|
commands = []
|
||||||
|
while token[0] is not EOF:
|
||||||
|
if token[0] != 'command':
|
||||||
|
raise SyntaxError("expecting a command; got %r" % (token,))
|
||||||
|
rule = self.command_dispatch[token[1]]
|
||||||
|
command_group, token = rule(next, token)
|
||||||
|
commands.append(command_group)
|
||||||
|
return commands
|
||||||
|
|
||||||
|
def rule_closepath(self, next, token):
|
||||||
|
command = token[1]
|
||||||
|
token = next()
|
||||||
|
return (command, None), token
|
||||||
|
|
||||||
|
def rule_moveto_or_lineto(self, next, token):
|
||||||
|
command = token[1]
|
||||||
|
token = next()
|
||||||
|
coordinates = []
|
||||||
|
while token[0] in self.number_tokens:
|
||||||
|
pair, token = self.rule_coordinate_pair(next, token)
|
||||||
|
coordinates.append(pair)
|
||||||
|
return (command, coordinates), token
|
||||||
|
|
||||||
|
def rule_orthogonal_lineto(self, next, token):
|
||||||
|
command = token[1]
|
||||||
|
token = next()
|
||||||
|
coordinates = []
|
||||||
|
while token[0] in self.number_tokens:
|
||||||
|
coord, token = self.rule_coordinate(next, token)
|
||||||
|
coordinates.append(coord)
|
||||||
|
return (command, coordinates), token
|
||||||
|
|
||||||
|
def rule_curveto3(self, next, token):
|
||||||
|
command = token[1]
|
||||||
|
token = next()
|
||||||
|
coordinates = []
|
||||||
|
while token[0] in self.number_tokens:
|
||||||
|
pair1, token = self.rule_coordinate_pair(next, token)
|
||||||
|
pair2, token = self.rule_coordinate_pair(next, token)
|
||||||
|
pair3, token = self.rule_coordinate_pair(next, token)
|
||||||
|
coordinates.append((pair1, pair2, pair3))
|
||||||
|
return (command, coordinates), token
|
||||||
|
|
||||||
|
def rule_curveto2(self, next, token):
|
||||||
|
command = token[1]
|
||||||
|
token = next()
|
||||||
|
coordinates = []
|
||||||
|
while token[0] in self.number_tokens:
|
||||||
|
pair1, token = self.rule_coordinate_pair(next, token)
|
||||||
|
pair2, token = self.rule_coordinate_pair(next, token)
|
||||||
|
coordinates.append((pair1, pair2))
|
||||||
|
return (command, coordinates), token
|
||||||
|
|
||||||
|
def rule_curveto1(self, next, token):
|
||||||
|
command = token[1]
|
||||||
|
token = next()
|
||||||
|
coordinates = []
|
||||||
|
while token[0] in self.number_tokens:
|
||||||
|
pair1, token = self.rule_coordinate_pair(next, token)
|
||||||
|
coordinates.append(pair1)
|
||||||
|
return (command, coordinates), token
|
||||||
|
|
||||||
|
def rule_elliptical_arc(self, next, token):
|
||||||
|
command = token[1]
|
||||||
|
token = next()
|
||||||
|
arguments = []
|
||||||
|
while token[0] in self.number_tokens:
|
||||||
|
rx = float(token[1])
|
||||||
|
if rx < 0.0:
|
||||||
|
raise SyntaxError("expecting a nonnegative number; got %r" % (token,))
|
||||||
|
|
||||||
|
token = next()
|
||||||
|
if token[0] not in self.number_tokens:
|
||||||
|
raise SyntaxError("expecting a number; got %r" % (token,))
|
||||||
|
ry = float(token[1])
|
||||||
|
if ry < 0.0:
|
||||||
|
raise SyntaxError("expecting a nonnegative number; got %r" % (token,))
|
||||||
|
|
||||||
|
token = next()
|
||||||
|
if token[0] not in self.number_tokens:
|
||||||
|
raise SyntaxError("expecting a number; got %r" % (token,))
|
||||||
|
axis_rotation = float(token[1])
|
||||||
|
|
||||||
|
token = next()
|
||||||
|
if token[1] not in ('0', '1'):
|
||||||
|
raise SyntaxError("expecting a boolean flag; got %r" % (token,))
|
||||||
|
large_arc_flag = bool(int(token[1]))
|
||||||
|
|
||||||
|
token = next()
|
||||||
|
if token[1] not in ('0', '1'):
|
||||||
|
raise SyntaxError("expecting a boolean flag; got %r" % (token,))
|
||||||
|
sweep_flag = bool(int(token[1]))
|
||||||
|
|
||||||
|
token = next()
|
||||||
|
if token[0] not in self.number_tokens:
|
||||||
|
raise SyntaxError("expecting a number; got %r" % (token,))
|
||||||
|
x = float(token[1])
|
||||||
|
|
||||||
|
token = next()
|
||||||
|
if token[0] not in self.number_tokens:
|
||||||
|
raise SyntaxError("expecting a number; got %r" % (token,))
|
||||||
|
y = float(token[1])
|
||||||
|
|
||||||
|
token = next()
|
||||||
|
arguments.append(((rx,ry), axis_rotation, large_arc_flag, sweep_flag, (x,y)))
|
||||||
|
|
||||||
|
return (command, arguments), token
|
||||||
|
|
||||||
|
def rule_coordinate(self, next, token):
|
||||||
|
if token[0] not in self.number_tokens:
|
||||||
|
raise SyntaxError("expecting a number; got %r" % (token,))
|
||||||
|
x = float(token[1])
|
||||||
|
token = next()
|
||||||
|
return x, token
|
||||||
|
|
||||||
|
|
||||||
|
def rule_coordinate_pair(self, next, token):
|
||||||
|
# Inline these since this rule is so common.
|
||||||
|
if token[0] not in self.number_tokens:
|
||||||
|
raise SyntaxError("expecting a number; got %r" % (token,))
|
||||||
|
x = float(token[1])
|
||||||
|
token = next()
|
||||||
|
if token[0] not in self.number_tokens:
|
||||||
|
raise SyntaxError("expecting a number; got %r" % (token,))
|
||||||
|
y = float(token[1])
|
||||||
|
token = next()
|
||||||
|
return (x,y), token
|
||||||
|
|
||||||
|
|
||||||
|
svg_parser = SVGPathParser()
|
||||||
7
unittests/path-simple-triangle.svg
Normal file
7
unittests/path-simple-triangle.svg
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
<svg viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg" version="1.1">
|
||||||
|
<path d="M 300. 100 h-50-1.5E+2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
l100.00000,2000.0E-01 z" fill="red" />
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 167 B |
Loading…
Add table
Add a link
Reference in a new issue