diff options
author | Adrian Johnson <ajohnson@redneon.com> | 2022-06-24 06:44:30 +0930 |
---|---|---|
committer | Adrian Johnson <ajohnson@redneon.com> | 2022-12-28 13:22:00 +1030 |
commit | 8233c6362bbe2ca2ac4d3ef3cfc79f15ee79bc40 (patch) | |
tree | f2779a6d844d210af9b1b306a800d497150a1ad9 /test | |
parent | 252ff60f1ee62c5b36d650b91ac2536d03656bea (diff) | |
download | cairo-8233c6362bbe2ca2ac4d3ef3cfc79f15ee79bc40.tar.gz |
ft-svg-render test
Diffstat (limited to 'test')
86 files changed, 4806 insertions, 0 deletions
diff --git a/test/cairo-svg-test-doc.ttx b/test/cairo-svg-test-doc.ttx new file mode 100644 index 000000000..c2cdb2817 --- /dev/null +++ b/test/cairo-svg-test-doc.ttx @@ -0,0 +1,689 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="4.19"> + + <GlyphOrder> + <!-- The 'id' attribute is only for humans; it is ignored when parsed. --> + <GlyphID id="0" name=".notdef"/> + <GlyphID id="1" name="zero"/> + <GlyphID id="2" name="one"/> + <GlyphID id="3" name="two"/> + <GlyphID id="4" name="three"/> + <GlyphID id="5" name="four"/> + <GlyphID id="6" name="five"/> + <GlyphID id="7" name="six"/> + <GlyphID id="8" name="seven"/> + <GlyphID id="9" name="eight"/> + <GlyphID id="10" name="nine"/> + <GlyphID id="11" name="A"/> + </GlyphOrder> + + <head> + <!-- Most of this table will be recalculated by the compiler --> + <tableVersion value="1.0"/> + <fontRevision value="1.0"/> + <checkSumAdjustment value="0x6d925ed5"/> + <magicNumber value="0x5f0f3cf5"/> + <flags value="00000000 00000011"/> + <unitsPerEm value="1000"/> + <created value="Wed Jun 15 00:00:00 2022"/> + <modified value="Fri Jul 1 06:21:40 2022"/> + <xMin value="0"/> + <yMin value="0"/> + <xMax value="1000"/> + <yMax value="1000"/> + <macStyle value="00000000 00000000"/> + <lowestRecPPEM value="6"/> + <fontDirectionHint value="2"/> + <indexToLocFormat value="0"/> + <glyphDataFormat value="0"/> + </head> + + <hhea> + <tableVersion value="0x00010000"/> + <ascent value="1000"/> + <descent value="0"/> + <lineGap value="200"/> + <advanceWidthMax value="1100"/> + <minLeftSideBearing value="0"/> + <minRightSideBearing value="100"/> + <xMaxExtent value="1000"/> + <caretSlopeRise value="1"/> + <caretSlopeRun value="0"/> + <caretOffset value="0"/> + <reserved0 value="0"/> + <reserved1 value="0"/> + <reserved2 value="0"/> + <reserved3 value="0"/> + <metricDataFormat value="0"/> + <numberOfHMetrics value="1"/> + </hhea> + + <maxp> + <!-- Most of this table will be recalculated by the compiler --> + <tableVersion value="0x10000"/> + <numGlyphs value="12"/> + <maxPoints value="4"/> + <maxContours value="1"/> + <maxCompositePoints value="0"/> + <maxCompositeContours value="0"/> + <maxZones value="1"/> + <maxTwilightPoints value="0"/> + <maxStorage value="0"/> + <maxFunctionDefs value="0"/> + <maxInstructionDefs value="0"/> + <maxStackElements value="256"/> + <maxSizeOfInstructions value="1"/> + <maxComponentElements value="0"/> + <maxComponentDepth value="0"/> + </maxp> + + <OS_2> + <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex' + will be recalculated by the compiler --> + <version value="3"/> + <xAvgCharWidth value="1000"/> + <usWeightClass value="400"/> + <usWidthClass value="5"/> + <fsType value="00000000 00000001"/> + <ySubscriptXSize value="600"/> + <ySubscriptYSize value="600"/> + <ySubscriptXOffset value="0"/> + <ySubscriptYOffset value="75"/> + <ySuperscriptXSize value="600"/> + <ySuperscriptYSize value="600"/> + <ySuperscriptXOffset value="0"/> + <ySuperscriptYOffset value="300"/> + <yStrikeoutSize value="0"/> + <yStrikeoutPosition value="300"/> + <sFamilyClass value="0"/> + <panose> + <bFamilyType value="0"/> + <bSerifStyle value="0"/> + <bWeight value="0"/> + <bProportion value="0"/> + <bContrast value="0"/> + <bStrokeVariation value="0"/> + <bArmStyle value="0"/> + <bLetterForm value="0"/> + <bMidline value="0"/> + <bXHeight value="0"/> + </panose> + <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/> + <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/> + <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/> + <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/> + <achVendID value="djr "/> + <fsSelection value="00000000 01000000"/> + <usFirstCharIndex value="48"/> + <usLastCharIndex value="65"/> + <sTypoAscender value="1000"/> + <sTypoDescender value="0"/> + <sTypoLineGap value="200"/> + <usWinAscent value="1000"/> + <usWinDescent value="300"/> + <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/> + <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/> + <sxHeight value="500"/> + <sCapHeight value="720"/> + <usDefaultChar value="0"/> + <usBreakChar value="32"/> + <usMaxContext value="3"/> + </OS_2> + + <hmtx> + <mtx name=".notdef" width="1100" lsb="0"/> + <mtx name="A" width="1100" lsb="0"/> + <mtx name="eight" width="1100" lsb="0"/> + <mtx name="five" width="1100" lsb="0"/> + <mtx name="four" width="1100" lsb="0"/> + <mtx name="nine" width="1100" lsb="0"/> + <mtx name="one" width="1100" lsb="0"/> + <mtx name="seven" width="1100" lsb="0"/> + <mtx name="six" width="1100" lsb="0"/> + <mtx name="three" width="1100" lsb="0"/> + <mtx name="two" width="1100" lsb="0"/> + <mtx name="zero" width="1100" lsb="0"/> + </hmtx> + + <cmap> + <tableVersion version="0"/> + <cmap_format_4 platformID="0" platEncID="3" language="0"> + <map code="0x30" name="zero"/><!-- DIGIT ZERO --> + <map code="0x31" name="one"/><!-- DIGIT ONE --> + <map code="0x32" name="two"/><!-- DIGIT TWO --> + <map code="0x33" name="three"/><!-- DIGIT THREE --> + <map code="0x34" name="four"/><!-- DIGIT FOUR --> + <map code="0x35" name="five"/><!-- DIGIT FIVE --> + <map code="0x36" name="six"/><!-- DIGIT SIX --> + <map code="0x37" name="seven"/><!-- DIGIT SEVEN --> + <map code="0x38" name="eight"/><!-- DIGIT EIGHT --> + <map code="0x39" name="nine"/><!-- DIGIT NINE --> + <map code="0x41" name="A"/><!-- LATIN CAPITAL LETTER A --> + </cmap_format_4> + </cmap> + + <loca> + <!-- The 'loca' table will be calculated by the compiler --> + </loca> + + <glyf> + + <!-- The xMin, yMin, xMax and yMax values + will be recalculated by the compiler. --> + + <TTGlyph name=".notdef"/><!-- contains no outline data --> + + <TTGlyph name="A" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="eight" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="five" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="four" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="nine" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="one" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="seven" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="six" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="three" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="two" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="zero" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + </glyf> + + <name> + <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409"> + Cairo Svg Test Doc + </namerecord> + <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409"> + Regular + </namerecord> + <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409"> + Cairo Svg Test Doc Regular + </namerecord> + </name> + + <post> + <formatType value="3.0"/> + <italicAngle value="0.0"/> + <underlinePosition value="0"/> + <underlineThickness value="0"/> + <isFixedPitch value="0"/> + <minMemType42 value="0"/> + <maxMemType42 value="0"/> + <minMemType1 value="0"/> + <maxMemType1 value="0"/> + </post> + + <CPAL> + <version value="0"/> + <numPaletteEntries value="2"/> + <palette index="0"> + <color index="0" value="#C5A1D7FF"/> + <color index="1" value="#80DFC8FF"/> + </palette> + <palette index="1"> + <color index="0" value="#6392A9FF"/> + <color index="1" value="#7896B3FF"/> + </palette> + </CPAL> + + <SVG> + + <svgDoc endGlyphID="0" startGlyphID="0"> + <![CDATA[<svg xmlns="http://www.w3.org/2000/svg"></svg>]]> + </svgDoc> + <svgDoc endGlyphID="1" startGlyphID="1"> + <![CDATA[<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> + <rect x="10" y="-90" width="80" height="80" + fill="none" stroke="black" stroke-width="10"/> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="2" startGlyphID="2"> + <![CDATA[<svg viewBox="-5 -5 10 10" xmlns="http://www.w3.org/2000/svg"> + <rect x="-4" y="-14" width="8" height="8" + fill="none" stroke="black" stroke-width="1"/> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="3" startGlyphID="3"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <image x="0" y="-1000" width="1000" height="1000" + xlink:href="data:image/png;base64, +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 +BNcsrHnv+f9Qc51Rfhz5VAAAAABJRU5ErkJggg=="/> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="4" startGlyphID="4"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <image x="0" y="-1000" width="1000" height="1000" + transform="scale(0.5) rotate(-45),translate(800,500)" + xlink:href="data:image/png;base64, +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 +BNcsrHnv+f9Qc51Rfhz5VAAAAABJRU5ErkJggg=="/> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="5" startGlyphID="5"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="1000" height="1000"> + <clipPath id="clip" clipPathUnits="userSpaceOnUse" > + <circle cx="500" cy="-500" r="400" /> + </clipPath> + + <rect x="100" y="-900" width="800" height="800" + stroke="green" stroke-width="100" + clip-path="url(#clip)" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="6" startGlyphID="6"> + <![CDATA[<svg xmlns="http://www.w3.org/2000/svg" width="1000" height="1000"> + <clipPath id="clip" clipPathUnits="objectBoundingBox"> + <circle cx=".5" cy=".5" r=".5" /> + </clipPath> + + <rect x="100" y="-900" width="800" height="800" + stroke="green" stroke-width="100" + clip-path="url(#clip)" /> + +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="7" startGlyphID="7"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="1000" height="1000"> + <clipPath id="clip" clipPathUnits="userSpaceOnUse" > + <circle cx="500" cy="-500" r="400" /> + <rect x="100" y="-900" width="800" height="400"/> + </clipPath> + + <rect x="100" y="-900" width="800" height="800" + stroke="green" stroke-width="100" + clip-path="url(#clip)" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="8" startGlyphID="8"> + <![CDATA[<svg xmlns="http://www.w3.org/2000/svg" width="1000" height="1000"> + <clipPath id="clip" clipPathUnits="objectBoundingBox"> + <circle cx=".5" cy=".5" r=".5" /> + <rect x="0" y="0" width="1" height="0.5"/> + </clipPath> + + <rect x="100" y="-900" width="800" height="800" + stroke="green" stroke-width="100" + clip-path="url(#clip)" /> + +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="9" startGlyphID="9"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="1000" height="1000"> + <clipPath id="clip" clipPathUnits="userSpaceOnUse" > + <circle cx="500" cy="-500" r="400" /> + </clipPath> + + <clipPath id="clip2" clipPathUnits="userSpaceOnUse" > + <rect x="100" y="-900" width="800" height="400"/> + </clipPath> + + <g clip-path="url(#clip)"> + <rect x="100" y="-900" width="800" height="800" + stroke="green" stroke-width="100" + clip-path="url(#clip2)" /> + </g> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="10" startGlyphID="10"> + <![CDATA[<svg xmlns="http://www.w3.org/2000/svg" width="1000" height="1000"> + <clipPath id="clip" clipPathUnits="objectBoundingBox"> + <circle cx=".5" cy=".5" r=".5" /> + </clipPath> + + <clipPath id="clip2" clipPathUnits="objectBoundingBox"> + <rect x="0" y="0" width="1" height="0.5"/> + </clipPath> + + <g clip-path="url(#clip)"> + <rect x="100" y="-900" width="800" height="800" + stroke="green" stroke-width="100" + clip-path="url(#clip2)" /> + </g> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="11" startGlyphID="11"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" > + <defs> + <circle id="circle" + cx="0" cy="0" r="250" /> + </defs> + + <g opacity="0.5"> + <use xlink:href="#circle" x="330" y="-500" + fill="red" /> + <use xlink:href="#circle" x="670" y="-500" + fill="green" /> + </g> +</svg>]]> + </svgDoc> + </SVG> + +</ttFont> diff --git a/test/cairo-svg-test-fill.ttx b/test/cairo-svg-test-fill.ttx new file mode 100644 index 000000000..b6867ec8f --- /dev/null +++ b/test/cairo-svg-test-fill.ttx @@ -0,0 +1,365 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="4.19"> + + <GlyphOrder> + <!-- The 'id' attribute is only for humans; it is ignored when parsed. --> + <GlyphID id="0" name=".notdef"/> + <GlyphID id="1" name="zero"/> + <GlyphID id="2" name="one"/> + <GlyphID id="3" name="two"/> + <GlyphID id="4" name="three"/> + <GlyphID id="5" name="four"/> + <GlyphID id="6" name="five"/> + <GlyphID id="7" name="six"/> + <GlyphID id="8" name="seven"/> + <GlyphID id="9" name="eight"/> + </GlyphOrder> + + <head> + <!-- Most of this table will be recalculated by the compiler --> + <tableVersion value="1.0"/> + <fontRevision value="1.0"/> + <checkSumAdjustment value="0x71e2812"/> + <magicNumber value="0x5f0f3cf5"/> + <flags value="00000000 00000011"/> + <unitsPerEm value="1000"/> + <created value="Wed Jun 15 00:00:00 2022"/> + <modified value="Fri Jul 1 06:21:40 2022"/> + <xMin value="0"/> + <yMin value="0"/> + <xMax value="1000"/> + <yMax value="1000"/> + <macStyle value="00000000 00000000"/> + <lowestRecPPEM value="6"/> + <fontDirectionHint value="2"/> + <indexToLocFormat value="0"/> + <glyphDataFormat value="0"/> + </head> + + <hhea> + <tableVersion value="0x00010000"/> + <ascent value="1000"/> + <descent value="0"/> + <lineGap value="200"/> + <advanceWidthMax value="1100"/> + <minLeftSideBearing value="0"/> + <minRightSideBearing value="100"/> + <xMaxExtent value="1000"/> + <caretSlopeRise value="1"/> + <caretSlopeRun value="0"/> + <caretOffset value="0"/> + <reserved0 value="0"/> + <reserved1 value="0"/> + <reserved2 value="0"/> + <reserved3 value="0"/> + <metricDataFormat value="0"/> + <numberOfHMetrics value="1"/> + </hhea> + + <maxp> + <!-- Most of this table will be recalculated by the compiler --> + <tableVersion value="0x10000"/> + <numGlyphs value="10"/> + <maxPoints value="4"/> + <maxContours value="1"/> + <maxCompositePoints value="0"/> + <maxCompositeContours value="0"/> + <maxZones value="1"/> + <maxTwilightPoints value="0"/> + <maxStorage value="0"/> + <maxFunctionDefs value="0"/> + <maxInstructionDefs value="0"/> + <maxStackElements value="256"/> + <maxSizeOfInstructions value="1"/> + <maxComponentElements value="0"/> + <maxComponentDepth value="0"/> + </maxp> + + <OS_2> + <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex' + will be recalculated by the compiler --> + <version value="3"/> + <xAvgCharWidth value="1000"/> + <usWeightClass value="400"/> + <usWidthClass value="5"/> + <fsType value="00000000 00000001"/> + <ySubscriptXSize value="600"/> + <ySubscriptYSize value="600"/> + <ySubscriptXOffset value="0"/> + <ySubscriptYOffset value="75"/> + <ySuperscriptXSize value="600"/> + <ySuperscriptYSize value="600"/> + <ySuperscriptXOffset value="0"/> + <ySuperscriptYOffset value="300"/> + <yStrikeoutSize value="0"/> + <yStrikeoutPosition value="300"/> + <sFamilyClass value="0"/> + <panose> + <bFamilyType value="0"/> + <bSerifStyle value="0"/> + <bWeight value="0"/> + <bProportion value="0"/> + <bContrast value="0"/> + <bStrokeVariation value="0"/> + <bArmStyle value="0"/> + <bLetterForm value="0"/> + <bMidline value="0"/> + <bXHeight value="0"/> + </panose> + <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/> + <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/> + <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/> + <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/> + <achVendID value="djr "/> + <fsSelection value="00000000 01000000"/> + <usFirstCharIndex value="48"/> + <usLastCharIndex value="56"/> + <sTypoAscender value="1000"/> + <sTypoDescender value="0"/> + <sTypoLineGap value="200"/> + <usWinAscent value="1000"/> + <usWinDescent value="300"/> + <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/> + <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/> + <sxHeight value="500"/> + <sCapHeight value="720"/> + <usDefaultChar value="0"/> + <usBreakChar value="32"/> + <usMaxContext value="3"/> + </OS_2> + + <hmtx> + <mtx name=".notdef" width="1100" lsb="0"/> + <mtx name="eight" width="1100" lsb="0"/> + <mtx name="five" width="1100" lsb="0"/> + <mtx name="four" width="1100" lsb="0"/> + <mtx name="one" width="1100" lsb="0"/> + <mtx name="seven" width="1100" lsb="0"/> + <mtx name="six" width="1100" lsb="0"/> + <mtx name="three" width="1100" lsb="0"/> + <mtx name="two" width="1100" lsb="0"/> + <mtx name="zero" width="1100" lsb="0"/> + </hmtx> + + <cmap> + <tableVersion version="0"/> + <cmap_format_4 platformID="0" platEncID="3" language="0"> + <map code="0x30" name="zero"/><!-- DIGIT ZERO --> + <map code="0x31" name="one"/><!-- DIGIT ONE --> + <map code="0x32" name="two"/><!-- DIGIT TWO --> + <map code="0x33" name="three"/><!-- DIGIT THREE --> + <map code="0x34" name="four"/><!-- DIGIT FOUR --> + <map code="0x35" name="five"/><!-- DIGIT FIVE --> + <map code="0x36" name="six"/><!-- DIGIT SIX --> + <map code="0x37" name="seven"/><!-- DIGIT SEVEN --> + <map code="0x38" name="eight"/><!-- DIGIT EIGHT --> + </cmap_format_4> + </cmap> + + <loca> + <!-- The 'loca' table will be calculated by the compiler --> + </loca> + + <glyf> + + <!-- The xMin, yMin, xMax and yMax values + will be recalculated by the compiler. --> + + <TTGlyph name=".notdef"/><!-- contains no outline data --> + + <TTGlyph name="eight" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="five" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="four" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="one" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="seven" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="six" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="three" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="two" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="zero" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + </glyf> + + <name> + <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409"> + Cairo Svg Test Fill + </namerecord> + <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409"> + Regular + </namerecord> + <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409"> + Cairo Svg Test Fill Regular + </namerecord> + </name> + + <post> + <formatType value="3.0"/> + <italicAngle value="0.0"/> + <underlinePosition value="0"/> + <underlineThickness value="0"/> + <isFixedPitch value="0"/> + <minMemType42 value="0"/> + <maxMemType42 value="0"/> + <minMemType1 value="0"/> + <maxMemType1 value="0"/> + </post> + + <CPAL> + <version value="0"/> + <numPaletteEntries value="2"/> + <palette index="0"> + <color index="0" value="#C5A1D7FF"/> + <color index="1" value="#80DFC8FF"/> + </palette> + <palette index="1"> + <color index="0" value="#6392A9FF"/> + <color index="1" value="#7896B3FF"/> + </palette> + </CPAL> + + <SVG> + + <svgDoc endGlyphID="0" startGlyphID="0"> + <![CDATA[<svg xmlns="http://www.w3.org/2000/svg"></svg>]]> + </svgDoc> + <svgDoc endGlyphID="1" startGlyphID="1"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <rect x="100" y="-750" width="800" height="500" + fill="indigo" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="2" startGlyphID="2"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <rect x="100" y="-750" width="800" height="500" + fill="#AA55AA" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="3" startGlyphID="3"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <rect x="100" y="-750" width="800" height="500" + fill="#A5A" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="4" startGlyphID="4"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <rect x="100" y="-750" width="800" height="500" + fill="rgb (75, 0 , 130)" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="5" startGlyphID="5"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <rect x="100" y="-750" width="800" height="500" + fill="currentColor" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="6" startGlyphID="6"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <rect x="100" y="-750" width="800" height="500" + fill="var(--color1, red)" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="7" startGlyphID="7"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <rect x="100" y="-750" width="800" height="500" + fill="magenta" fill-opacity="0.5" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="8" startGlyphID="8"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + color="green" > + <rect x="100" y="-750" width="800" height="500" + fill="currentColor" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="9" startGlyphID="9"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <g transform="scale(5,5) translate(0,-150)"> + <polygon fill-rule="nonzero" + points="50,0 21,90 98,35 2,35 79,90"/> + <polygon fill-rule="evenodd" + points="150,0 121,90 198,35 102,35 179,90"/> + </g> +</svg>]]> + </svgDoc> + </SVG> + +</ttFont> diff --git a/test/cairo-svg-test-gradient.ttx b/test/cairo-svg-test-gradient.ttx new file mode 100644 index 000000000..4a7a22175 --- /dev/null +++ b/test/cairo-svg-test-gradient.ttx @@ -0,0 +1,441 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="4.19"> + + <GlyphOrder> + <!-- The 'id' attribute is only for humans; it is ignored when parsed. --> + <GlyphID id="0" name=".notdef"/> + <GlyphID id="1" name="zero"/> + <GlyphID id="2" name="one"/> + <GlyphID id="3" name="two"/> + <GlyphID id="4" name="three"/> + <GlyphID id="5" name="four"/> + <GlyphID id="6" name="five"/> + <GlyphID id="7" name="six"/> + <GlyphID id="8" name="seven"/> + <GlyphID id="9" name="eight"/> + <GlyphID id="10" name="nine"/> + </GlyphOrder> + + <head> + <!-- Most of this table will be recalculated by the compiler --> + <tableVersion value="1.0"/> + <fontRevision value="1.0"/> + <checkSumAdjustment value="0x4322c7de"/> + <magicNumber value="0x5f0f3cf5"/> + <flags value="00000000 00000011"/> + <unitsPerEm value="1000"/> + <created value="Wed Jun 15 00:00:00 2022"/> + <modified value="Fri Jul 1 06:21:39 2022"/> + <xMin value="0"/> + <yMin value="0"/> + <xMax value="1000"/> + <yMax value="1000"/> + <macStyle value="00000000 00000000"/> + <lowestRecPPEM value="6"/> + <fontDirectionHint value="2"/> + <indexToLocFormat value="0"/> + <glyphDataFormat value="0"/> + </head> + + <hhea> + <tableVersion value="0x00010000"/> + <ascent value="1000"/> + <descent value="0"/> + <lineGap value="200"/> + <advanceWidthMax value="1100"/> + <minLeftSideBearing value="0"/> + <minRightSideBearing value="100"/> + <xMaxExtent value="1000"/> + <caretSlopeRise value="1"/> + <caretSlopeRun value="0"/> + <caretOffset value="0"/> + <reserved0 value="0"/> + <reserved1 value="0"/> + <reserved2 value="0"/> + <reserved3 value="0"/> + <metricDataFormat value="0"/> + <numberOfHMetrics value="1"/> + </hhea> + + <maxp> + <!-- Most of this table will be recalculated by the compiler --> + <tableVersion value="0x10000"/> + <numGlyphs value="11"/> + <maxPoints value="4"/> + <maxContours value="1"/> + <maxCompositePoints value="0"/> + <maxCompositeContours value="0"/> + <maxZones value="1"/> + <maxTwilightPoints value="0"/> + <maxStorage value="0"/> + <maxFunctionDefs value="0"/> + <maxInstructionDefs value="0"/> + <maxStackElements value="256"/> + <maxSizeOfInstructions value="1"/> + <maxComponentElements value="0"/> + <maxComponentDepth value="0"/> + </maxp> + + <OS_2> + <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex' + will be recalculated by the compiler --> + <version value="3"/> + <xAvgCharWidth value="1000"/> + <usWeightClass value="400"/> + <usWidthClass value="5"/> + <fsType value="00000000 00000001"/> + <ySubscriptXSize value="600"/> + <ySubscriptYSize value="600"/> + <ySubscriptXOffset value="0"/> + <ySubscriptYOffset value="75"/> + <ySuperscriptXSize value="600"/> + <ySuperscriptYSize value="600"/> + <ySuperscriptXOffset value="0"/> + <ySuperscriptYOffset value="300"/> + <yStrikeoutSize value="0"/> + <yStrikeoutPosition value="300"/> + <sFamilyClass value="0"/> + <panose> + <bFamilyType value="0"/> + <bSerifStyle value="0"/> + <bWeight value="0"/> + <bProportion value="0"/> + <bContrast value="0"/> + <bStrokeVariation value="0"/> + <bArmStyle value="0"/> + <bLetterForm value="0"/> + <bMidline value="0"/> + <bXHeight value="0"/> + </panose> + <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/> + <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/> + <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/> + <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/> + <achVendID value="djr "/> + <fsSelection value="00000000 01000000"/> + <usFirstCharIndex value="48"/> + <usLastCharIndex value="57"/> + <sTypoAscender value="1000"/> + <sTypoDescender value="0"/> + <sTypoLineGap value="200"/> + <usWinAscent value="1000"/> + <usWinDescent value="300"/> + <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/> + <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/> + <sxHeight value="500"/> + <sCapHeight value="720"/> + <usDefaultChar value="0"/> + <usBreakChar value="32"/> + <usMaxContext value="3"/> + </OS_2> + + <hmtx> + <mtx name=".notdef" width="1100" lsb="0"/> + <mtx name="eight" width="1100" lsb="0"/> + <mtx name="five" width="1100" lsb="0"/> + <mtx name="four" width="1100" lsb="0"/> + <mtx name="nine" width="1100" lsb="0"/> + <mtx name="one" width="1100" lsb="0"/> + <mtx name="seven" width="1100" lsb="0"/> + <mtx name="six" width="1100" lsb="0"/> + <mtx name="three" width="1100" lsb="0"/> + <mtx name="two" width="1100" lsb="0"/> + <mtx name="zero" width="1100" lsb="0"/> + </hmtx> + + <cmap> + <tableVersion version="0"/> + <cmap_format_4 platformID="0" platEncID="3" language="0"> + <map code="0x30" name="zero"/><!-- DIGIT ZERO --> + <map code="0x31" name="one"/><!-- DIGIT ONE --> + <map code="0x32" name="two"/><!-- DIGIT TWO --> + <map code="0x33" name="three"/><!-- DIGIT THREE --> + <map code="0x34" name="four"/><!-- DIGIT FOUR --> + <map code="0x35" name="five"/><!-- DIGIT FIVE --> + <map code="0x36" name="six"/><!-- DIGIT SIX --> + <map code="0x37" name="seven"/><!-- DIGIT SEVEN --> + <map code="0x38" name="eight"/><!-- DIGIT EIGHT --> + <map code="0x39" name="nine"/><!-- DIGIT NINE --> + </cmap_format_4> + </cmap> + + <loca> + <!-- The 'loca' table will be calculated by the compiler --> + </loca> + + <glyf> + + <!-- The xMin, yMin, xMax and yMax values + will be recalculated by the compiler. --> + + <TTGlyph name=".notdef"/><!-- contains no outline data --> + + <TTGlyph name="eight" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="five" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="four" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="nine" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="one" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="seven" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="six" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="three" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="two" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="zero" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + </glyf> + + <name> + <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409"> + Cairo Svg Test Gradient + </namerecord> + <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409"> + Regular + </namerecord> + <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409"> + Cairo Svg Test Gradient Regular + </namerecord> + </name> + + <post> + <formatType value="3.0"/> + <italicAngle value="0.0"/> + <underlinePosition value="0"/> + <underlineThickness value="0"/> + <isFixedPitch value="0"/> + <minMemType42 value="0"/> + <maxMemType42 value="0"/> + <minMemType1 value="0"/> + <maxMemType1 value="0"/> + </post> + + <CPAL> + <version value="0"/> + <numPaletteEntries value="2"/> + <palette index="0"> + <color index="0" value="#C5A1D7FF"/> + <color index="1" value="#80DFC8FF"/> + </palette> + <palette index="1"> + <color index="0" value="#6392A9FF"/> + <color index="1" value="#7896B3FF"/> + </palette> + </CPAL> + + <SVG> + + <svgDoc endGlyphID="0" startGlyphID="0"> + <![CDATA[<svg xmlns="http://www.w3.org/2000/svg"></svg>]]> + </svgDoc> + <svgDoc endGlyphID="1" startGlyphID="1"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <defs> + <linearGradient id="grad" x1="33%" x21="66%"> + <stop offset="0%" stop-color="blue" stop-opacity="1" /> + <stop offset="100%" stop-color="red" stop-opacity="0.5" /> + </linearGradient> + </defs> + <rect x="100" y="-900" width="800" height="800" fill="url(#grad)" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="2" startGlyphID="2"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <defs> + <linearGradient id="grad" x1="33%" x2="66%" + spreadMethod="reflect"> + <stop offset="0%" stop-color="blue" stop-opacity="1" /> + <stop offset="100%" stop-color="red" stop-opacity="1" /> + </linearGradient> + </defs> + <rect x="0" y="-900" width="1000" height="800" fill="url(#grad)" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="3" startGlyphID="3"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <defs> + <linearGradient id="grad" x1="33%" x2="66%" + spreadMethod="repeat"> + <stop offset="0%" stop-color="blue" stop-opacity="1" /> + <stop offset="100%" stop-color="red" stop-opacity="1" /> + </linearGradient> + </defs> + <rect x="0" y="-900" width="1000" height="800" fill="url(#grad)" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="4" startGlyphID="4"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <defs> + <linearGradient id="grad" x1="300" y1="-500" x2="600" y2="-500" + gradientUnits="userSpaceOnUse"> + <stop offset="0%" stop-color="blue" stop-opacity="1" /> + <stop offset="100%" stop-color="red" stop-opacity="1" /> + </linearGradient> + </defs> + <rect x="0" y="-900" width="1000" height="800" fill="url(#grad)" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="5" startGlyphID="5"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <defs> + <linearGradient id="grad" gradientTransform="rotate(45)"> + <stop offset="0%" stop-color="blue" stop-opacity="1" /> + <stop offset="100%" stop-color="red" stop-opacity="1" /> + </linearGradient> + </defs> + <rect x="100" y="-900" width="800" height="800" fill="url(#grad)" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="6" startGlyphID="6"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <defs> + <radialGradient id="grad" cx="50%" cy="50%" + fx="0.75" fy="0.35" r="0.5"> + <stop offset="0%" stop-color="white" stop-opacity="1" /> + <stop offset="100%" stop-color="green" stop-opacity="1" /> + </radialGradient> + </defs> + <rect x="100" y="-900" width="800" height="800" fill="url(#grad)" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="7" startGlyphID="7"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <defs> + <radialGradient id="grad" cx="75%" cy="25%" r="33%" + fx="0.64" fy="0.18" fr="0.17" + spreadMethod="reflect" > + <stop offset="0%" stop-color="white" stop-opacity="1" /> + <stop offset="100%" stop-color="green" stop-opacity="1" /> + </radialGradient> + </defs> + <rect x="100" y="-900" width="800" height="800" fill="url(#grad)" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="8" startGlyphID="8"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <defs> + <radialGradient id="grad" cx="75%" cy="25%" r="33%" + fx="0.64" fy="0.18" fr="0.17" + spreadMethod="repeat" > + <stop offset="0%" stop-color="white" stop-opacity="1" /> + <stop offset="100%" stop-color="green" stop-opacity="1" /> + </radialGradient> + </defs> + <rect x="100" y="-900" width="800" height="800" fill="url(#grad)" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="9" startGlyphID="9"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <defs> + <radialGradient id="grad" cx="450" cy="-550" r="400" + fx="600" fy="-400" fr="10" + gradientUnits="userSpaceOnUse" > + <stop offset="0%" stop-color="red" stop-opacity="1" /> + <stop offset="100%" stop-color="green" stop-opacity="0.5" /> + </radialGradient> + </defs> + <rect x="0" y="-1000" width="1000" height="1000" fill="url(#grad)" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="10" startGlyphID="10"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <defs> + <radialGradient id="grad" cx="50%" cy="25%" + fx="0.75" fy="0.35" r="0.5" + gradientTransform="scale(1, 2)"> + <stop offset="0%" stop-color="red" stop-opacity="1" /> + <stop offset="100%" stop-color="green" stop-opacity="1" /> + </radialGradient> + </defs> + <rect x="100" y="-900" width="800" height="800" fill="url(#grad)" /> +</svg>]]> + </svgDoc> + </SVG> + +</ttFont> diff --git a/test/cairo-svg-test-path.ttx b/test/cairo-svg-test-path.ttx new file mode 100644 index 000000000..9173a537d --- /dev/null +++ b/test/cairo-svg-test-path.ttx @@ -0,0 +1,281 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="4.19"> + + <GlyphOrder> + <!-- The 'id' attribute is only for humans; it is ignored when parsed. --> + <GlyphID id="0" name=".notdef"/> + <GlyphID id="1" name="zero"/> + <GlyphID id="2" name="one"/> + <GlyphID id="3" name="two"/> + <GlyphID id="4" name="three"/> + </GlyphOrder> + + <head> + <!-- Most of this table will be recalculated by the compiler --> + <tableVersion value="1.0"/> + <fontRevision value="1.0"/> + <checkSumAdjustment value="0x20ff0b91"/> + <magicNumber value="0x5f0f3cf5"/> + <flags value="00000000 00000011"/> + <unitsPerEm value="1000"/> + <created value="Wed Jun 15 00:00:00 2022"/> + <modified value="Fri Jul 1 06:21:40 2022"/> + <xMin value="0"/> + <yMin value="0"/> + <xMax value="1000"/> + <yMax value="1000"/> + <macStyle value="00000000 00000000"/> + <lowestRecPPEM value="6"/> + <fontDirectionHint value="2"/> + <indexToLocFormat value="0"/> + <glyphDataFormat value="0"/> + </head> + + <hhea> + <tableVersion value="0x00010000"/> + <ascent value="1000"/> + <descent value="0"/> + <lineGap value="200"/> + <advanceWidthMax value="1100"/> + <minLeftSideBearing value="0"/> + <minRightSideBearing value="100"/> + <xMaxExtent value="1000"/> + <caretSlopeRise value="1"/> + <caretSlopeRun value="0"/> + <caretOffset value="0"/> + <reserved0 value="0"/> + <reserved1 value="0"/> + <reserved2 value="0"/> + <reserved3 value="0"/> + <metricDataFormat value="0"/> + <numberOfHMetrics value="1"/> + </hhea> + + <maxp> + <!-- Most of this table will be recalculated by the compiler --> + <tableVersion value="0x10000"/> + <numGlyphs value="5"/> + <maxPoints value="4"/> + <maxContours value="1"/> + <maxCompositePoints value="0"/> + <maxCompositeContours value="0"/> + <maxZones value="1"/> + <maxTwilightPoints value="0"/> + <maxStorage value="0"/> + <maxFunctionDefs value="0"/> + <maxInstructionDefs value="0"/> + <maxStackElements value="256"/> + <maxSizeOfInstructions value="1"/> + <maxComponentElements value="0"/> + <maxComponentDepth value="0"/> + </maxp> + + <OS_2> + <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex' + will be recalculated by the compiler --> + <version value="3"/> + <xAvgCharWidth value="1000"/> + <usWeightClass value="400"/> + <usWidthClass value="5"/> + <fsType value="00000000 00000001"/> + <ySubscriptXSize value="600"/> + <ySubscriptYSize value="600"/> + <ySubscriptXOffset value="0"/> + <ySubscriptYOffset value="75"/> + <ySuperscriptXSize value="600"/> + <ySuperscriptYSize value="600"/> + <ySuperscriptXOffset value="0"/> + <ySuperscriptYOffset value="300"/> + <yStrikeoutSize value="0"/> + <yStrikeoutPosition value="300"/> + <sFamilyClass value="0"/> + <panose> + <bFamilyType value="0"/> + <bSerifStyle value="0"/> + <bWeight value="0"/> + <bProportion value="0"/> + <bContrast value="0"/> + <bStrokeVariation value="0"/> + <bArmStyle value="0"/> + <bLetterForm value="0"/> + <bMidline value="0"/> + <bXHeight value="0"/> + </panose> + <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/> + <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/> + <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/> + <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/> + <achVendID value="djr "/> + <fsSelection value="00000000 01000000"/> + <usFirstCharIndex value="48"/> + <usLastCharIndex value="51"/> + <sTypoAscender value="1000"/> + <sTypoDescender value="0"/> + <sTypoLineGap value="200"/> + <usWinAscent value="1000"/> + <usWinDescent value="300"/> + <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/> + <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/> + <sxHeight value="500"/> + <sCapHeight value="720"/> + <usDefaultChar value="0"/> + <usBreakChar value="32"/> + <usMaxContext value="3"/> + </OS_2> + + <hmtx> + <mtx name=".notdef" width="1100" lsb="0"/> + <mtx name="one" width="1100" lsb="0"/> + <mtx name="three" width="1100" lsb="0"/> + <mtx name="two" width="1100" lsb="0"/> + <mtx name="zero" width="1100" lsb="0"/> + </hmtx> + + <cmap> + <tableVersion version="0"/> + <cmap_format_4 platformID="0" platEncID="3" language="0"> + <map code="0x30" name="zero"/><!-- DIGIT ZERO --> + <map code="0x31" name="one"/><!-- DIGIT ONE --> + <map code="0x32" name="two"/><!-- DIGIT TWO --> + <map code="0x33" name="three"/><!-- DIGIT THREE --> + </cmap_format_4> + </cmap> + + <loca> + <!-- The 'loca' table will be calculated by the compiler --> + </loca> + + <glyf> + + <!-- The xMin, yMin, xMax and yMax values + will be recalculated by the compiler. --> + + <TTGlyph name=".notdef"/><!-- contains no outline data --> + + <TTGlyph name="one" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="three" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="two" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="zero" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + </glyf> + + <name> + <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409"> + Cairo Svg Test Path + </namerecord> + <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409"> + Regular + </namerecord> + <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409"> + Cairo Svg Test Path Regular + </namerecord> + </name> + + <post> + <formatType value="3.0"/> + <italicAngle value="0.0"/> + <underlinePosition value="0"/> + <underlineThickness value="0"/> + <isFixedPitch value="0"/> + <minMemType42 value="0"/> + <maxMemType42 value="0"/> + <minMemType1 value="0"/> + <maxMemType1 value="0"/> + </post> + + <CPAL> + <version value="0"/> + <numPaletteEntries value="2"/> + <palette index="0"> + <color index="0" value="#C5A1D7FF"/> + <color index="1" value="#80DFC8FF"/> + </palette> + <palette index="1"> + <color index="0" value="#6392A9FF"/> + <color index="1" value="#7896B3FF"/> + </palette> + </CPAL> + + <SVG> + + <svgDoc endGlyphID="0" startGlyphID="0"> + <![CDATA[<svg xmlns="http://www.w3.org/2000/svg"></svg>]]> + </svgDoc> + <svgDoc endGlyphID="1" startGlyphID="1"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <path fill="none" stroke="black" stroke-width="20" + d="M 200 -200 + L 500 -500 + H 800 + V -200 + " /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="2" startGlyphID="2"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <path fill="none" stroke="black" stroke-width="20" + d="M200,-400 + C200,-200 + 500,-200 + 500,-400 + S800,-600 + 800,-400" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="3" startGlyphID="3"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <path fill="none" stroke="black" stroke-width="20" + d="M200,-300 + Q400,-50 + 600,-300 + T1000,-300" + /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="4" startGlyphID="4"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <path fill="none" stroke="black" stroke-width="20" + d="M500,-500 + L 712 -712 + A300,300 0 1,0 712, -288 z" + /> +</svg>]]> + </svgDoc> + </SVG> + +</ttFont> diff --git a/test/cairo-svg-test-shapes.ttx b/test/cairo-svg-test-shapes.ttx new file mode 100644 index 000000000..15a573a64 --- /dev/null +++ b/test/cairo-svg-test-shapes.ttx @@ -0,0 +1,333 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="4.19"> + + <GlyphOrder> + <!-- The 'id' attribute is only for humans; it is ignored when parsed. --> + <GlyphID id="0" name=".notdef"/> + <GlyphID id="1" name="zero"/> + <GlyphID id="2" name="one"/> + <GlyphID id="3" name="two"/> + <GlyphID id="4" name="three"/> + <GlyphID id="5" name="four"/> + <GlyphID id="6" name="five"/> + <GlyphID id="7" name="six"/> + </GlyphOrder> + + <head> + <!-- Most of this table will be recalculated by the compiler --> + <tableVersion value="1.0"/> + <fontRevision value="1.0"/> + <checkSumAdjustment value="0xa8919a30"/> + <magicNumber value="0x5f0f3cf5"/> + <flags value="00000000 00000011"/> + <unitsPerEm value="1000"/> + <created value="Wed Jun 15 00:00:00 2022"/> + <modified value="Fri Jul 1 06:21:40 2022"/> + <xMin value="0"/> + <yMin value="0"/> + <xMax value="1000"/> + <yMax value="1000"/> + <macStyle value="00000000 00000000"/> + <lowestRecPPEM value="6"/> + <fontDirectionHint value="2"/> + <indexToLocFormat value="0"/> + <glyphDataFormat value="0"/> + </head> + + <hhea> + <tableVersion value="0x00010000"/> + <ascent value="1000"/> + <descent value="0"/> + <lineGap value="200"/> + <advanceWidthMax value="1100"/> + <minLeftSideBearing value="0"/> + <minRightSideBearing value="100"/> + <xMaxExtent value="1000"/> + <caretSlopeRise value="1"/> + <caretSlopeRun value="0"/> + <caretOffset value="0"/> + <reserved0 value="0"/> + <reserved1 value="0"/> + <reserved2 value="0"/> + <reserved3 value="0"/> + <metricDataFormat value="0"/> + <numberOfHMetrics value="1"/> + </hhea> + + <maxp> + <!-- Most of this table will be recalculated by the compiler --> + <tableVersion value="0x10000"/> + <numGlyphs value="8"/> + <maxPoints value="4"/> + <maxContours value="1"/> + <maxCompositePoints value="0"/> + <maxCompositeContours value="0"/> + <maxZones value="1"/> + <maxTwilightPoints value="0"/> + <maxStorage value="0"/> + <maxFunctionDefs value="0"/> + <maxInstructionDefs value="0"/> + <maxStackElements value="256"/> + <maxSizeOfInstructions value="1"/> + <maxComponentElements value="0"/> + <maxComponentDepth value="0"/> + </maxp> + + <OS_2> + <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex' + will be recalculated by the compiler --> + <version value="3"/> + <xAvgCharWidth value="1000"/> + <usWeightClass value="400"/> + <usWidthClass value="5"/> + <fsType value="00000000 00000001"/> + <ySubscriptXSize value="600"/> + <ySubscriptYSize value="600"/> + <ySubscriptXOffset value="0"/> + <ySubscriptYOffset value="75"/> + <ySuperscriptXSize value="600"/> + <ySuperscriptYSize value="600"/> + <ySuperscriptXOffset value="0"/> + <ySuperscriptYOffset value="300"/> + <yStrikeoutSize value="0"/> + <yStrikeoutPosition value="300"/> + <sFamilyClass value="0"/> + <panose> + <bFamilyType value="0"/> + <bSerifStyle value="0"/> + <bWeight value="0"/> + <bProportion value="0"/> + <bContrast value="0"/> + <bStrokeVariation value="0"/> + <bArmStyle value="0"/> + <bLetterForm value="0"/> + <bMidline value="0"/> + <bXHeight value="0"/> + </panose> + <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/> + <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/> + <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/> + <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/> + <achVendID value="djr "/> + <fsSelection value="00000000 01000000"/> + <usFirstCharIndex value="48"/> + <usLastCharIndex value="54"/> + <sTypoAscender value="1000"/> + <sTypoDescender value="0"/> + <sTypoLineGap value="200"/> + <usWinAscent value="1000"/> + <usWinDescent value="300"/> + <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/> + <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/> + <sxHeight value="500"/> + <sCapHeight value="720"/> + <usDefaultChar value="0"/> + <usBreakChar value="32"/> + <usMaxContext value="3"/> + </OS_2> + + <hmtx> + <mtx name=".notdef" width="1100" lsb="0"/> + <mtx name="five" width="1100" lsb="0"/> + <mtx name="four" width="1100" lsb="0"/> + <mtx name="one" width="1100" lsb="0"/> + <mtx name="six" width="1100" lsb="0"/> + <mtx name="three" width="1100" lsb="0"/> + <mtx name="two" width="1100" lsb="0"/> + <mtx name="zero" width="1100" lsb="0"/> + </hmtx> + + <cmap> + <tableVersion version="0"/> + <cmap_format_4 platformID="0" platEncID="3" language="0"> + <map code="0x30" name="zero"/><!-- DIGIT ZERO --> + <map code="0x31" name="one"/><!-- DIGIT ONE --> + <map code="0x32" name="two"/><!-- DIGIT TWO --> + <map code="0x33" name="three"/><!-- DIGIT THREE --> + <map code="0x34" name="four"/><!-- DIGIT FOUR --> + <map code="0x35" name="five"/><!-- DIGIT FIVE --> + <map code="0x36" name="six"/><!-- DIGIT SIX --> + </cmap_format_4> + </cmap> + + <loca> + <!-- The 'loca' table will be calculated by the compiler --> + </loca> + + <glyf> + + <!-- The xMin, yMin, xMax and yMax values + will be recalculated by the compiler. --> + + <TTGlyph name=".notdef"/><!-- contains no outline data --> + + <TTGlyph name="five" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="four" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="one" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="six" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="three" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="two" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="zero" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + </glyf> + + <name> + <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409"> + Cairo Svg Test Shapes + </namerecord> + <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409"> + Regular + </namerecord> + <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409"> + Cairo Svg Test Shapes Regular + </namerecord> + </name> + + <post> + <formatType value="3.0"/> + <italicAngle value="0.0"/> + <underlinePosition value="0"/> + <underlineThickness value="0"/> + <isFixedPitch value="0"/> + <minMemType42 value="0"/> + <maxMemType42 value="0"/> + <minMemType1 value="0"/> + <maxMemType1 value="0"/> + </post> + + <CPAL> + <version value="0"/> + <numPaletteEntries value="2"/> + <palette index="0"> + <color index="0" value="#C5A1D7FF"/> + <color index="1" value="#80DFC8FF"/> + </palette> + <palette index="1"> + <color index="0" value="#6392A9FF"/> + <color index="1" value="#7896B3FF"/> + </palette> + </CPAL> + + <SVG> + + <svgDoc endGlyphID="0" startGlyphID="0"> + <![CDATA[<svg xmlns="http://www.w3.org/2000/svg"></svg>]]> + </svgDoc> + <svgDoc endGlyphID="1" startGlyphID="1"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <rect x="100" y="-750" width="800" height="500"/> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="2" startGlyphID="2"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <rect x="100" y="-750" width="800" height="500" rx="100" ry="100"/> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="3" startGlyphID="3"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <circle cx="500" cy="-500" r="400"/> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="4" startGlyphID="4"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <ellipse cx="500" cy="-500" rx="400" ry="200"/> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="5" startGlyphID="5"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <line x1="200" y1="-200" x2="800" y2="-800" stroke="black" stroke-width="20"/> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="6" startGlyphID="6"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <polyline fill="none" stroke="black" stroke-width="20" + points="100, -100, + 300, -100, + 300, -300, + 500, -300, + 500, -500, + 700, -500 + 700, -700 + 900, -700 + 900, -900" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="7" startGlyphID="7"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="500" height="500"> +<polygon points="350, -75 + 379, -161 + 469, -161 + 397, -215 + 423, -301 + 350, -250 + 277, -301 + 303, -215 + 231, -161 + 321, -161" /> +</svg>]]> + </svgDoc> + </SVG> + +</ttFont> diff --git a/test/cairo-svg-test-stroke.ttx b/test/cairo-svg-test-stroke.ttx new file mode 100644 index 000000000..a403da928 --- /dev/null +++ b/test/cairo-svg-test-stroke.ttx @@ -0,0 +1,608 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="4.19"> + + <GlyphOrder> + <!-- The 'id' attribute is only for humans; it is ignored when parsed. --> + <GlyphID id="0" name=".notdef"/> + <GlyphID id="1" name="zero"/> + <GlyphID id="2" name="one"/> + <GlyphID id="3" name="two"/> + <GlyphID id="4" name="three"/> + <GlyphID id="5" name="four"/> + <GlyphID id="6" name="five"/> + <GlyphID id="7" name="six"/> + <GlyphID id="8" name="seven"/> + <GlyphID id="9" name="eight"/> + <GlyphID id="10" name="nine"/> + <GlyphID id="11" name="A"/> + <GlyphID id="12" name="B"/> + <GlyphID id="13" name="C"/> + <GlyphID id="14" name="D"/> + <GlyphID id="15" name="E"/> + <GlyphID id="16" name="F"/> + </GlyphOrder> + + <head> + <!-- Most of this table will be recalculated by the compiler --> + <tableVersion value="1.0"/> + <fontRevision value="1.0"/> + <checkSumAdjustment value="0x2d1b9ede"/> + <magicNumber value="0x5f0f3cf5"/> + <flags value="00000000 00000011"/> + <unitsPerEm value="1000"/> + <created value="Wed Jun 15 00:00:00 2022"/> + <modified value="Fri Jul 1 06:21:39 2022"/> + <xMin value="0"/> + <yMin value="0"/> + <xMax value="1000"/> + <yMax value="1000"/> + <macStyle value="00000000 00000000"/> + <lowestRecPPEM value="6"/> + <fontDirectionHint value="2"/> + <indexToLocFormat value="0"/> + <glyphDataFormat value="0"/> + </head> + + <hhea> + <tableVersion value="0x00010000"/> + <ascent value="1000"/> + <descent value="0"/> + <lineGap value="200"/> + <advanceWidthMax value="1100"/> + <minLeftSideBearing value="0"/> + <minRightSideBearing value="100"/> + <xMaxExtent value="1000"/> + <caretSlopeRise value="1"/> + <caretSlopeRun value="0"/> + <caretOffset value="0"/> + <reserved0 value="0"/> + <reserved1 value="0"/> + <reserved2 value="0"/> + <reserved3 value="0"/> + <metricDataFormat value="0"/> + <numberOfHMetrics value="1"/> + </hhea> + + <maxp> + <!-- Most of this table will be recalculated by the compiler --> + <tableVersion value="0x10000"/> + <numGlyphs value="17"/> + <maxPoints value="4"/> + <maxContours value="1"/> + <maxCompositePoints value="0"/> + <maxCompositeContours value="0"/> + <maxZones value="1"/> + <maxTwilightPoints value="0"/> + <maxStorage value="0"/> + <maxFunctionDefs value="0"/> + <maxInstructionDefs value="0"/> + <maxStackElements value="256"/> + <maxSizeOfInstructions value="1"/> + <maxComponentElements value="0"/> + <maxComponentDepth value="0"/> + </maxp> + + <OS_2> + <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex' + will be recalculated by the compiler --> + <version value="3"/> + <xAvgCharWidth value="1000"/> + <usWeightClass value="400"/> + <usWidthClass value="5"/> + <fsType value="00000000 00000001"/> + <ySubscriptXSize value="600"/> + <ySubscriptYSize value="600"/> + <ySubscriptXOffset value="0"/> + <ySubscriptYOffset value="75"/> + <ySuperscriptXSize value="600"/> + <ySuperscriptYSize value="600"/> + <ySuperscriptXOffset value="0"/> + <ySuperscriptYOffset value="300"/> + <yStrikeoutSize value="0"/> + <yStrikeoutPosition value="300"/> + <sFamilyClass value="0"/> + <panose> + <bFamilyType value="0"/> + <bSerifStyle value="0"/> + <bWeight value="0"/> + <bProportion value="0"/> + <bContrast value="0"/> + <bStrokeVariation value="0"/> + <bArmStyle value="0"/> + <bLetterForm value="0"/> + <bMidline value="0"/> + <bXHeight value="0"/> + </panose> + <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/> + <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/> + <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/> + <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/> + <achVendID value="djr "/> + <fsSelection value="00000000 01000000"/> + <usFirstCharIndex value="48"/> + <usLastCharIndex value="70"/> + <sTypoAscender value="1000"/> + <sTypoDescender value="0"/> + <sTypoLineGap value="200"/> + <usWinAscent value="1000"/> + <usWinDescent value="300"/> + <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/> + <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/> + <sxHeight value="500"/> + <sCapHeight value="720"/> + <usDefaultChar value="0"/> + <usBreakChar value="32"/> + <usMaxContext value="3"/> + </OS_2> + + <hmtx> + <mtx name=".notdef" width="1100" lsb="0"/> + <mtx name="A" width="1100" lsb="0"/> + <mtx name="B" width="1100" lsb="0"/> + <mtx name="C" width="1100" lsb="0"/> + <mtx name="D" width="1100" lsb="0"/> + <mtx name="E" width="1100" lsb="0"/> + <mtx name="F" width="1100" lsb="0"/> + <mtx name="eight" width="1100" lsb="0"/> + <mtx name="five" width="1100" lsb="0"/> + <mtx name="four" width="1100" lsb="0"/> + <mtx name="nine" width="1100" lsb="0"/> + <mtx name="one" width="1100" lsb="0"/> + <mtx name="seven" width="1100" lsb="0"/> + <mtx name="six" width="1100" lsb="0"/> + <mtx name="three" width="1100" lsb="0"/> + <mtx name="two" width="1100" lsb="0"/> + <mtx name="zero" width="1100" lsb="0"/> + </hmtx> + + <cmap> + <tableVersion version="0"/> + <cmap_format_4 platformID="0" platEncID="3" language="0"> + <map code="0x30" name="zero"/><!-- DIGIT ZERO --> + <map code="0x31" name="one"/><!-- DIGIT ONE --> + <map code="0x32" name="two"/><!-- DIGIT TWO --> + <map code="0x33" name="three"/><!-- DIGIT THREE --> + <map code="0x34" name="four"/><!-- DIGIT FOUR --> + <map code="0x35" name="five"/><!-- DIGIT FIVE --> + <map code="0x36" name="six"/><!-- DIGIT SIX --> + <map code="0x37" name="seven"/><!-- DIGIT SEVEN --> + <map code="0x38" name="eight"/><!-- DIGIT EIGHT --> + <map code="0x39" name="nine"/><!-- DIGIT NINE --> + <map code="0x41" name="A"/><!-- LATIN CAPITAL LETTER A --> + <map code="0x42" name="B"/><!-- LATIN CAPITAL LETTER B --> + <map code="0x43" name="C"/><!-- LATIN CAPITAL LETTER C --> + <map code="0x44" name="D"/><!-- LATIN CAPITAL LETTER D --> + <map code="0x45" name="E"/><!-- LATIN CAPITAL LETTER E --> + <map code="0x46" name="F"/><!-- LATIN CAPITAL LETTER F --> + </cmap_format_4> + </cmap> + + <loca> + <!-- The 'loca' table will be calculated by the compiler --> + </loca> + + <glyf> + + <!-- The xMin, yMin, xMax and yMax values + will be recalculated by the compiler. --> + + <TTGlyph name=".notdef"/><!-- contains no outline data --> + + <TTGlyph name="A" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="B" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="C" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="D" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="E" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="F" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="eight" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="five" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="four" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="nine" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="one" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="seven" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="six" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="three" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="two" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="zero" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + </glyf> + + <name> + <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409"> + Cairo Svg Test Stroke + </namerecord> + <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409"> + Regular + </namerecord> + <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409"> + Cairo Svg Test Stroke Regular + </namerecord> + </name> + + <post> + <formatType value="3.0"/> + <italicAngle value="0.0"/> + <underlinePosition value="0"/> + <underlineThickness value="0"/> + <isFixedPitch value="0"/> + <minMemType42 value="0"/> + <maxMemType42 value="0"/> + <minMemType1 value="0"/> + <maxMemType1 value="0"/> + </post> + + <CPAL> + <version value="0"/> + <numPaletteEntries value="2"/> + <palette index="0"> + <color index="0" value="#C5A1D7FF"/> + <color index="1" value="#80DFC8FF"/> + </palette> + <palette index="1"> + <color index="0" value="#6392A9FF"/> + <color index="1" value="#7896B3FF"/> + </palette> + </CPAL> + + <SVG> + + <svgDoc endGlyphID="0" startGlyphID="0"> + <![CDATA[<svg xmlns="http://www.w3.org/2000/svg"></svg>]]> + </svgDoc> + <svgDoc endGlyphID="1" startGlyphID="1"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <line x1="100" y1="-500" x2="900" y2="-500" + fill="none" + stroke-width="100" + stroke="indigo" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="2" startGlyphID="2"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <line x1="100" y1="-500" x2="900" y2="-500" + fill="none" + stroke-width="100" + stroke="#AA55AA" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="3" startGlyphID="3"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <line x1="100" y1="-500" x2="900" y2="-500" + fill="none" + stroke-width="100" + stroke="#A5A" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="4" startGlyphID="4"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <line x1="100" y1="-500" x2="900" y2="-500" + fill="none" + stroke-width="100" + stroke="rgb(75,0,130)" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="5" startGlyphID="5"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <line x1="100" y1="-500" x2="900" y2="-500" + fill="none" + stroke-width="100" + stroke="currentColor" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="6" startGlyphID="6"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <line x1="100" y1="-500" x2="900" y2="-500" + fill="none" + stroke-width="100" + stroke="var(--color1, red)" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="7" startGlyphID="7"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <line x1="100" y1="-500" x2="900" y2="-500" + fill="none" + stroke-width="100" + stroke="magenta" stroke-opacity="0.5" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="8" startGlyphID="8"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + color="green" > + <line x1="100" y1="-500" x2="900" y2="-500" + fill="none" + stroke-width="100" + stroke="currentColor" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="9" startGlyphID="9"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <line x1="100" y1="-900" x2="900" y2="-900" + fill="none" + stroke-width="100" + stroke="black" /> + <line x1="100" y1="-500" x2="900" y2="-500" + fill="none" + stroke-width="200" + stroke="black" /> + <line x1="100" y1="-100" x2="900" y2="-100" + fill="none" + stroke-width="300" + stroke="black" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="10" startGlyphID="10"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <line x1="100" y1="-900" x2="900" y2="-900" + fill="none" + stroke-width="200" + stroke-linecap="butt" + stroke="black" /> + <line x1="100" y1="-500" x2="900" y2="-500" + fill="none" + stroke-width="200" + stroke-linecap="round" + stroke="black" /> + <line x1="100" y1="-100" x2="900" y2="-100" + fill="none" + stroke-width="200" + stroke-linecap="square" + stroke="black" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="11" startGlyphID="11"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <line x1="100" y1="-950" x2="900" y2="-950" + fill="none" + stroke-width="100" + stroke-dasharray="none" + stroke="black" /> + <line x1="100" y1="-750" x2="900" y2="-750" + fill="none" + stroke-width="100" + stroke-dasharray="200" + stroke="black" /> + <line x1="100" y1="-550" x2="900" y2="-550" + fill="none" + stroke-width="100" + stroke-dasharray="200 50" + stroke="black" /> + <line x1="100" y1="-350" x2="900" y2="-350" + fill="none" + stroke-width="100" + stroke-dasharray="200 50 100" + stroke="black" /> + <line x1="100" y1="-150" x2="900" y2="-150" + fill="none" + stroke-width="100" + stroke-dasharray="200 50 100 150" + stroke="black" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="12" startGlyphID="12"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <line x1="100" y1="-950" x2="900" y2="-950" + fill="none" + stroke-width="100" + stroke-dasharray="none" + stroke="black" /> + <line x1="100" y1="-750" x2="900" y2="-750" + fill="none" + stroke-width="100" + stroke-dasharray="200" + stroke-dashoffset="100" + stroke="black" /> + <line x1="100" y1="-550" x2="900" y2="-550" + fill="none" + stroke-width="100" + stroke-dasharray="200 50" + stroke-dashoffset="100" + stroke="black" /> + <line x1="100" y1="-350" x2="900" y2="-350" + fill="none" + stroke-width="100" + stroke-dasharray="200 50 100" + stroke-dashoffset="100" + stroke="black" /> + <line x1="100" y1="-150" x2="900" y2="-150" + fill="none" + stroke-width="100" + stroke-dasharray="200 50 100 150" + stroke-dashoffset="100" + stroke="black" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="13" startGlyphID="13"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <polyline + points="100, -200 + 900, -400 + 100, -700" + fill="none" + stroke-width="200" + stroke-linejoin="miter" + stroke="black" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="14" startGlyphID="14"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <polyline + points="100, -200 + 900, -400 + 100, -700" + fill="none" + stroke-width="200" + stroke-linejoin="round" + stroke="black" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="15" startGlyphID="15"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <polyline + points="100, -200 + 900, -400 + 100, -700" + fill="none" + stroke-width="200" + stroke-linejoin="bevel" + stroke="black" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="16" startGlyphID="16"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <polyline + points="100, -200 + 900, -400 + 100, -700" + fill="none" + stroke-width="200" + stroke-linejoin="miter" + stroke-miterlimit="2" + stroke="black" /> +</svg>]]> + </svgDoc> + </SVG> + +</ttFont> diff --git a/test/cairo-svg-test-transform.ttx b/test/cairo-svg-test-transform.ttx new file mode 100644 index 000000000..1f07c05ad --- /dev/null +++ b/test/cairo-svg-test-transform.ttx @@ -0,0 +1,403 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="4.19"> + + <GlyphOrder> + <!-- The 'id' attribute is only for humans; it is ignored when parsed. --> + <GlyphID id="0" name=".notdef"/> + <GlyphID id="1" name="zero"/> + <GlyphID id="2" name="one"/> + <GlyphID id="3" name="two"/> + <GlyphID id="4" name="three"/> + <GlyphID id="5" name="four"/> + <GlyphID id="6" name="five"/> + <GlyphID id="7" name="six"/> + <GlyphID id="8" name="seven"/> + </GlyphOrder> + + <head> + <!-- Most of this table will be recalculated by the compiler --> + <tableVersion value="1.0"/> + <fontRevision value="1.0"/> + <checkSumAdjustment value="0x970fff1"/> + <magicNumber value="0x5f0f3cf5"/> + <flags value="00000000 00000011"/> + <unitsPerEm value="1000"/> + <created value="Wed Jun 15 00:00:00 2022"/> + <modified value="Fri Jul 1 06:21:39 2022"/> + <xMin value="0"/> + <yMin value="0"/> + <xMax value="1000"/> + <yMax value="1000"/> + <macStyle value="00000000 00000000"/> + <lowestRecPPEM value="6"/> + <fontDirectionHint value="2"/> + <indexToLocFormat value="0"/> + <glyphDataFormat value="0"/> + </head> + + <hhea> + <tableVersion value="0x00010000"/> + <ascent value="1000"/> + <descent value="0"/> + <lineGap value="200"/> + <advanceWidthMax value="1100"/> + <minLeftSideBearing value="0"/> + <minRightSideBearing value="100"/> + <xMaxExtent value="1000"/> + <caretSlopeRise value="1"/> + <caretSlopeRun value="0"/> + <caretOffset value="0"/> + <reserved0 value="0"/> + <reserved1 value="0"/> + <reserved2 value="0"/> + <reserved3 value="0"/> + <metricDataFormat value="0"/> + <numberOfHMetrics value="1"/> + </hhea> + + <maxp> + <!-- Most of this table will be recalculated by the compiler --> + <tableVersion value="0x10000"/> + <numGlyphs value="9"/> + <maxPoints value="4"/> + <maxContours value="1"/> + <maxCompositePoints value="0"/> + <maxCompositeContours value="0"/> + <maxZones value="1"/> + <maxTwilightPoints value="0"/> + <maxStorage value="0"/> + <maxFunctionDefs value="0"/> + <maxInstructionDefs value="0"/> + <maxStackElements value="256"/> + <maxSizeOfInstructions value="1"/> + <maxComponentElements value="0"/> + <maxComponentDepth value="0"/> + </maxp> + + <OS_2> + <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex' + will be recalculated by the compiler --> + <version value="3"/> + <xAvgCharWidth value="1000"/> + <usWeightClass value="400"/> + <usWidthClass value="5"/> + <fsType value="00000000 00000001"/> + <ySubscriptXSize value="600"/> + <ySubscriptYSize value="600"/> + <ySubscriptXOffset value="0"/> + <ySubscriptYOffset value="75"/> + <ySuperscriptXSize value="600"/> + <ySuperscriptYSize value="600"/> + <ySuperscriptXOffset value="0"/> + <ySuperscriptYOffset value="300"/> + <yStrikeoutSize value="0"/> + <yStrikeoutPosition value="300"/> + <sFamilyClass value="0"/> + <panose> + <bFamilyType value="0"/> + <bSerifStyle value="0"/> + <bWeight value="0"/> + <bProportion value="0"/> + <bContrast value="0"/> + <bStrokeVariation value="0"/> + <bArmStyle value="0"/> + <bLetterForm value="0"/> + <bMidline value="0"/> + <bXHeight value="0"/> + </panose> + <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/> + <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/> + <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/> + <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/> + <achVendID value="djr "/> + <fsSelection value="00000000 01000000"/> + <usFirstCharIndex value="48"/> + <usLastCharIndex value="55"/> + <sTypoAscender value="1000"/> + <sTypoDescender value="0"/> + <sTypoLineGap value="200"/> + <usWinAscent value="1000"/> + <usWinDescent value="300"/> + <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/> + <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/> + <sxHeight value="500"/> + <sCapHeight value="720"/> + <usDefaultChar value="0"/> + <usBreakChar value="32"/> + <usMaxContext value="3"/> + </OS_2> + + <hmtx> + <mtx name=".notdef" width="1100" lsb="0"/> + <mtx name="five" width="1100" lsb="0"/> + <mtx name="four" width="1100" lsb="0"/> + <mtx name="one" width="1100" lsb="0"/> + <mtx name="seven" width="1100" lsb="0"/> + <mtx name="six" width="1100" lsb="0"/> + <mtx name="three" width="1100" lsb="0"/> + <mtx name="two" width="1100" lsb="0"/> + <mtx name="zero" width="1100" lsb="0"/> + </hmtx> + + <cmap> + <tableVersion version="0"/> + <cmap_format_4 platformID="0" platEncID="3" language="0"> + <map code="0x30" name="zero"/><!-- DIGIT ZERO --> + <map code="0x31" name="one"/><!-- DIGIT ONE --> + <map code="0x32" name="two"/><!-- DIGIT TWO --> + <map code="0x33" name="three"/><!-- DIGIT THREE --> + <map code="0x34" name="four"/><!-- DIGIT FOUR --> + <map code="0x35" name="five"/><!-- DIGIT FIVE --> + <map code="0x36" name="six"/><!-- DIGIT SIX --> + <map code="0x37" name="seven"/><!-- DIGIT SEVEN --> + </cmap_format_4> + </cmap> + + <loca> + <!-- The 'loca' table will be calculated by the compiler --> + </loca> + + <glyf> + + <!-- The xMin, yMin, xMax and yMax values + will be recalculated by the compiler. --> + + <TTGlyph name=".notdef"/><!-- contains no outline data --> + + <TTGlyph name="five" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="four" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="one" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="seven" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="six" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="three" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="two" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + <TTGlyph name="zero" xMin="0" yMin="0" xMax="1000" yMax="1000"> + <contour> + <pt x="0" y="0" on="1"/> + <pt x="0" y="1000" on="1"/> + <pt x="1000" y="1000" on="1"/> + <pt x="1000" y="0" on="1"/> + </contour> + <instructions/> + </TTGlyph> + + </glyf> + + <name> + <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409"> + Cairo Svg Test Transform + </namerecord> + <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409"> + Regular + </namerecord> + <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409"> + Cairo Svg Test Transform Regular + </namerecord> + </name> + + <post> + <formatType value="3.0"/> + <italicAngle value="0.0"/> + <underlinePosition value="0"/> + <underlineThickness value="0"/> + <isFixedPitch value="0"/> + <minMemType42 value="0"/> + <maxMemType42 value="0"/> + <minMemType1 value="0"/> + <maxMemType1 value="0"/> + </post> + + <CPAL> + <version value="0"/> + <numPaletteEntries value="2"/> + <palette index="0"> + <color index="0" value="#C5A1D7FF"/> + <color index="1" value="#80DFC8FF"/> + </palette> + <palette index="1"> + <color index="0" value="#6392A9FF"/> + <color index="1" value="#7896B3FF"/> + </palette> + </CPAL> + + <SVG> + + <svgDoc endGlyphID="0" startGlyphID="0"> + <![CDATA[<svg xmlns="http://www.w3.org/2000/svg"></svg>]]> + </svgDoc> + <svgDoc endGlyphID="1" startGlyphID="1"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <rect id="square" width="300" height="300"/> + </defs> + <use xlink:href="#square" transform="translate(100, -900)"/> + <use xlink:href="#square" transform="translate(600, -400)"/> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="2" startGlyphID="2"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <rect id="square" width="300" height="300"/> + </defs> + <use xlink:href="#square" transform="translate(100, -900)"/> + <g transform="translate(400, -400)"> + <use xlink:href="#square" transform="scale(1.5, 0.5)"/> + </g> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="3" startGlyphID="3"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <rect id="square" width="300" height="300"/> + </defs> + <use xlink:href="#square" transform="translate(100, -900)"/> + <g transform="translate(600, -600)"> + <use xlink:href="#square" transform="rotate(30)"/> + </g> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="4" startGlyphID="4"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <rect id="square" width="300" height="300"/> + </defs> + <use xlink:href="#square" transform="translate(100, -900)"/> + <g transform="translate(400, -400)"> + <use xlink:href="#square" transform="skewX(30)"/> + </g> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="5" startGlyphID="5"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <rect id="square" width="300" height="300"/> + </defs> + <use xlink:href="#square" transform="translate(100, -900)"/> + <g transform="translate(400, -500)"> + <use xlink:href="#square" transform="skewY(30)"/> + </g> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="6" startGlyphID="6"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <rect id="square" width="300" height="300"/> + </defs> + <use xlink:href="#square" transform="translate(100, -900)"/> + <g transform="translate(600, -600)"> + <use xlink:href="#square" transform="matrix(1, 0.4, -0.6, 1.1, 50, -70)"/> + </g> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="7" startGlyphID="7"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <path id="heart" d="M 10,30 A 20,20 0,0,1 50,30 A 20,20 0,0,1 90,30 Q 90,60 50,90 Q 10,60 10,30 z" /> + </defs> + <use xlink:href="#heart" + transform="translate(10, -650) + rotate(-10 50 100) + translate(-166 125.5) + skewX(40) + scale(1 0.5),scale(8, 8)" + fill="grey"/> + <use xlink:href="#heart" + transform="translate(300, -800),scale(6, 6)" + fill="none" stroke="red" /> +</svg>]]> + </svgDoc> + <svgDoc endGlyphID="8" startGlyphID="8"> + <![CDATA[<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <circle id="c1" + cx="100" cy="100" r="80" + fill="none" + stroke="black" + stroke-width="20" /> + <circle id="c2" + cx="100" cy="100" r="80" + fill="none" + stroke="black" + stroke-width="20" + transform="scale(3,3)" /> + </defs> + + <use xlink:href="#c1" x="100" y="-900"/> + <use xlink:href="#c2" x="300" y="-700"/> + +</svg>]]> + </svgDoc> + </SVG> + +</ttFont> diff --git a/test/ft-svg-render.c b/test/ft-svg-render.c new file mode 100644 index 000000000..9b0351b10 --- /dev/null +++ b/test/ft-svg-render.c @@ -0,0 +1,159 @@ +/* + * Copyright © 2022 Adrian Johnson + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Author: Adrian Johnson <ajohnson@redneon.com> + */ + +#include "cairo-test.h" +#include <cairo-ft.h> + +#define GLYPH_SIZE 50 +#define PAD 5 +#define WIDTH (4*(GLYPH_SIZE + PAD) + PAD) +#define HEIGHT WIDTH + +//#define CLIP 1 +#define LOG_EXTENTS 1 + +static cairo_test_status_t +draw_font (cairo_t *cr, int width, int height, const char *font_file) +{ + cairo_test_status_t result; + char buf[10]; + cairo_text_extents_t extents; + cairo_font_options_t *font_options; + + cairo_set_source_rgb (cr, 1, 1, 1); + cairo_paint (cr); + cairo_set_source_rgb (cr, 0, 0, 0); + + result = cairo_test_ft_select_font_from_file (cr, font_file); + if (result) + return result; + + font_options = cairo_font_options_create (); + cairo_font_options_set_color_mode (font_options, CAIRO_COLOR_MODE_NO_COLOR); +// cairo_set_font_options (cr, font_options); + cairo_font_options_destroy (font_options); + + cairo_set_font_size (cr, GLYPH_SIZE); + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + int x = j * (GLYPH_SIZE + PAD) + PAD; + int y = i * (GLYPH_SIZE + PAD) + PAD; + int glyph_number = 4*i + j; + buf[0] = glyph_number < 10 ? '0' + glyph_number : 'A' + glyph_number - 10; + buf[1] = 0; + cairo_save (cr); + cairo_text_extents (cr, buf, &extents); +#if LOG_EXTENTS + cairo_test_log (cairo_test_get_context (cr), + "Char '%c' extents: x_bearing: %f y_bearing: %f width: %f height: %f x_advance: %f y_advance: %f\n", + buf[0], + extents.x_bearing, + extents.y_bearing, + extents.width, + extents.height, + extents.x_advance, + extents.y_advance); +#endif +#if CLIP + cairo_rectangle (cr, x, y, GLYPH_SIZE, GLYPH_SIZE); + cairo_clip (cr); +#endif + cairo_move_to (cr, x, y + GLYPH_SIZE); + cairo_show_text (cr, buf); + cairo_restore (cr); + if (cairo_status (cr)) { + cairo_test_log (cairo_test_get_context (cr), + "cairo_show_text() failed with \"%s\"\n", + buf); + return CAIRO_TEST_FAILURE; + } + } + } + + return CAIRO_TEST_SUCCESS; +} + +#define DRAW_FUNC(name) \ +static cairo_test_status_t \ +draw_##name (cairo_t *cr, int width, int height) { \ + return draw_font (cr, width, height, "cairo-svg-test-" #name ".ttf"); \ +} + +DRAW_FUNC(doc) +CAIRO_TEST (ft_svg_render_doc, + "Test SVG glyph render", + "svgrender", /* keywords */ + NULL, /* requirements */ + WIDTH, HEIGHT, + NULL, draw_doc) + +DRAW_FUNC(fill) +CAIRO_TEST (ft_svg_render_fill, + "Test SVG glyph render", + "svgrender", /* keywords */ + NULL, /* requirements */ + WIDTH, HEIGHT, + NULL, draw_fill) + +DRAW_FUNC(gradient) +CAIRO_TEST (ft_svg_render_gradient, + "Test SVG glyph render", + "svgrender", /* keywords */ + NULL, /* requirements */ + WIDTH, HEIGHT, + NULL, draw_gradient) + +DRAW_FUNC(path) +CAIRO_TEST (ft_svg_render_path, + "Test SVG glyph render", + "svgrender", /* keywords */ + NULL, /* requirements */ + WIDTH, HEIGHT, + NULL, draw_path) + +DRAW_FUNC(shapes) +CAIRO_TEST (ft_svg_render_shapes, + "Test SVG glyph render", + "svgrender", /* keywords */ + NULL, /* requirements */ + WIDTH, HEIGHT, + NULL, draw_shapes) + +DRAW_FUNC(stroke) +CAIRO_TEST (ft_svg_render_stroke, + "Test SVG glyph render", + "svgrender", /* keywords */ + NULL, /* requirements */ + WIDTH, HEIGHT, + NULL, draw_stroke) + +DRAW_FUNC(transform) +CAIRO_TEST (ft_svg_render_transform, + "Test SVG glyph render", + "svgrender", /* keywords */ + NULL, /* requirements */ + WIDTH, HEIGHT, + NULL, draw_transform) diff --git a/test/meson.build b/test/meson.build index 3071ac6ca..3606bfc27 100644 --- a/test/meson.build +++ b/test/meson.build @@ -431,6 +431,7 @@ test_ft_svg_font_sources = [ test_ft_svg_ttx_font_sources = [ 'ft-svg-cairo-logo.c', + 'ft-svg-render.c' ] test_gl_sources = [ @@ -525,6 +526,13 @@ ps2png_sources = [ test_ttx_fonts = [ 'cairo-logo-font.ttx', + 'cairo-svg-test-doc.ttx', + 'cairo-svg-test-fill.ttx', + 'cairo-svg-test-gradient.ttx', + 'cairo-svg-test-path.ttx', + 'cairo-svg-test-shapes.ttx', + 'cairo-svg-test-stroke.ttx', + 'cairo-svg-test-transform.ttx', ] build_any2ppm = false @@ -681,3 +689,9 @@ test('cairo', exe, suite: ['cairo-test-suite', 'slow'], workdir: meson.current_build_dir(), depends: test_depends) + +# The SVG renderer debug tools can only be built if the _cairo_debug_svg_render() +# function has been exposed by defining DEBUG_SVG_RENDER +if conf.get('HAVE_FT_SVG_DOCUMENT', 0) == 1 and cc.get_define('DEBUG_SVG_RENDER') != '' + subdir('svg') +endif diff --git a/test/reference/ft-svg-render-doc.ref.png b/test/reference/ft-svg-render-doc.ref.png Binary files differnew file mode 100644 index 000000000..e7ecf7f1a --- /dev/null +++ b/test/reference/ft-svg-render-doc.ref.png diff --git a/test/reference/ft-svg-render-fill.ref.png b/test/reference/ft-svg-render-fill.ref.png Binary files differnew file mode 100644 index 000000000..a72cdd1f2 --- /dev/null +++ b/test/reference/ft-svg-render-fill.ref.png diff --git a/test/reference/ft-svg-render-gradient.ref.png b/test/reference/ft-svg-render-gradient.ref.png Binary files differnew file mode 100644 index 000000000..d647dc06a --- /dev/null +++ b/test/reference/ft-svg-render-gradient.ref.png diff --git a/test/reference/ft-svg-render-path.ref.png b/test/reference/ft-svg-render-path.ref.png Binary files differnew file mode 100644 index 000000000..2667059cc --- /dev/null +++ b/test/reference/ft-svg-render-path.ref.png diff --git a/test/reference/ft-svg-render-shapes.ref.png b/test/reference/ft-svg-render-shapes.ref.png Binary files differnew file mode 100644 index 000000000..209e0ddb3 --- /dev/null +++ b/test/reference/ft-svg-render-shapes.ref.png diff --git a/test/reference/ft-svg-render-stroke.ref.png b/test/reference/ft-svg-render-stroke.ref.png Binary files differnew file mode 100644 index 000000000..86f1ab9b6 --- /dev/null +++ b/test/reference/ft-svg-render-stroke.ref.png diff --git a/test/reference/ft-svg-render-transform.ref.png b/test/reference/ft-svg-render-transform.ref.png Binary files differnew file mode 100644 index 000000000..dcc372aac --- /dev/null +++ b/test/reference/ft-svg-render-transform.ref.png diff --git a/test/svg/README b/test/svg/README new file mode 100644 index 000000000..c4504dc9b --- /dev/null +++ b/test/svg/README @@ -0,0 +1,22 @@ +build_ttx_fonts.py +================== +Is used to create the test/*.ttx files used for testing the SVG glyph renderer. + +build_ttx_fonts.py will look for files of the form + +<font-name>.<char>.<test-name>.svg + +in the input directory, and using svg-font-template.ttx, create <font-name>.ttx +files that contain one glyph for each svg file. Each <font-name>.ttx will contain +a glyph for each svg with the matching <font-name> prefix. Each glyphs will be mapped +to the <char> i nthe svg filename. The <char> must be one of 0-9,A-F. + +svg-render.c +============ +svg-render renders SVG files using both librsvg and cairo-svg-glyph-render.c. +It is used for testing cairo-svg-glyph-render.c during development. + +To use svg-render, cairo must be built with CFLAGS="-DDEBUG_SVG_RENDER" to enable the +_cairo_debug_svg_render() function. + + diff --git a/test/svg/build_ttx_fonts.py b/test/svg/build_ttx_fonts.py new file mode 100755 index 000000000..d7e7f5b8f --- /dev/null +++ b/test/svg/build_ttx_fonts.py @@ -0,0 +1,161 @@ +#!/usr/bin/env python3 + +# Build the ttx cairo svg test fonts from svg files +# The svg files use the naming convention +# <font-name>.<char>.<test-name>.svg +# eg "circle.A.cx_cy_r.svg" +# +# <font-name> is use to create the name of the ttx font. +# <char> is a ascii hex character (uppercase) that the font fill map to the SVG description. +# <test-name> is a descriptive name of the SVG file and is not used to build the font… +# +# This script looks for all files matching the above pattern and +# creates one ttx font for each unique <font-name>. Each font will +# contain up to 16 characters. The SVG description of each character +# and the character that maps to the SVG description is obtained from +# the SVG file beginning with <font-name>.<char>. + +import argparse +import os +import re +import sys +import xml.dom.minidom + +TEMPLATE_FILE="svg-font-template.ttx" + +glyph_names = { + '0': 'zero', + '1': 'one', + '2': 'two', + '3': 'three', + '4': 'four', + '5': 'five', + '6': 'six', + '7': 'seven', + '8': 'eight', + '9': 'nine', + 'A': 'A', + 'B': 'B', + 'C': 'C', + 'D': 'D', + 'E': 'E', + 'F': 'F' +} + +# files is list of (char, filename) +def build_font(font_name, files, in_dir, out_dir, no_reformat): + name = "cairo-svg-test-" + font_name + doc = xml.dom.minidom.parse(os.path.join(in_dir, TEMPLATE_FILE)) + glyph_id = 1 + text_nl = doc.createTextNode('\n\n') + for f in sorted(files): + glyph_name = glyph_names[f[0]] + + glyph_order = doc.getElementsByTagName('GlyphOrder')[0] + glyph_id_elem = doc.createElement('GlyphID') + glyph_id_elem.setAttribute('id', str(glyph_id)) + glyph_id_elem.setAttribute('name', glyph_name) + glyph_order.appendChild(glyph_id_elem) + glyph_order.appendChild(text_nl) + + hmtx = doc.getElementsByTagName('hmtx')[0] + mtx = doc.createElement('mtx') + mtx.setAttribute('name', glyph_name) + mtx.setAttribute('width', '1100') + mtx.setAttribute('lsb', '0') + hmtx.appendChild(mtx) + + cmap_format = doc.getElementsByTagName('cmap_format_4')[0] + map = doc.createElement('map') + map.setAttribute('code', hex(ord(f[0]))) + map.setAttribute('name', glyph_name) + cmap_format.appendChild(map) + + glyf = doc.getElementsByTagName('glyf')[0] + tt_glyph = doc.createElement('TTGlyph') + tt_glyph.setAttribute('name', glyph_name) + glyf.appendChild(tt_glyph) + contour = doc.createElement('contour') + tt_glyph.appendChild(contour) + pt = doc.createElement('pt') + pt.setAttribute('x', "0") + pt.setAttribute('y', "0") + pt.setAttribute('on', "1") + contour.appendChild(pt) + pt = doc.createElement('pt') + pt.setAttribute('x', "0") + pt.setAttribute('y', "1000") + pt.setAttribute('on', "1") + contour.appendChild(pt) + pt = doc.createElement('pt') + pt.setAttribute('x', "1000") + pt.setAttribute('y', "1000") + pt.setAttribute('on', "1") + contour.appendChild(pt) + pt = doc.createElement('pt') + pt.setAttribute('x', "1000") + pt.setAttribute('y', "0") + pt.setAttribute('on', "1") + contour.appendChild(pt) + instructions = doc.createElement('instructions') + tt_glyph.appendChild(instructions) + + svg = doc.getElementsByTagName('SVG')[0] + svgdoc = doc.createElement('svgDoc') + svgdoc.setAttribute('startGlyphID', str(glyph_id)) + svgdoc.setAttribute('endGlyphID', str(glyph_id)) + with open(os.path.join(in_dir, f[1]), 'r') as svg_file: + svg_data = svg_file.read() + cdata = doc.createCDATASection(svg_data) + svgdoc.appendChild(cdata) + svg.appendChild(svgdoc) + glyph_id += 1 + + name_record = doc.getElementsByTagName('namerecord')[0] + name_record.firstChild.replaceWholeText(name.replace("-", " ").title()) + name_record = doc.getElementsByTagName('namerecord')[2] + name_record.firstChild.replaceWholeText(name.replace("-", " ").title() + " Regular") + + ttx_filename = os.path.join(out_dir, name + '.ttx') + ttf_filename = os.path.join(out_dir, name + '.ttf') + with open(ttx_filename, 'w') as ttx_file: + doc.writexml(ttx_file) + + if not no_reformat: + # Convert to ttf and back to ttx. This reformats the ttx file + # which allows better quality diffs. + if os.path.exists(ttf_filename): + os.remove(ttf_filename) + os.system("ttx " + ttx_filename) + os.remove(ttx_filename) + os.system("ttx " + ttf_filename) + os.remove(ttf_filename) + +def build_file_list(in_dir): + dict = {} + regex_prog = re.compile(r"([^\.]+)\.(.)\.[^\.]+\.svg", re.ASCII) + files = os.listdir(in_dir) + for f in files: + match = regex_prog.fullmatch(f) + if match: + fontname = match.group(1) + character = match.group(2) + if (fontname not in dict): + dict[fontname] = [(character, f)]; + else: + dict[fontname].append((character, f)) + return dict + +if __name__=='__main__': + parser = argparse.ArgumentParser(description='Build ttx fonts.') + parser.add_argument("-i", nargs=1, metavar="indir", default=["."], help="Input directory") + parser.add_argument("-o", nargs=1, metavar="outdir", default=["."], help="Output directory") + parser.add_argument("-n", action='store_true', help="Don't reformat the output.") + args = parser.parse_args() + in_dir = args.i[0] + out_dir = args.o[0] + no_reformat = args.n + file_list = build_file_list(in_dir) + font_name = None + for key, value in file_list.items(): + build_font(key, value, in_dir, out_dir, no_reformat) diff --git a/test/svg/doc.0.viewBox1.svg b/test/svg/doc.0.viewBox1.svg new file mode 100644 index 000000000..c1f55a4eb --- /dev/null +++ b/test/svg/doc.0.viewBox1.svg @@ -0,0 +1,4 @@ +<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"> + <rect x="10" y="-90" width="80" height="80" + fill="none" stroke="black" stroke-width="10"/> +</svg> diff --git a/test/svg/doc.1.viewBox2.svg b/test/svg/doc.1.viewBox2.svg new file mode 100644 index 000000000..b8f976ba9 --- /dev/null +++ b/test/svg/doc.1.viewBox2.svg @@ -0,0 +1,4 @@ +<svg viewBox="-5 -5 10 10" xmlns="http://www.w3.org/2000/svg"> + <rect x="-4" y="-14" width="8" height="8" + fill="none" stroke="black" stroke-width="1"/> +</svg> diff --git a/test/svg/doc.2.image.svg b/test/svg/doc.2.image.svg new file mode 100644 index 000000000..1d03842a9 --- /dev/null +++ b/test/svg/doc.2.image.svg @@ -0,0 +1,121 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <image x="0" y="-1000" width="1000" height="1000" + xlink:href="data:image/png;base64, +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 +BNcsrHnv+f9Qc51Rfhz5VAAAAABJRU5ErkJggg=="/> +</svg> diff --git a/test/svg/doc.3.image-transform.svg b/test/svg/doc.3.image-transform.svg new file mode 100644 index 000000000..90e5ecb1a --- /dev/null +++ b/test/svg/doc.3.image-transform.svg @@ -0,0 +1,122 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <image x="0" y="-1000" width="1000" height="1000" + transform="scale(0.5) rotate(-45),translate(800,500)" + xlink:href="data:image/png;base64, +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 +BNcsrHnv+f9Qc51Rfhz5VAAAAABJRU5ErkJggg=="/> +</svg> diff --git a/test/svg/doc.4.clip-user.svg b/test/svg/doc.4.clip-user.svg new file mode 100644 index 000000000..26cdd818a --- /dev/null +++ b/test/svg/doc.4.clip-user.svg @@ -0,0 +1,9 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="1000" height="1000"> + <clipPath id="clip" clipPathUnits="userSpaceOnUse" > + <circle cx="500" cy="-500" r="400" /> + </clipPath> + + <rect x="100" y="-900" width="800" height="800" + stroke="green" stroke-width="100" + clip-path="url(#clip)" /> +</svg> diff --git a/test/svg/doc.5.clip-object.svg b/test/svg/doc.5.clip-object.svg new file mode 100644 index 000000000..732911590 --- /dev/null +++ b/test/svg/doc.5.clip-object.svg @@ -0,0 +1,10 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="1000" height="1000"> + <clipPath id="clip" clipPathUnits="objectBoundingBox"> + <circle cx=".5" cy=".5" r=".5" /> + </clipPath> + + <rect x="100" y="-900" width="800" height="800" + stroke="green" stroke-width="100" + clip-path="url(#clip)" /> + +</svg> diff --git a/test/svg/doc.6.clip-user2.svg b/test/svg/doc.6.clip-user2.svg new file mode 100644 index 000000000..a68c1c42f --- /dev/null +++ b/test/svg/doc.6.clip-user2.svg @@ -0,0 +1,10 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="1000" height="1000"> + <clipPath id="clip" clipPathUnits="userSpaceOnUse" > + <circle cx="500" cy="-500" r="400" /> + <rect x="100" y="-900" width="800" height="400"/> + </clipPath> + + <rect x="100" y="-900" width="800" height="800" + stroke="green" stroke-width="100" + clip-path="url(#clip)" /> +</svg> diff --git a/test/svg/doc.7.clip-object2.svg b/test/svg/doc.7.clip-object2.svg new file mode 100644 index 000000000..f5c153dd1 --- /dev/null +++ b/test/svg/doc.7.clip-object2.svg @@ -0,0 +1,11 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="1000" height="1000"> + <clipPath id="clip" clipPathUnits="objectBoundingBox"> + <circle cx=".5" cy=".5" r=".5" /> + <rect x="0" y="0" width="1" height="0.5"/> + </clipPath> + + <rect x="100" y="-900" width="800" height="800" + stroke="green" stroke-width="100" + clip-path="url(#clip)" /> + +</svg> diff --git a/test/svg/doc.8.clip-user3.svg b/test/svg/doc.8.clip-user3.svg new file mode 100644 index 000000000..8ff61d593 --- /dev/null +++ b/test/svg/doc.8.clip-user3.svg @@ -0,0 +1,15 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="1000" height="1000"> + <clipPath id="clip" clipPathUnits="userSpaceOnUse" > + <circle cx="500" cy="-500" r="400" /> + </clipPath> + + <clipPath id="clip2" clipPathUnits="userSpaceOnUse" > + <rect x="100" y="-900" width="800" height="400"/> + </clipPath> + + <g clip-path="url(#clip)"> + <rect x="100" y="-900" width="800" height="800" + stroke="green" stroke-width="100" + clip-path="url(#clip2)" /> + </g> +</svg> diff --git a/test/svg/doc.9.clip-object3.svg b/test/svg/doc.9.clip-object3.svg new file mode 100644 index 000000000..b291df79f --- /dev/null +++ b/test/svg/doc.9.clip-object3.svg @@ -0,0 +1,15 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="1000" height="1000"> + <clipPath id="clip" clipPathUnits="objectBoundingBox"> + <circle cx=".5" cy=".5" r=".5" /> + </clipPath> + + <clipPath id="clip2" clipPathUnits="objectBoundingBox"> + <rect x="0" y="0" width="1" height="0.5"/> + </clipPath> + + <g clip-path="url(#clip)"> + <rect x="100" y="-900" width="800" height="800" + stroke="green" stroke-width="100" + clip-path="url(#clip2)" /> + </g> +</svg> diff --git a/test/svg/doc.A.g.svg b/test/svg/doc.A.g.svg new file mode 100644 index 000000000..bdaade725 --- /dev/null +++ b/test/svg/doc.A.g.svg @@ -0,0 +1,14 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" > + <defs> + <circle id="circle" + cx="0" cy="0" r="250" /> + </defs> + + <g opacity="0.5"> + <use xlink:href="#circle" x="330" y="-500" + fill="red" /> + <use xlink:href="#circle" x="670" y="-500" + fill="green" /> + </g> +</svg> diff --git a/test/svg/fill.0.name.svg b/test/svg/fill.0.name.svg new file mode 100644 index 000000000..e377b8827 --- /dev/null +++ b/test/svg/fill.0.name.svg @@ -0,0 +1,4 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <rect x="100" y="-750" width="800" height="500" + fill="indigo" /> +</svg> diff --git a/test/svg/fill.1.hex6.svg b/test/svg/fill.1.hex6.svg new file mode 100644 index 000000000..04759d78a --- /dev/null +++ b/test/svg/fill.1.hex6.svg @@ -0,0 +1,4 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <rect x="100" y="-750" width="800" height="500" + fill="#AA55AA" /> +</svg> diff --git a/test/svg/fill.2.hex3.svg b/test/svg/fill.2.hex3.svg new file mode 100644 index 000000000..9f9bce580 --- /dev/null +++ b/test/svg/fill.2.hex3.svg @@ -0,0 +1,4 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <rect x="100" y="-750" width="800" height="500" + fill="#A5A" /> +</svg> diff --git a/test/svg/fill.3.rgb.svg b/test/svg/fill.3.rgb.svg new file mode 100644 index 000000000..c18b03bb5 --- /dev/null +++ b/test/svg/fill.3.rgb.svg @@ -0,0 +1,4 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <rect x="100" y="-750" width="800" height="500" + fill="rgb (75, 0 , 130)" /> +</svg> diff --git a/test/svg/fill.4.current-color.svg b/test/svg/fill.4.current-color.svg new file mode 100644 index 000000000..cf77d65a6 --- /dev/null +++ b/test/svg/fill.4.current-color.svg @@ -0,0 +1,4 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <rect x="100" y="-750" width="800" height="500" + fill="currentColor" /> +</svg> diff --git a/test/svg/fill.5.palette.svg b/test/svg/fill.5.palette.svg new file mode 100644 index 000000000..53ea97512 --- /dev/null +++ b/test/svg/fill.5.palette.svg @@ -0,0 +1,4 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <rect x="100" y="-750" width="800" height="500" + fill="var(--color1, red)" /> +</svg> diff --git a/test/svg/fill.6.opacity.svg b/test/svg/fill.6.opacity.svg new file mode 100644 index 000000000..59b4eb41f --- /dev/null +++ b/test/svg/fill.6.opacity.svg @@ -0,0 +1,4 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <rect x="100" y="-750" width="800" height="500" + fill="magenta" fill-opacity="0.5" /> +</svg> diff --git a/test/svg/fill.7.color.svg b/test/svg/fill.7.color.svg new file mode 100644 index 000000000..745b2e881 --- /dev/null +++ b/test/svg/fill.7.color.svg @@ -0,0 +1,5 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + color="green" > + <rect x="100" y="-750" width="800" height="500" + fill="currentColor" /> +</svg> diff --git a/test/svg/fill.8.rule.svg b/test/svg/fill.8.rule.svg new file mode 100644 index 000000000..366ff6760 --- /dev/null +++ b/test/svg/fill.8.rule.svg @@ -0,0 +1,8 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <g transform="scale(5,5) translate(0,-150)"> + <polygon fill-rule="nonzero" + points="50,0 21,90 98,35 2,35 79,90"/> + <polygon fill-rule="evenodd" + points="150,0 121,90 198,35 102,35 179,90"/> + </g> +</svg> diff --git a/test/svg/gradient.0.lin-pad.svg b/test/svg/gradient.0.lin-pad.svg new file mode 100644 index 000000000..0ec54092f --- /dev/null +++ b/test/svg/gradient.0.lin-pad.svg @@ -0,0 +1,10 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <defs> + <linearGradient id="grad" x1="33%" x21="66%"> + <stop offset="0%" stop-color="blue" stop-opacity="1" /> + <stop offset="100%" stop-color="red" stop-opacity="0.5" /> + </linearGradient> + </defs> + <rect x="100" y="-900" width="800" height="800" fill="url(#grad)" /> +</svg> + diff --git a/test/svg/gradient.1.lin-reflect.svg b/test/svg/gradient.1.lin-reflect.svg new file mode 100644 index 000000000..9e3e50cb9 --- /dev/null +++ b/test/svg/gradient.1.lin-reflect.svg @@ -0,0 +1,11 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <defs> + <linearGradient id="grad" x1="33%" x2="66%" + spreadMethod="reflect"> + <stop offset="0%" stop-color="blue" stop-opacity="1" /> + <stop offset="100%" stop-color="red" stop-opacity="1" /> + </linearGradient> + </defs> + <rect x="0" y="-900" width="1000" height="800" fill="url(#grad)" /> +</svg> + diff --git a/test/svg/gradient.2.lin-repeat.svg b/test/svg/gradient.2.lin-repeat.svg new file mode 100644 index 000000000..1f023f5e1 --- /dev/null +++ b/test/svg/gradient.2.lin-repeat.svg @@ -0,0 +1,11 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <defs> + <linearGradient id="grad" x1="33%" x2="66%" + spreadMethod="repeat"> + <stop offset="0%" stop-color="blue" stop-opacity="1" /> + <stop offset="100%" stop-color="red" stop-opacity="1" /> + </linearGradient> + </defs> + <rect x="0" y="-900" width="1000" height="800" fill="url(#grad)" /> +</svg> + diff --git a/test/svg/gradient.3.lin-user.svg b/test/svg/gradient.3.lin-user.svg new file mode 100644 index 000000000..fc90328f0 --- /dev/null +++ b/test/svg/gradient.3.lin-user.svg @@ -0,0 +1,11 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <defs> + <linearGradient id="grad" x1="300" y1="-500" x2="600" y2="-500" + gradientUnits="userSpaceOnUse"> + <stop offset="0%" stop-color="blue" stop-opacity="1" /> + <stop offset="100%" stop-color="red" stop-opacity="1" /> + </linearGradient> + </defs> + <rect x="0" y="-900" width="1000" height="800" fill="url(#grad)" /> +</svg> + diff --git a/test/svg/gradient.4.lin-transform.svg b/test/svg/gradient.4.lin-transform.svg new file mode 100644 index 000000000..bc8f5b622 --- /dev/null +++ b/test/svg/gradient.4.lin-transform.svg @@ -0,0 +1,10 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <defs> + <linearGradient id="grad" gradientTransform="rotate(45)"> + <stop offset="0%" stop-color="blue" stop-opacity="1" /> + <stop offset="100%" stop-color="red" stop-opacity="1" /> + </linearGradient> + </defs> + <rect x="100" y="-900" width="800" height="800" fill="url(#grad)" /> +</svg> + diff --git a/test/svg/gradient.5.rad-pad.svg b/test/svg/gradient.5.rad-pad.svg new file mode 100644 index 000000000..b631ddc73 --- /dev/null +++ b/test/svg/gradient.5.rad-pad.svg @@ -0,0 +1,10 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <defs> + <radialGradient id="grad" cx="50%" cy="50%" + fx="0.75" fy="0.35" r="0.5"> + <stop offset="0%" stop-color="white" stop-opacity="1" /> + <stop offset="100%" stop-color="green" stop-opacity="1" /> + </radialGradient> + </defs> + <rect x="100" y="-900" width="800" height="800" fill="url(#grad)" /> +</svg> diff --git a/test/svg/gradient.6.rad-reflect.svg b/test/svg/gradient.6.rad-reflect.svg new file mode 100644 index 000000000..b6fea76be --- /dev/null +++ b/test/svg/gradient.6.rad-reflect.svg @@ -0,0 +1,11 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <defs> + <radialGradient id="grad" cx="75%" cy="25%" r="33%" + fx="0.64" fy="0.18" fr="0.17" + spreadMethod="reflect" > + <stop offset="0%" stop-color="white" stop-opacity="1" /> + <stop offset="100%" stop-color="green" stop-opacity="1" /> + </radialGradient> + </defs> + <rect x="100" y="-900" width="800" height="800" fill="url(#grad)" /> +</svg> diff --git a/test/svg/gradient.7.rad-repeat.svg b/test/svg/gradient.7.rad-repeat.svg new file mode 100644 index 000000000..63d138d2a --- /dev/null +++ b/test/svg/gradient.7.rad-repeat.svg @@ -0,0 +1,11 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <defs> + <radialGradient id="grad" cx="75%" cy="25%" r="33%" + fx="0.64" fy="0.18" fr="0.17" + spreadMethod="repeat" > + <stop offset="0%" stop-color="white" stop-opacity="1" /> + <stop offset="100%" stop-color="green" stop-opacity="1" /> + </radialGradient> + </defs> + <rect x="100" y="-900" width="800" height="800" fill="url(#grad)" /> +</svg> diff --git a/test/svg/gradient.8.rad-user.svg b/test/svg/gradient.8.rad-user.svg new file mode 100644 index 000000000..e1d9c61f0 --- /dev/null +++ b/test/svg/gradient.8.rad-user.svg @@ -0,0 +1,11 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <defs> + <radialGradient id="grad" cx="450" cy="-550" r="400" + fx="600" fy="-400" fr="10" + gradientUnits="userSpaceOnUse" > + <stop offset="0%" stop-color="red" stop-opacity="1" /> + <stop offset="100%" stop-color="green" stop-opacity="0.5" /> + </radialGradient> + </defs> + <rect x="0" y="-1000" width="1000" height="1000" fill="url(#grad)" /> +</svg> diff --git a/test/svg/gradient.9.rad-transform.svg b/test/svg/gradient.9.rad-transform.svg new file mode 100644 index 000000000..4b90aaaf6 --- /dev/null +++ b/test/svg/gradient.9.rad-transform.svg @@ -0,0 +1,11 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <defs> + <radialGradient id="grad" cx="50%" cy="25%" + fx="0.75" fy="0.35" r="0.5" + gradientTransform="scale(1, 2)"> + <stop offset="0%" stop-color="red" stop-opacity="1" /> + <stop offset="100%" stop-color="green" stop-opacity="1" /> + </radialGradient> + </defs> + <rect x="100" y="-900" width="800" height="800" fill="url(#grad)" /> +</svg> diff --git a/test/svg/meson.build b/test/svg/meson.build new file mode 100644 index 000000000..b2b017d79 --- /dev/null +++ b/test/svg/meson.build @@ -0,0 +1,5 @@ +if librsvg_dep.found() + executable('svg-render', + 'svg-render.c', + dependencies: [libcairo_dep, librsvg_dep]) +endif diff --git a/test/svg/path.0.line.svg b/test/svg/path.0.line.svg new file mode 100644 index 000000000..19d50914a --- /dev/null +++ b/test/svg/path.0.line.svg @@ -0,0 +1,8 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <path fill="none" stroke="black" stroke-width="20" + d="M 200 -200 + L 500 -500 + H 800 + V -200 + " /> +</svg> diff --git a/test/svg/path.1.curve.svg b/test/svg/path.1.curve.svg new file mode 100644 index 000000000..49c252ac8 --- /dev/null +++ b/test/svg/path.1.curve.svg @@ -0,0 +1,9 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <path fill="none" stroke="black" stroke-width="20" + d="M200,-400 + C200,-200 + 500,-200 + 500,-400 + S800,-600 + 800,-400" /> +</svg> diff --git a/test/svg/path.2.quad.svg b/test/svg/path.2.quad.svg new file mode 100644 index 000000000..00a0dde57 --- /dev/null +++ b/test/svg/path.2.quad.svg @@ -0,0 +1,8 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <path fill="none" stroke="black" stroke-width="20" + d="M200,-300 + Q400,-50 + 600,-300 + T1000,-300" + /> +</svg> diff --git a/test/svg/path.3.arc.svg b/test/svg/path.3.arc.svg new file mode 100644 index 000000000..f177a72af --- /dev/null +++ b/test/svg/path.3.arc.svg @@ -0,0 +1,7 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <path fill="none" stroke="black" stroke-width="20" + d="M500,-500 + L 712 -712 + A300,300 0 1,0 712, -288 z" + /> +</svg> diff --git a/test/svg/shapes.0.rect.svg b/test/svg/shapes.0.rect.svg new file mode 100644 index 000000000..17db34649 --- /dev/null +++ b/test/svg/shapes.0.rect.svg @@ -0,0 +1,3 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <rect x="100" y="-750" width="800" height="500"/> +</svg> diff --git a/test/svg/shapes.1.rounded-rect.svg b/test/svg/shapes.1.rounded-rect.svg new file mode 100644 index 000000000..717470bee --- /dev/null +++ b/test/svg/shapes.1.rounded-rect.svg @@ -0,0 +1,3 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <rect x="100" y="-750" width="800" height="500" rx="100" ry="100"/> +</svg> diff --git a/test/svg/shapes.2.circle.svg b/test/svg/shapes.2.circle.svg new file mode 100644 index 000000000..3c07bad83 --- /dev/null +++ b/test/svg/shapes.2.circle.svg @@ -0,0 +1,3 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <circle cx="500" cy="-500" r="400"/> +</svg> diff --git a/test/svg/shapes.3.ellipse.svg b/test/svg/shapes.3.ellipse.svg new file mode 100644 index 000000000..67260a404 --- /dev/null +++ b/test/svg/shapes.3.ellipse.svg @@ -0,0 +1,3 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <ellipse cx="500" cy="-500" rx="400" ry="200"/> +</svg> diff --git a/test/svg/shapes.4.line.svg b/test/svg/shapes.4.line.svg new file mode 100644 index 000000000..58de42947 --- /dev/null +++ b/test/svg/shapes.4.line.svg @@ -0,0 +1,3 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <line x1="200" y1="-200" x2="800" y2="-800" stroke="black" stroke-width="20"/> +</svg> diff --git a/test/svg/shapes.5.polyline.svg b/test/svg/shapes.5.polyline.svg new file mode 100644 index 000000000..0cc5c383c --- /dev/null +++ b/test/svg/shapes.5.polyline.svg @@ -0,0 +1,12 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <polyline fill="none" stroke="black" stroke-width="20" + points="100, -100, + 300, -100, + 300, -300, + 500, -300, + 500, -500, + 700, -500 + 700, -700 + 900, -700 + 900, -900" /> +</svg> diff --git a/test/svg/shapes.6.polygon.svg b/test/svg/shapes.6.polygon.svg new file mode 100644 index 000000000..56bda0705 --- /dev/null +++ b/test/svg/shapes.6.polygon.svg @@ -0,0 +1,12 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="500" height="500"> +<polygon points="350, -75 + 379, -161 + 469, -161 + 397, -215 + 423, -301 + 350, -250 + 277, -301 + 303, -215 + 231, -161 + 321, -161" /> +</svg> diff --git a/test/svg/stroke.0.name.svg b/test/svg/stroke.0.name.svg new file mode 100644 index 000000000..f2a926475 --- /dev/null +++ b/test/svg/stroke.0.name.svg @@ -0,0 +1,6 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <line x1="100" y1="-500" x2="900" y2="-500" + fill="none" + stroke-width="100" + stroke="indigo" /> +</svg> diff --git a/test/svg/stroke.1.hex6.svg b/test/svg/stroke.1.hex6.svg new file mode 100644 index 000000000..89f2b1b38 --- /dev/null +++ b/test/svg/stroke.1.hex6.svg @@ -0,0 +1,6 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <line x1="100" y1="-500" x2="900" y2="-500" + fill="none" + stroke-width="100" + stroke="#AA55AA" /> +</svg> diff --git a/test/svg/stroke.2.hex3.svg b/test/svg/stroke.2.hex3.svg new file mode 100644 index 000000000..a8565a7b6 --- /dev/null +++ b/test/svg/stroke.2.hex3.svg @@ -0,0 +1,6 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <line x1="100" y1="-500" x2="900" y2="-500" + fill="none" + stroke-width="100" + stroke="#A5A" /> +</svg> diff --git a/test/svg/stroke.3.rgb.svg b/test/svg/stroke.3.rgb.svg new file mode 100644 index 000000000..42e7514e4 --- /dev/null +++ b/test/svg/stroke.3.rgb.svg @@ -0,0 +1,6 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <line x1="100" y1="-500" x2="900" y2="-500" + fill="none" + stroke-width="100" + stroke="rgb(75,0,130)" /> +</svg> diff --git a/test/svg/stroke.4.current-color.svg b/test/svg/stroke.4.current-color.svg new file mode 100644 index 000000000..9d645b881 --- /dev/null +++ b/test/svg/stroke.4.current-color.svg @@ -0,0 +1,6 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <line x1="100" y1="-500" x2="900" y2="-500" + fill="none" + stroke-width="100" + stroke="currentColor" /> +</svg> diff --git a/test/svg/stroke.5.palette.svg b/test/svg/stroke.5.palette.svg new file mode 100644 index 000000000..1262a7ba0 --- /dev/null +++ b/test/svg/stroke.5.palette.svg @@ -0,0 +1,6 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <line x1="100" y1="-500" x2="900" y2="-500" + fill="none" + stroke-width="100" + stroke="var(--color1, red)" /> +</svg> diff --git a/test/svg/stroke.6.opacity.svg b/test/svg/stroke.6.opacity.svg new file mode 100644 index 000000000..b84d1bdc9 --- /dev/null +++ b/test/svg/stroke.6.opacity.svg @@ -0,0 +1,6 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <line x1="100" y1="-500" x2="900" y2="-500" + fill="none" + stroke-width="100" + stroke="magenta" stroke-opacity="0.5" /> +</svg> diff --git a/test/svg/stroke.7.color.svg b/test/svg/stroke.7.color.svg new file mode 100644 index 000000000..952f48261 --- /dev/null +++ b/test/svg/stroke.7.color.svg @@ -0,0 +1,7 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + color="green" > + <line x1="100" y1="-500" x2="900" y2="-500" + fill="none" + stroke-width="100" + stroke="currentColor" /> +</svg> diff --git a/test/svg/stroke.8.width.svg b/test/svg/stroke.8.width.svg new file mode 100644 index 000000000..bb9edea90 --- /dev/null +++ b/test/svg/stroke.8.width.svg @@ -0,0 +1,14 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <line x1="100" y1="-900" x2="900" y2="-900" + fill="none" + stroke-width="100" + stroke="black" /> + <line x1="100" y1="-500" x2="900" y2="-500" + fill="none" + stroke-width="200" + stroke="black" /> + <line x1="100" y1="-100" x2="900" y2="-100" + fill="none" + stroke-width="300" + stroke="black" /> +</svg> diff --git a/test/svg/stroke.9.cap.svg b/test/svg/stroke.9.cap.svg new file mode 100644 index 000000000..35046446c --- /dev/null +++ b/test/svg/stroke.9.cap.svg @@ -0,0 +1,17 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <line x1="100" y1="-900" x2="900" y2="-900" + fill="none" + stroke-width="200" + stroke-linecap="butt" + stroke="black" /> + <line x1="100" y1="-500" x2="900" y2="-500" + fill="none" + stroke-width="200" + stroke-linecap="round" + stroke="black" /> + <line x1="100" y1="-100" x2="900" y2="-100" + fill="none" + stroke-width="200" + stroke-linecap="square" + stroke="black" /> +</svg> diff --git a/test/svg/stroke.A.dash.svg b/test/svg/stroke.A.dash.svg new file mode 100644 index 000000000..2be5a1d90 --- /dev/null +++ b/test/svg/stroke.A.dash.svg @@ -0,0 +1,27 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <line x1="100" y1="-950" x2="900" y2="-950" + fill="none" + stroke-width="100" + stroke-dasharray="none" + stroke="black" /> + <line x1="100" y1="-750" x2="900" y2="-750" + fill="none" + stroke-width="100" + stroke-dasharray="200" + stroke="black" /> + <line x1="100" y1="-550" x2="900" y2="-550" + fill="none" + stroke-width="100" + stroke-dasharray="200 50" + stroke="black" /> + <line x1="100" y1="-350" x2="900" y2="-350" + fill="none" + stroke-width="100" + stroke-dasharray="200 50 100" + stroke="black" /> + <line x1="100" y1="-150" x2="900" y2="-150" + fill="none" + stroke-width="100" + stroke-dasharray="200 50 100 150" + stroke="black" /> +</svg> diff --git a/test/svg/stroke.B.dash-offset.svg b/test/svg/stroke.B.dash-offset.svg new file mode 100644 index 000000000..f7623ea84 --- /dev/null +++ b/test/svg/stroke.B.dash-offset.svg @@ -0,0 +1,31 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <line x1="100" y1="-950" x2="900" y2="-950" + fill="none" + stroke-width="100" + stroke-dasharray="none" + stroke="black" /> + <line x1="100" y1="-750" x2="900" y2="-750" + fill="none" + stroke-width="100" + stroke-dasharray="200" + stroke-dashoffset="100" + stroke="black" /> + <line x1="100" y1="-550" x2="900" y2="-550" + fill="none" + stroke-width="100" + stroke-dasharray="200 50" + stroke-dashoffset="100" + stroke="black" /> + <line x1="100" y1="-350" x2="900" y2="-350" + fill="none" + stroke-width="100" + stroke-dasharray="200 50 100" + stroke-dashoffset="100" + stroke="black" /> + <line x1="100" y1="-150" x2="900" y2="-150" + fill="none" + stroke-width="100" + stroke-dasharray="200 50 100 150" + stroke-dashoffset="100" + stroke="black" /> +</svg> diff --git a/test/svg/stroke.C.miter.svg b/test/svg/stroke.C.miter.svg new file mode 100644 index 000000000..1dc4ee6a7 --- /dev/null +++ b/test/svg/stroke.C.miter.svg @@ -0,0 +1,10 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <polyline + points="100, -200 + 900, -400 + 100, -700" + fill="none" + stroke-width="200" + stroke-linejoin="miter" + stroke="black" /> +</svg> diff --git a/test/svg/stroke.D.round.svg b/test/svg/stroke.D.round.svg new file mode 100644 index 000000000..3e4c6236f --- /dev/null +++ b/test/svg/stroke.D.round.svg @@ -0,0 +1,10 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <polyline + points="100, -200 + 900, -400 + 100, -700" + fill="none" + stroke-width="200" + stroke-linejoin="round" + stroke="black" /> +</svg> diff --git a/test/svg/stroke.E.bevel.svg b/test/svg/stroke.E.bevel.svg new file mode 100644 index 000000000..25d9e3803 --- /dev/null +++ b/test/svg/stroke.E.bevel.svg @@ -0,0 +1,10 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <polyline + points="100, -200 + 900, -400 + 100, -700" + fill="none" + stroke-width="200" + stroke-linejoin="bevel" + stroke="black" /> +</svg> diff --git a/test/svg/stroke.F.miter-limit.svg b/test/svg/stroke.F.miter-limit.svg new file mode 100644 index 000000000..14357f0b4 --- /dev/null +++ b/test/svg/stroke.F.miter-limit.svg @@ -0,0 +1,11 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg"> + <polyline + points="100, -200 + 900, -400 + 100, -700" + fill="none" + stroke-width="200" + stroke-linejoin="miter" + stroke-miterlimit="2" + stroke="black" /> +</svg> diff --git a/test/svg/svg-font-template.ttx b/test/svg/svg-font-template.ttx new file mode 100644 index 000000000..715074dda --- /dev/null +++ b/test/svg/svg-font-template.ttx @@ -0,0 +1,190 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="4.19"> + + <GlyphOrder> + <!-- The 'id' attribute is only for humans; it is ignored when parsed. --> + <GlyphID id="0" name=".notdef"/> + </GlyphOrder> + + <head> + <!-- Most of this table will be recalculated by the compiler --> + <tableVersion value="1.0"/> + <fontRevision value="1.0"/> + <checkSumAdjustment value="0x3e7355ef"/> + <magicNumber value="0x5f0f3cf5"/> + <flags value="00000000 00000001"/> + <unitsPerEm value="1000"/> + <created value="Wed Jun 15 00:00:00 2022"/> + <modified value="Wed Jun 15 00:00:00 2022"/> + <xMin value="0"/> + <yMin value="0"/> + <xMax value="1000"/> + <yMax value="1000"/> + <macStyle value="00000000 00000000"/> + <lowestRecPPEM value="6"/> + <fontDirectionHint value="2"/> + <indexToLocFormat value="0"/> + <glyphDataFormat value="0"/> + </head> + + <hhea> + <tableVersion value="0x00010000"/> + <ascent value="1000"/> + <descent value="0"/> + <lineGap value="200"/> + <advanceWidthMax value="1100"/> + <minLeftSideBearing value="0"/> + <minRightSideBearing value="0"/> + <xMaxExtent value="1000"/> + <caretSlopeRise value="1"/> + <caretSlopeRun value="0"/> + <caretOffset value="0"/> + <reserved0 value="0"/> + <reserved1 value="0"/> + <reserved2 value="0"/> + <reserved3 value="0"/> + <metricDataFormat value="0"/> + <numberOfHMetrics value="2"/> + </hhea> + + <maxp> + <!-- Most of this table will be recalculated by the compiler --> + <tableVersion value="0x10000"/> + <numGlyphs value="2"/> + <maxPoints value="1"/> + <maxContours value="1"/> + <maxCompositePoints value="1"/> + <maxCompositeContours value="1"/> + <maxZones value="1"/> + <maxTwilightPoints value="0"/> + <maxStorage value="0"/> + <maxFunctionDefs value="0"/> + <maxInstructionDefs value="0"/> + <maxStackElements value="256"/> + <maxSizeOfInstructions value="1"/> + <maxComponentElements value="2"/> + <maxComponentDepth value="1"/> + </maxp> + + <OS_2> + <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex' + will be recalculated by the compiler --> + <version value="3"/> + <xAvgCharWidth value="1000"/> + <usWeightClass value="400"/> + <usWidthClass value="5"/> + <fsType value="00000000 00000001"/> + <ySubscriptXSize value="600"/> + <ySubscriptYSize value="600"/> + <ySubscriptXOffset value="0"/> + <ySubscriptYOffset value="75"/> + <ySuperscriptXSize value="600"/> + <ySuperscriptYSize value="600"/> + <ySuperscriptXOffset value="0"/> + <ySuperscriptYOffset value="300"/> + <yStrikeoutSize value="0"/> + <yStrikeoutPosition value="300"/> + <sFamilyClass value="0"/> + <panose> + <bFamilyType value="0"/> + <bSerifStyle value="0"/> + <bWeight value="0"/> + <bProportion value="0"/> + <bContrast value="0"/> + <bStrokeVariation value="0"/> + <bArmStyle value="0"/> + <bLetterForm value="0"/> + <bMidline value="0"/> + <bXHeight value="0"/> + </panose> + <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/> + <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/> + <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/> + <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/> + <achVendID value="djr "/> + <fsSelection value="00000000 01000000"/> + <usFirstCharIndex value="65"/> + <usLastCharIndex value="65"/> + <sTypoAscender value="1000"/> + <sTypoDescender value="0"/> + <sTypoLineGap value="200"/> + <usWinAscent value="1000"/> + <usWinDescent value="300"/> + <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/> + <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/> + <sxHeight value="500"/> + <sCapHeight value="720"/> + <usDefaultChar value="0"/> + <usBreakChar value="32"/> + <usMaxContext value="3"/> + </OS_2> + + <hmtx> + <mtx name=".notdef" width="1100" lsb="0"/> + </hmtx> + + <cmap> + <tableVersion version="0"/> + <cmap_format_4 platformID="0" platEncID="3" language="0"> + </cmap_format_4> + </cmap> + + <loca> + <!-- The 'loca' table will be calculated by the compiler --> + </loca> + + <glyf> + + <!-- The xMin, yMin, xMax and yMax values + will be recalculated by the compiler. --> + + <TTGlyph name=".notdef"/><!-- contains no outline data --> + + </glyf> + + <name> + <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409"> + Cairo Font Template + </namerecord> + <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409"> + Regular + </namerecord> + <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409"> + Cairo Font Template Regular + </namerecord> + </name> + + <post> + <formatType value="3.0"/> + <italicAngle value="0.0"/> + <underlinePosition value="0"/> + <underlineThickness value="0"/> + <isFixedPitch value="0"/> + <minMemType42 value="0"/> + <maxMemType42 value="0"/> + <minMemType1 value="0"/> + <maxMemType1 value="0"/> + </post> + + <CPAL> + <version value="0"/> + <numPaletteEntries value="2"/> + <palette index="0"> + <color index="0" value="#C5A1D7FF"/> + <color index="1" value="#80DFC8FF"/> + </palette> + <palette index="1"> + <color index="0" value="#6392A9FF"/> + <color index="1" value="#7896B3FF"/> + </palette> + </CPAL> + + <SVG> + <svgDoc endGlyphID="0" startGlyphID="0"> + <![CDATA[<svg xmlns="http://www.w3.org/2000/svg"></svg>]]> + </svgDoc> + <colorPalettes> + </colorPalettes> + </SVG> + +</ttFont> diff --git a/test/svg/svg-render.c b/test/svg/svg-render.c new file mode 100644 index 000000000..8f67ebdc2 --- /dev/null +++ b/test/svg/svg-render.c @@ -0,0 +1,308 @@ +/* + * Copyright © 2016 Adrian Johnson + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Author: Adrian Johnson <ajohnson@redneon.com> + */ + +/* Compilation: + * Build cairo with -DDEBUG_SVG_RENDER + * gcc -o svg-render svg-render.c `pkg-config --cflags --libs cairo librsvg` + */ + +/* svg-render - render SVG files using both the cairo glyph renderer and librsvg. + * + * This allows testing the cairo SVG test cases before assembling them into an SVG font. + * Usage: + * svg-render [-b] [-s] [-g <id>] [-e <em_size> ] input.svg + * + * Output is written to input.cairo.png and input.rsvg.png. + * + * -b print bounding box. + * -s Use standard SVG viewport. See below. + * -g render glyph with id <id> + * -e set the EM size. The default is 1000. + * + * SVG Glyphs are assumed to be wholely within the view port. + */ + +#include <stdio.h> +#include <math.h> +#include <cairo.h> +#include <librsvg/rsvg.h> + +typedef enum { CAIRO_SVG, LIBRSVG } svg_renderer_t; + +/* output image size */ +#define WIDTH 1000 +#define HEIGHT 1000 + +static cairo_bool_t bbox = FALSE; +static cairo_bool_t standard_svg = FALSE; +static const char *glyph_id = NULL; +static int em_size = 1000; + +cairo_bool_t +_cairo_debug_svg_render (cairo_t *cr, + const char *svg_document, + const char *element, + double units_per_em, + int debug_level); + +static void +cairo_render (const char *svg_document, cairo_t *cr) +{ + if (!_cairo_debug_svg_render (cr, svg_document, glyph_id, em_size, 2)) + printf("_cairo_debug_svg_render() failed\n"); +} + +static void +librsvg_render (const char *svg_document, cairo_t *cr) +{ + gboolean has_width; + gboolean has_height; + gboolean has_viewbox; + RsvgLength svg_width; + RsvgLength svg_height; + RsvgRectangle svg_viewbox; + RsvgRectangle viewport; + double width, height; + GError *error = NULL; + + RsvgHandle *handle = rsvg_handle_new_from_data ((guint8 *)svg_document, + strlen(svg_document), + &error); + if (!handle) { + printf ("Could not load: %s", error->message); + return; + } + + /* Default width if not specified is EM Square */ + width = em_size; + height = em_size; + + /* Get width/height if specified. */ + rsvg_handle_get_intrinsic_dimensions(handle, + &has_width, + &svg_width, + &has_height, + &svg_height, + &has_viewbox, + &svg_viewbox); + if (has_width) + width = svg_width.length; + + if (has_height) + height = svg_height.length; + + /* We set the viewport for the call rsvg_handle_render_layer() to + * width/height. That way if either dimension is not specified in + * the SVG it will be inherited from the viewport we provide. + * + * As this scales up the rendered dimensions by width/height we + * need to undo this scaling to get a unit square scale that + * matches the cairo SVG renderer scale. The OpenType SVG spec + * does not say what to do if width != height. In this case we + * will just use a uniform scale that ensures the viewport fits in + * the unit square and also center it. + */ + + if (width > height) { + cairo_scale (cr, 1.0/width, 1.0/width); + cairo_translate (cr, 0, (width - height)/2.0); + } else { + cairo_scale (cr, 1.0/height, 1.0/height); + cairo_translate (cr, (height - width)/2.0, 0); + } + + viewport.x = 0; + viewport.y = 0; + viewport.width = width; + viewport.height = height; + if (!rsvg_handle_render_layer (handle, cr, glyph_id, &viewport, &error)) { + printf ("librsvg render failed: %s", error->message); + return; + } +} + +static void +render_svg (const char *svg_document, svg_renderer_t renderer, const char* out_file) +{ + double x, y, w, h; + + cairo_surface_t *recording = cairo_recording_surface_create (CAIRO_CONTENT_COLOR_ALPHA, NULL); + cairo_t *cr = cairo_create (recording); + + /* Scale up to image size when recording to reduce rounding errors + * in cairo_recording_surface_ink_extents() + */ + cairo_scale (cr, WIDTH, HEIGHT); + + if (renderer == CAIRO_SVG) { + cairo_render (svg_document, cr); + } else { + librsvg_render (svg_document, cr); + } + cairo_destroy (cr); + + if (bbox) { + cairo_recording_surface_ink_extents (recording, &x, &y, &w, &h); + if (renderer == CAIRO_SVG) + printf("cairo "); + else + printf("librsvg"); + + printf(" bbox left: %d right: %d top: %d bottom: %d\n", + (int)floor(x), + (int)ceil(x + w), + (int)floor(y), + (int)ceil(y + h)); + } + + cairo_surface_t *surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, WIDTH, HEIGHT); + cr = cairo_create (surface); + + /* If rendering a glyph need to translate base line to bottom of image */ + if (standard_svg) + cairo_set_source_surface (cr, recording, 0, 0); + else + cairo_set_source_surface (cr, recording, 0, HEIGHT); + + cairo_paint (cr); + + cairo_surface_write_to_png (surface, out_file); + cairo_surface_destroy (surface); +} + +static char * +create_output_name (const char *svg_file, svg_renderer_t renderer) +{ + char buf[1000]; + int len; + + strcpy (buf, svg_file); + len = strlen (buf); + + if (strlen (buf) > 5 && strcmp (buf + len - 4, ".svg") == 0) + buf[len - 4] = 0; + + if (renderer == CAIRO_SVG) + strcat (buf, ".cairo.png"); + else + strcat (buf, ".rsvg.png"); + + return strdup (buf); +} + +static char * +read_file(const char *filename) +{ + FILE *fp; + int len; + char *data; + + fp = fopen (filename, "r"); + if (fp == NULL) + return NULL; + + fseek (fp, 0, SEEK_END); + len = ftell(fp); + rewind (fp); + data = malloc (len + 1); + if (fread(data, len, 1, fp) != 1) + return NULL; + data[len] = 0; + fclose(fp); + return data; +} + +static void +usage_and_exit() +{ + printf ("svg-render [-b] [-s] [-g <id>] [-e <em_size> ] input.svg\n"); + exit (1); +} + +int +main(int argc, char **argv) +{ + const char *input_file = NULL; + char *svg_document; + char *output_file; + + argc--; + argv++; + while (argc > 0) { + if (strcmp (argv[0], "-b") == 0) { + bbox = TRUE; + argc--; + argv++; + } else if (strcmp (argv[0], "-s") == 0) { + standard_svg = TRUE; + argc--; + argv++; + } else if (strcmp (argv[0], "-g") == 0) { + if (argc > 1) { + glyph_id = argv[1]; + argc -= 2; + argv += 2; + } else { + usage_and_exit(); + } + } else if (strcmp (argv[0], "-e") == 0) { + if (argc > 1) { + em_size = atoi (argv[1]); + if (em_size <= 0) { + usage_and_exit(); + } + argc -= 2; + argv += 2; + } else { + usage_and_exit(); + } + } else { + input_file = argv[0]; + argc--; + argv++; + } + } + if (!input_file) + usage_and_exit(); + + svg_document = read_file (input_file); + if (!svg_document) { + printf("error reading file %s\n", input_file); + exit (1); + } + + output_file = create_output_name (input_file, CAIRO_SVG); + render_svg (svg_document, CAIRO_SVG, output_file); + free (output_file); + + output_file = create_output_name (input_file, LIBRSVG); + render_svg (svg_document, LIBRSVG, output_file); + free (output_file); + + free (svg_document); + + return 0; +} diff --git a/test/svg/transform.0.translate.svg b/test/svg/transform.0.translate.svg new file mode 100644 index 000000000..5d9555673 --- /dev/null +++ b/test/svg/transform.0.translate.svg @@ -0,0 +1,8 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <rect id="square" width="300" height="300"/> + </defs> + <use xlink:href="#square" transform="translate(100, -900)"/> + <use xlink:href="#square" transform="translate(600, -400)"/> +</svg> diff --git a/test/svg/transform.1.scale.svg b/test/svg/transform.1.scale.svg new file mode 100644 index 000000000..b7742fc80 --- /dev/null +++ b/test/svg/transform.1.scale.svg @@ -0,0 +1,10 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <rect id="square" width="300" height="300"/> + </defs> + <use xlink:href="#square" transform="translate(100, -900)"/> + <g transform="translate(400, -400)"> + <use xlink:href="#square" transform="scale(1.5, 0.5)"/> + </g> +</svg> diff --git a/test/svg/transform.2.rotate.svg b/test/svg/transform.2.rotate.svg new file mode 100644 index 000000000..926ae63fc --- /dev/null +++ b/test/svg/transform.2.rotate.svg @@ -0,0 +1,10 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <rect id="square" width="300" height="300"/> + </defs> + <use xlink:href="#square" transform="translate(100, -900)"/> + <g transform="translate(600, -600)"> + <use xlink:href="#square" transform="rotate(30)"/> + </g> +</svg> diff --git a/test/svg/transform.3.skewX.svg b/test/svg/transform.3.skewX.svg new file mode 100644 index 000000000..f7555534d --- /dev/null +++ b/test/svg/transform.3.skewX.svg @@ -0,0 +1,10 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <rect id="square" width="300" height="300"/> + </defs> + <use xlink:href="#square" transform="translate(100, -900)"/> + <g transform="translate(400, -400)"> + <use xlink:href="#square" transform="skewX(30)"/> + </g> +</svg> diff --git a/test/svg/transform.4.skewY.svg b/test/svg/transform.4.skewY.svg new file mode 100644 index 000000000..cd62c8a8a --- /dev/null +++ b/test/svg/transform.4.skewY.svg @@ -0,0 +1,10 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <rect id="square" width="300" height="300"/> + </defs> + <use xlink:href="#square" transform="translate(100, -900)"/> + <g transform="translate(400, -500)"> + <use xlink:href="#square" transform="skewY(30)"/> + </g> +</svg> diff --git a/test/svg/transform.5.matrix.svg b/test/svg/transform.5.matrix.svg new file mode 100644 index 000000000..643fbe36b --- /dev/null +++ b/test/svg/transform.5.matrix.svg @@ -0,0 +1,10 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <rect id="square" width="300" height="300"/> + </defs> + <use xlink:href="#square" transform="translate(100, -900)"/> + <g transform="translate(600, -600)"> + <use xlink:href="#square" transform="matrix(1, 0.4, -0.6, 1.1, 50, -70)"/> + </g> +</svg> diff --git a/test/svg/transform.6.multiple.svg b/test/svg/transform.6.multiple.svg new file mode 100644 index 000000000..90c7b3054 --- /dev/null +++ b/test/svg/transform.6.multiple.svg @@ -0,0 +1,16 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <path id="heart" d="M 10,30 A 20,20 0,0,1 50,30 A 20,20 0,0,1 90,30 Q 90,60 50,90 Q 10,60 10,30 z" /> + </defs> + <use xlink:href="#heart" + transform="translate(10, -650) + rotate(-10 50 100) + translate(-166 125.5) + skewX(40) + scale(1 0.5),scale(8, 8)" + fill="grey"/> + <use xlink:href="#heart" + transform="translate(300, -800),scale(6, 6)" + fill="none" stroke="red" /> +</svg> diff --git a/test/svg/transform.7.stroke.svg b/test/svg/transform.7.stroke.svg new file mode 100644 index 000000000..f56b24dfe --- /dev/null +++ b/test/svg/transform.7.stroke.svg @@ -0,0 +1,20 @@ +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <defs> + <circle id="c1" + cx="100" cy="100" r="80" + fill="none" + stroke="black" + stroke-width="20" /> + <circle id="c2" + cx="100" cy="100" r="80" + fill="none" + stroke="black" + stroke-width="20" + transform="scale(3,3)" /> + </defs> + + <use xlink:href="#c1" x="100" y="-900"/> + <use xlink:href="#c2" x="300" y="-700"/> + +</svg> |