exp/shiny/iconvg: add testdata/favicon.
Also fix a Rasterizer.AbsArcTo bug. The testdata/arcs example, based on
the examples from the SVG spec, only uses RelArcTo.
Change-Id: Iad94323eedfdf40938543692cdf3faf0731796bf
Reviewed-on: https://go-review.googlesource.com/31372
Reviewed-by: David Crawshaw <crawshaw@golang.org>
diff --git a/shiny/iconvg/decode_test.go b/shiny/iconvg/decode_test.go
index 26b780b..d941766 100644
--- a/shiny/iconvg/decode_test.go
+++ b/shiny/iconvg/decode_test.go
@@ -134,6 +134,7 @@
{"testdata/action-info.hires", ""},
{"testdata/arcs", ""},
{"testdata/blank", ""},
+ {"testdata/favicon", ""},
{"testdata/lod-polygon", ";64"},
{"testdata/video-005.primitive", ""},
}
diff --git a/shiny/iconvg/encode_test.go b/shiny/iconvg/encode_test.go
index 6b1bdf9..2a06891 100644
--- a/shiny/iconvg/encode_test.go
+++ b/shiny/iconvg/encode_test.go
@@ -10,6 +10,7 @@
"io/ioutil"
"math"
"path/filepath"
+ "strconv"
"testing"
"golang.org/x/image/math/f32"
@@ -129,6 +130,200 @@
testEncode(t, &e, "testdata/arcs.ivg")
}
+var faviconColors = []color.RGBA{
+ {0x76, 0xe1, 0xfe, 0xff},
+ {0x38, 0x4e, 0x54, 0xff},
+ {0xff, 0xff, 0xff, 0xff},
+ {0x17, 0x13, 0x11, 0xff},
+ {0x00, 0x00, 0x00, 0x54},
+ {0xff, 0xfc, 0xfb, 0xff},
+ {0xc3, 0x8c, 0x74, 0xff},
+ {0x23, 0x20, 0x1f, 0xff},
+}
+
+var faviconSVGData = []struct {
+ faviconColorsIndex int
+ d string
+}{{
+ faviconColorsIndex: 1,
+ d: "m16.092 1.002c-1.1057.01-2.2107.048844-3.3164.089844-2.3441.086758-4.511.88464-6.2832 2.1758a3.8208 3.5794 29.452 0 0 -.8947 -.6856 3.8208 3.5794 29.452 0 0 -5.0879 1.2383 3.8208 3.5794 29.452 0 0 1.5664 4.9961 3.8208 3.5794 29.452 0 0 .3593 .1758c-.2784.9536-.4355 1.9598-.4355 3.0078v20h28v-20c0-1.042-.152-2.0368-.418-2.9766a3.5794 3.8208 60.548 0 0 .43359 -.20703 3.5794 3.8208 60.548 0 0 1.5684 -4.9961 3.5794 3.8208 60.548 0 0 -5.0879 -1.2383 3.5794 3.8208 60.548 0 0 -.92969 .72461c-1.727-1.257-3.843-2.0521-6.1562-2.2148-1.1058-.078-2.2126-.098844-3.3184-.089844z",
+}, {
+ faviconColorsIndex: 0,
+ d: "m16 3c-4.835 0-7.9248 1.0791-9.7617 2.8906-.4777-.4599-1.2937-1.0166-1.6309-1.207-.9775-.5520-2.1879-.2576-2.7051.6582-.5171.9158-.1455 2.1063.8321 2.6582.2658.1501 1.2241.5845 1.7519.7441-.3281.9946-.4863 2.0829-.4863 3.2559v20h24c-.049-7.356 0-18 0-20 0-1.209-.166-2.3308-.516-3.3496.539-.2011 1.243-.5260 1.463-.6504.978-.5519 1.351-1.7424.834-2.6582s-1.729-1.2102-2.707-.6582c-.303.1711-.978.6356-1.463 1.0625-1.854-1.724-4.906-2.7461-9.611-2.7461z",
+}, {
+ faviconColorsIndex: 1,
+ d: "m3.0918 5.9219c-.060217.00947-.10772.020635-.14648.033203-.019384.00628-.035462.013581-.052734.021484-.00864.00395-.019118.00825-.03125.015625-.00607.00369-.011621.00781-.021484.015625-.00493.00391-.017342.015389-.017578.015625-.0002366.0002356-.025256.031048-.025391.03125a.19867 .19867 0 0 0 .26367 .28320c.0005595-.0002168.00207-.00128.00391-.00195a.19867 .19867 0 0 0 .00391 -.00195c.015939-.00517.045148-.013113.085937-.019531.081581-.012836.20657-.020179.36719.00391.1020.0152.2237.0503.3535.0976-.3277.0694-.5656.1862-.7227.3145-.1143.0933-.1881.1903-.2343.2695-.023099.0396-.039499.074216-.050781.10547-.00564.015626-.00989.029721-.013672.046875-.00189.00858-.00458.017085-.00586.03125-.0006392.00708-.0005029.014724 0 .027344.0002516.00631.00192.023197.00195.023437.0000373.0002412.0097.036937.00977.037109a.19867 .19867 0 0 0 .38477 -.039063 .19867 .19867 0 0 0 0 -.00195c.00312-.00751.00865-.015947.017578-.03125.0230-.0395.0660-.0977.1425-.1601.1530-.1250.4406-.2702.9863-.2871a.19930 .19930 0 0 0 .082031 -.019531c.12649.089206.25979.19587.39844.32422a.19867 .19867 0 1 0 .2696 -.2911c-.6099-.5646-1.1566-.7793-1.5605-.8398-.2020-.0303-.3679-.0229-.4883-.0039z",
+}, {
+ faviconColorsIndex: 1,
+ d: "m28.543 5.8203c-.12043-.018949-.28631-.026379-.48828.00391-.40394.060562-.94869.27524-1.5586.83984a.19867 .19867 0 1 0 .26953 .29102c.21354-.19768.40814-.33222.59180-.44141.51624.023399.79659.16181.94531.28320.07652.062461.11952.12063.14258.16016.0094.016037.01458.025855.01758.033203a.19867 .19867 0 0 0 .38476 .039063c.000062-.0001719.0097-.036868.0098-.037109.000037-.0002412.0017-.017125.002-.023437.000505-.012624.000639-.020258 0-.027344-.0013-.01417-.004-.022671-.0059-.03125-.0038-.017158-.008-.031248-.01367-.046875-.01128-.031254-.02768-.067825-.05078-.10742-.04624-.079195-.12003-.17424-.23437-.26758-.11891-.097066-.28260-.18832-.49609-.25781.01785-.00328.03961-.011119.05664-.013672.16062-.024082.28561-.016738.36719-.00391.03883.00611.06556.012409.08203.017578.000833.0002613.0031.0017.0039.00195a.19867 .19867 0 0 0 .271 -.2793c-.000135-.0002016-.02515-.031014-.02539-.03125-.000236-.0002356-.01265-.011717-.01758-.015625-.0099-.00782-.01737-.01194-.02344-.015625-.01213-.00737-.02066-.011673-.0293-.015625-.01727-.0079-.03336-.013247-.05273-.019531-.03877-.012568-.08822-.025682-.14844-.035156z",
+}, {
+ faviconColorsIndex: 2,
+ d: "m15.171 9.992a4.8316 4.8316 0 0 1 -4.832 4.832 4.8316 4.8316 0 0 1 -4.8311 -4.832 4.8316 4.8316 0 0 1 4.8311 -4.8316 4.8316 4.8316 0 0 1 4.832 4.8316z",
+}, {
+ faviconColorsIndex: 2,
+ d: "m25.829 9.992a4.6538 4.6538 0 0 1 -4.653 4.654 4.6538 4.6538 0 0 1 -4.654 -4.654 4.6538 4.6538 0 0 1 4.654 -4.6537 4.6538 4.6538 0 0 1 4.653 4.6537z",
+}, {
+ faviconColorsIndex: 3,
+ d: "m14.377 9.992a1.9631 1.9631 0 0 1 -1.963 1.963 1.9631 1.9631 0 0 1 -1.963 -1.963 1.9631 1.9631 0 0 1 1.963 -1.963 1.9631 1.9631 0 0 1 1.963 1.963z",
+}, {
+ faviconColorsIndex: 3,
+ d: "m25.073 9.992a1.9631 1.9631 0 0 1 -1.963 1.963 1.9631 1.9631 0 0 1 -1.963 -1.963 1.9631 1.9631 0 0 1 1.963 -1.963 1.9631 1.9631 0 0 1 1.963 1.963z",
+}, {
+ faviconColorsIndex: 4,
+ d: "m14.842 15.555h2.2156c.40215 0 .72590.3237.72590.7259v2.6545c0 .4021-.32375.7259-.72590.7259h-2.2156c-.40215 0-.72590-.3238-.72590-.7259v-2.6545c0-.4022.32375-.7259.72590-.7259z",
+}, {
+ faviconColorsIndex: 5,
+ d: "m14.842 14.863h2.2156c.40215 0 .72590.3238.72590.7259v2.6546c0 .4021-.32375.7259-.72590.7259h-2.2156c-.40215 0-.72590-.3238-.72590-.7259v-2.6546c0-.4021.32375-.7259.72590-.7259z",
+}, {
+ faviconColorsIndex: 4,
+ d: "m20 16.167c0 .838-.87123 1.2682-2.1448 1.1659-.02366 0-.04795-.6004-.25415-.5832-.50367.042-1.0959-.02-1.686-.02-.61294 0-1.2063.1826-1.6855.017-.11023-.038-.17830.5838-.26153.5816-1.2437-.033-2.0788-.3383-2.0788-1.1618 0-1.2118 1.8156-2.1941 4.0554-2.1941 2.2397 0 4.0554.9823 4.0554 2.1941z",
+}, {
+ faviconColorsIndex: 6,
+ d: "m19.977 15.338c0 .5685-.43366.8554-1.1381 1.0001-.29193.06-.63037.096-1.0037.1166-.56405.032-1.2078.031-1.8912.031-.67283 0-1.3072 0-1.8649-.029-.30627-.017-.58943-.043-.84316-.084-.81383-.1318-1.325-.417-1.325-1.0344 0-1.1601 1.8056-2.1006 4.033-2.1006s4.033.9405 4.033 2.1006z",
+}, {
+ faviconColorsIndex: 7,
+ d: "m18.025 13.488a2.0802 1.3437 0 0 1 -2.0802 1.3437 2.0802 1.3437 0 0 1 -2.0802 -1.3437 2.0802 1.3437 0 0 1 2.0802 -1.3437 2.0802 1.3437 0 0 1 2.0802 1.3437z",
+}}
+
+func TestEncodeFavicon(t *testing.T) {
+ var e Encoder
+
+ for i, c := range faviconColors[:2] {
+ e.SetCReg(uint8(i), false, RGBAColor(c))
+ }
+ remainingColors := faviconColors[2:]
+
+ seenFCI2 := false
+ for _, data := range faviconSVGData {
+ adj := uint8(data.faviconColorsIndex)
+ if adj >= 2 {
+ if !seenFCI2 {
+ seenFCI2 = true
+ for i, c := range remainingColors {
+ e.SetCReg(uint8(i), false, RGBAColor(c))
+ }
+ }
+ adj -= 2
+ }
+
+ var args [7]float32
+ prevN, prevVerb := 0, byte(0)
+ for d, first := data.d, true; d[0] != 'z'; first = false {
+ n, verb, implicit := 0, d[0], false
+ switch d[0] {
+ case 'H', 'h', 'V', 'v':
+ n = 1
+ case 'L', 'M', 'l', 'm':
+ n = 2
+ case 'S', 's':
+ n = 4
+ case 'C', 'c':
+ n = 6
+ case 'A', 'a':
+ n = 7
+ default:
+ if prevVerb == '\x00' {
+ panic("unrecognized verb")
+ }
+ n, verb, implicit = prevN, prevVerb, true
+ }
+ prevN, prevVerb = n, verb
+ if !implicit {
+ d = d[1:]
+ }
+
+ for i := 0; i < n; i++ {
+ nDots := 0
+ if d[0] == '.' {
+ nDots = 1
+ }
+ j := 1
+ for ; ; j++ {
+ switch d[j] {
+ case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
+ continue
+ case '.':
+ nDots++
+ if nDots == 1 {
+ continue
+ }
+ }
+ break
+ }
+ f, err := strconv.ParseFloat(d[:j], 64)
+ if err != nil {
+ t.Fatal(err)
+ }
+ args[i] = float32(f)
+ for ; d[j] == ' ' || d[j] == ','; j++ {
+ }
+ d = d[j:]
+ }
+
+ // The original SVG is 32x32 units, with the top left being (0, 0).
+ // Normalize to 64x64 units, with the center being (0, 0).
+ if verb == 'A' {
+ args[0] = 2 * args[0]
+ args[1] = 2 * args[1]
+ args[2] /= 360
+ args[5] = 2*args[5] - 32
+ args[6] = 2*args[6] - 32
+ } else if verb == 'a' {
+ args[0] = 2 * args[0]
+ args[1] = 2 * args[1]
+ args[2] /= 360
+ args[5] = 2 * args[5]
+ args[6] = 2 * args[6]
+ } else if first || ('A' <= verb && verb <= 'Z') {
+ for i := range args {
+ args[i] = 2*args[i] - 32
+ }
+ } else {
+ for i := range args {
+ args[i] = 2 * args[i]
+ }
+ }
+
+ if first {
+ first = false
+ e.StartPath(adj, args[0], args[1])
+ continue
+ }
+ switch verb {
+ case 'H':
+ e.AbsHLineTo(args[0])
+ case 'h':
+ e.RelHLineTo(args[0])
+ case 'V':
+ e.AbsVLineTo(args[0])
+ case 'v':
+ e.RelVLineTo(args[0])
+ case 'L':
+ e.AbsLineTo(args[0], args[1])
+ case 'l':
+ e.RelLineTo(args[0], args[1])
+ case 'S':
+ e.AbsSmoothCubeTo(args[0], args[1], args[2], args[3])
+ case 's':
+ e.RelSmoothCubeTo(args[0], args[1], args[2], args[3])
+ case 'C':
+ e.AbsCubeTo(args[0], args[1], args[2], args[3], args[4], args[5])
+ case 'c':
+ e.RelCubeTo(args[0], args[1], args[2], args[3], args[4], args[5])
+ case 'A':
+ e.AbsArcTo(args[0], args[1], args[2], args[3] != 0, args[4] != 0, args[5], args[6])
+ case 'a':
+ e.RelArcTo(args[0], args[1], args[2], args[3] != 0, args[4] != 0, args[5], args[6])
+ default:
+ panic("unrecognized verb")
+ }
+ }
+ e.ClosePathEndPath()
+ }
+
+ testEncode(t, &e, "testdata/favicon.ivg")
+}
+
var video005PrimitiveSVGData = []struct {
r, g, b uint32
x0, y0 int
diff --git a/shiny/iconvg/rasterizer.go b/shiny/iconvg/rasterizer.go
index 30f79c0..f03ac7d 100644
--- a/shiny/iconvg/rasterizer.go
+++ b/shiny/iconvg/rasterizer.go
@@ -373,8 +373,8 @@
pen := z.z.Pen()
x1 := float64(z.unabsX(pen[0]))
y1 := float64(z.unabsY(pen[1]))
- x2 := float64(z.unabsX(x))
- y2 := float64(z.unabsY(y))
+ x2 := float64(x)
+ y2 := float64(y)
phi := 2 * math.Pi * float64(xAxisRotation)
@@ -479,7 +479,7 @@
func (z *Rasterizer) RelArcTo(rx, ry, xAxisRotation float32, largeArc, sweep bool, x, y float32) {
a := z.relVec2(x, y)
- z.AbsArcTo(rx, ry, xAxisRotation, largeArc, sweep, a[0], a[1])
+ z.AbsArcTo(rx, ry, xAxisRotation, largeArc, sweep, z.unabsX(a[0]), z.unabsY(a[1]))
}
// angle returns the angle between the u and v vectors.
diff --git a/shiny/iconvg/testdata/README b/shiny/iconvg/testdata/README
index c883fe3..94ef89c 100644
--- a/shiny/iconvg/testdata/README
+++ b/shiny/iconvg/testdata/README
@@ -2,9 +2,9 @@
action/svg/production/ic_info_48px.svg in the
github.com/google/material-design-icons repository.
-action-info.{lo,hi}res.ivg are low- and high-resolution IconVG versions of
-action-info.svg. Low resolution means that coordinates are quantized to 1/64th
-of a unit; the graphic's size is 48 by 48 units. High resolution means that
+action-info.{lo,hi}res.ivg are low- and high-resolution IconVG versions of that
+SVG file. Low resolution means that coordinates are quantized to 1/64th of a
+unit; the graphic's size is 48 by 48 units. High resolution means that
coordinates are represented by all but the 2 least significant bits of a
float32. Each low resolution coordinate is encoded in either 1 or 2 bytes. Each
high resolution coordinate is encoded in either 1, 2 or 4 bytes.
@@ -32,6 +32,18 @@
+favicon.svg is based on doc/gopher/favicon.svg from the Go 1.7 release, after
+using Inkscape to convert strokes and circles to paths, and saving it as an
+"Optimized SVG".
+
+favicon.ivg is an IconVG version of that SVG file.
+
+favicon.ivg.disassembly is a disassembly of that IconVG file.
+
+favicon.png is a rendering of that IconVG file.
+
+
+
lod-polygon.ivg was created manually.
lod-polygon.ivg.disassembly is a disassembly of that IconVG file.
diff --git a/shiny/iconvg/testdata/favicon.ivg b/shiny/iconvg/testdata/favicon.ivg
new file mode 100644
index 0000000..afe10eb
--- /dev/null
+++ b/shiny/iconvg/testdata/favicon.ivg
Binary files differ
diff --git a/shiny/iconvg/testdata/favicon.ivg.disassembly b/shiny/iconvg/testdata/favicon.ivg.disassembly
new file mode 100644
index 0000000..28fca9d
--- /dev/null
+++ b/shiny/iconvg/testdata/favicon.ivg.disassembly
@@ -0,0 +1,988 @@
+89 49 56 47 IconVG Magic identifier
+00 Number of metadata chunks: 0
+90 Set CREG[CSEL-0] to a 3 byte (direct) color
+76 e1 fe RGBA 76e1feff
+91 Set CREG[CSEL-1] to a 3 byte (direct) color
+38 4e 54 RGBA 384e54ff
+c1 Start path, filled with CREG[CSEL-1]; M (absolute moveTo)
+31 80 +0.1875
+44 -30
+b1 c (relative cubeTo), 2 reps
+c9 7d -2.21875
+05 80 +0.015625
+95 7b -4.421875
+19 80 +0.09375
+61 79 -6.625
+31 80 +0.1875
+ c (relative cubeTo), implicit
+51 7b -4.6875
+2d 80 +0.171875
+fd 76 -9.015625
+c5 81 +1.765625
+71 73 -12.5625
+5d 84 +4.359375
+d3 a (relative arcTo), 4 reps
+a5 87 +7.640625
+29 87 +7.15625
+97 8c a7 3d 0.0818111 × 360 degrees (29.451996 degrees)
+00 0x0 (largeArc=0, sweep=0)
+35 7e -1.796875
+a1 7e -1.375
+ a (relative arcTo), implicit
+a5 87 +7.640625
+29 87 +7.15625
+97 8c a7 3d 0.0818111 × 360 degrees (29.451996 degrees)
+00 0x0 (largeArc=0, sweep=0)
+d5 75 -10.171875
+7d 82 +2.484375
+ a (relative arcTo), implicit
+a5 87 +7.640625
+29 87 +7.15625
+97 8c a7 3d 0.0818111 × 360 degrees (29.451996 degrees)
+00 0x0 (largeArc=0, sweep=0)
+21 83 +3.125
+94 +10
+ a (relative arcTo), implicit
+a5 87 +7.640625
+29 87 +7.15625
+97 8c a7 3d 0.0818111 × 360 degrees (29.451996 degrees)
+00 0x0 (largeArc=0, sweep=0)
+b9 80 +0.71875
+5d 80 +0.359375
+b0 c (relative cubeTo), 1 reps
+71 7f -0.5625
+e9 81 +1.90625
+21 7f -0.875
+ed 83 +3.921875
+21 7f -0.875
+05 86 +6.015625
+e9 v (relative vertical lineTo)
+d0 +40
+e7 h (relative horizontal lineTo)
+f0 +56
+e9 v (relative vertical lineTo)
+30 -40
+b0 c (relative cubeTo), 1 reps
+80 +0
+ed 7d -2.078125
+b5 7f -0.296875
+ed 7b -4.078125
+29 7f -0.84375
+0d 7a -5.953125
+d3 a (relative arcTo), 4 reps
+29 87 +7.15625
+a5 87 +7.640625
+b7 39 2c 3e 0.16818887 × 360 degrees (60.547993 degrees)
+00 0x0 (largeArc=0, sweep=0)
+dd 80 +0.859375
+99 7f -0.40625
+ a (relative arcTo), implicit
+29 87 +7.15625
+a5 87 +7.640625
+b7 39 2c 3e 0.16818887 × 360 degrees (60.547993 degrees)
+00 0x0 (largeArc=0, sweep=0)
+25 83 +3.140625
+6c -10
+ a (relative arcTo), implicit
+29 87 +7.15625
+a5 87 +7.640625
+b7 39 2c 3e 0.16818887 × 360 degrees (60.547993 degrees)
+00 0x0 (largeArc=0, sweep=0)
+d5 75 -10.171875
+85 7d -2.484375
+ a (relative arcTo), implicit
+29 87 +7.15625
+a5 87 +7.640625
+b7 39 2c 3e 0.16818887 × 360 degrees (60.547993 degrees)
+00 0x0 (largeArc=0, sweep=0)
+25 7e -1.859375
+75 81 +1.453125
+b1 c (relative cubeTo), 2 reps
+8d 7c -3.453125
+7d 7d -2.515625
+51 78 -7.6875
+e5 7b -4.109375
+b1 73 -12.3125
+95 7b -4.421875
+ c (relative cubeTo), implicit
+c9 7d -2.21875
+d9 7f -0.15625
+95 7b -4.421875
+cd 7f -0.203125
+5d 79 -6.640625
+d1 7f -0.1875
+e1 z (closePath); end path
+c0 Start path, filled with CREG[CSEL-0]; M (absolute moveTo)
+80 +0
+4c -26
+b5 c (relative cubeTo), 6 reps
+55 76 -9.671875
+80 +0
+29 70 -15.84375
+29 82 +2.15625
+7d 6c -19.515625
+c9 85 +5.78125
+ c (relative cubeTo), implicit
+0d 7f -0.953125
+15 7f -0.921875
+69 7d -2.59375
+f9 7d -2.03125
+bd 7c -3.265625
+99 7d -2.40625
+ c (relative cubeTo), implicit
+0d 7e -1.953125
+e5 7e -1.109375
+a1 7b -4.375
+7d 7f -0.515625
+99 7a -5.40625
+51 81 +1.3125
+ c (relative cubeTo), implicit
+f9 7e -1.03125
+d5 81 +1.828125
+b5 7f -0.296875
+39 84 +4.21875
+ad 81 +1.671875
+51 85 +5.3125
+ c (relative cubeTo), implicit
+89 80 +0.53125
+4d 80 +0.296875
+75 82 +2.453125
+2d 81 +1.171875
+81 83 +3.5
+7d 81 +1.484375
+ c (relative cubeTo), implicit
+59 7f -0.65625
+fd 81 +1.984375
+09 7f -0.96875
+2d 84 +4.171875
+09 7f -0.96875
+85 86 +6.515625
+e9 v (relative vertical lineTo)
+d0 +40
+e7 h (relative horizontal lineTo)
+e0 +48
+b3 c (relative cubeTo), 4 reps
+e9 7f -0.09375
+49 71 -14.71875
+80 +0
+38 -36
+80 +0
+30 -40
+ c (relative cubeTo), implicit
+80 +0
+95 7d -2.421875
+ad 7f -0.328125
+59 7b -4.65625
+f9 7e -1.03125
+4d 79 -6.703125
+ c (relative cubeTo), implicit
+15 81 +1.078125
+99 7f -0.40625
+7d 82 +2.484375
+f5 7e -1.046875
+ed 82 +2.921875
+b5 7e -1.296875
+ c (relative cubeTo), implicit
+f5 81 +1.953125
+e5 7e -1.109375
+b5 82 +2.703125
+85 7c -3.484375
+ad 81 +1.671875
+b1 7a -5.3125
+90 s (relative smooth cubeTo), 1 reps
+8d 7c -3.453125
+95 7d -2.421875
+99 7a -5.40625
+b1 7e -1.3125
+b1 c (relative cubeTo), 2 reps
+65 7f -0.609375
+59 80 +0.34375
+0d 7e -1.953125
+45 81 +1.265625
+15 7d -2.921875
+21 82 +2.125
+ c (relative cubeTo), implicit
+4d 7c -3.703125
+8d 7c -3.453125
+31 76 -9.8125
+81 7a -5.5
+c9 6c -19.21875
+81 7a -5.5
+e1 z (closePath); end path
+c1 Start path, filled with CREG[CSEL-1]; M (absolute moveTo)
+31 66 -25.8125
+d9 6b -20.15625
+b5 c (relative cubeTo), 6 reps
+e1 7f -0.125
+05 80 +0.015625
+c9 7f -0.21875
+0d 80 +0.046875
+b5 7f -0.296875
+11 80 +0.0625
+ c (relative cubeTo), implicit
+f9 7f -0.03125
+05 80 +0.015625
+ed 7f -0.078125
+09 80 +0.03125
+e5 7f -0.109375
+0d 80 +0.046875
+ c (relative cubeTo), implicit
+fd 7f -0.015625
+05 80 +0.015625
+f9 7f -0.03125
+05 80 +0.015625
+f1 7f -0.0625
+09 80 +0.03125
+ c (relative cubeTo), implicit
+fd 7f -0.015625
+80 +0
+fd 7f -0.015625
+05 80 +0.015625
+f5 7f -0.046875
+09 80 +0.03125
+ c (relative cubeTo), implicit
+fd 7f -0.015625
+05 80 +0.015625
+f9 7f -0.03125
+09 80 +0.03125
+f9 7f -0.03125
+09 80 +0.03125
+ c (relative cubeTo), implicit
+80 +0
+80 +0
+f5 7f -0.046875
+11 80 +0.0625
+f5 7f -0.046875
+11 80 +0.0625
+d0 a (relative arcTo), 1 reps
+65 80 +0.390625
+65 80 +0.390625
+00 0 × 360 degrees (0 degrees)
+00 0x0 (largeArc=0, sweep=0)
+89 80 +0.53125
+91 80 +0.5625
+b0 c (relative cubeTo), 1 reps
+80 +0
+80 +0
+80 +0
+80 +0
+05 80 +0.015625
+80 +0
+d0 a (relative arcTo), 1 reps
+65 80 +0.390625
+65 80 +0.390625
+00 0 × 360 degrees (0 degrees)
+00 0x0 (largeArc=0, sweep=0)
+05 80 +0.015625
+80 +0
+ba c (relative cubeTo), 11 reps
+09 80 +0.03125
+fd 7f -0.015625
+19 80 +0.09375
+f9 7f -0.03125
+2d 80 +0.171875
+f9 7f -0.03125
+ c (relative cubeTo), implicit
+29 80 +0.15625
+f9 7f -0.03125
+69 80 +0.40625
+f5 7f -0.046875
+bd 80 +0.734375
+05 80 +0.015625
+ c (relative cubeTo), implicit
+35 80 +0.203125
+09 80 +0.03125
+75 80 +0.453125
+19 80 +0.09375
+b5 80 +0.703125
+31 80 +0.1875
+ c (relative cubeTo), implicit
+59 7f -0.65625
+25 80 +0.140625
+e1 7e -1.125
+61 80 +0.375
+8d 7e -1.453125
+a1 80 +0.625
+ c (relative cubeTo), implicit
+c5 7f -0.234375
+31 80 +0.1875
+a1 7f -0.375
+61 80 +0.375
+89 7f -0.46875
+89 80 +0.53125
+ c (relative cubeTo), implicit
+f5 7f -0.046875
+15 80 +0.078125
+ed 7f -0.078125
+25 80 +0.140625
+e9 7f -0.09375
+39 80 +0.21875
+ c (relative cubeTo), implicit
+fd 7f -0.015625
+09 80 +0.03125
+fd 7f -0.015625
+11 80 +0.0625
+f9 7f -0.03125
+19 80 +0.09375
+ c (relative cubeTo), implicit
+80 +0
+05 80 +0.015625
+fd 7f -0.015625
+09 80 +0.03125
+fd 7f -0.015625
+11 80 +0.0625
+ c (relative cubeTo), implicit
+80 +0
+05 80 +0.015625
+80 +0
+09 80 +0.03125
+80 +0
+11 80 +0.0625
+ c (relative cubeTo), implicit
+80 +0
+05 80 +0.015625
+80 +0
+0d 80 +0.046875
+80 +0
+0d 80 +0.046875
+ c (relative cubeTo), implicit
+80 +0
+80 +0
+05 80 +0.015625
+15 80 +0.078125
+05 80 +0.015625
+15 80 +0.078125
+d1 a (relative arcTo), 2 reps
+65 80 +0.390625
+65 80 +0.390625
+00 0 × 360 degrees (0 degrees)
+00 0x0 (largeArc=0, sweep=0)
+c5 80 +0.765625
+ed 7f -0.078125
+ a (relative arcTo), implicit
+65 80 +0.390625
+65 80 +0.390625
+00 0 × 360 degrees (0 degrees)
+00 0x0 (largeArc=0, sweep=0)
+80 +0
+80 +0
+b2 c (relative cubeTo), 3 reps
+80 +0
+fd 7f -0.015625
+05 80 +0.015625
+f9 7f -0.03125
+09 80 +0.03125
+f1 7f -0.0625
+ c (relative cubeTo), implicit
+0d 80 +0.046875
+ed 7f -0.078125
+21 80 +0.125
+cd 7f -0.203125
+49 80 +0.28125
+b1 7f -0.3125
+ c (relative cubeTo), implicit
+51 80 +0.3125
+c1 7f -0.25
+e1 80 +0.875
+75 7f -0.546875
+f9 81 +1.96875
+6d 7f -0.578125
+d0 a (relative arcTo), 1 reps
+69 80 +0.40625
+69 80 +0.40625
+00 0 × 360 degrees (0 degrees)
+00 0x0 (largeArc=0, sweep=0)
+29 80 +0.15625
+f9 7f -0.03125
+b0 c (relative cubeTo), 1 reps
+41 80 +0.25
+2d 80 +0.171875
+85 80 +0.515625
+65 80 +0.390625
+cd 80 +0.796875
+a9 80 +0.65625
+d0 a (relative arcTo), 1 reps
+65 80 +0.390625
+65 80 +0.390625
+00 0 × 360 degrees (0 degrees)
+02 0x1 (largeArc=1, sweep=0)
+8d 80 +0.546875
+6d 7f -0.578125
+b1 c (relative cubeTo), 2 reps
+c9 7e -1.21875
+e1 7e -1.125
+b1 7d -2.3125
+71 7e -1.5625
+e1 7c -3.125
+55 7e -1.671875
+ c (relative cubeTo), implicit
+99 7f -0.40625
+f1 7f -0.0625
+45 7f -0.734375
+f5 7f -0.046875
+05 7f -0.984375
+80 +0
+e1 z (closePath); end path
+c1 Start path, filled with CREG[CSEL-1]; M (absolute moveTo)
+19 99 +25.09375
+a5 6b -20.359375
+b1 c (relative cubeTo), 2 reps
+c5 7f -0.234375
+f9 7f -0.03125
+6d 7f -0.578125
+f5 7f -0.046875
+09 7f -0.96875
+05 80 +0.015625
+ c (relative cubeTo), implicit
+31 7f -0.8125
+21 80 +0.125
+1d 7e -1.890625
+8d 80 +0.546875
+e1 7c -3.125
+ad 81 +1.671875
+d0 a (relative arcTo), 1 reps
+65 80 +0.390625
+65 80 +0.390625
+00 0 × 360 degrees (0 degrees)
+02 0x1 (largeArc=1, sweep=0)
+89 80 +0.53125
+95 80 +0.578125
+b3 c (relative cubeTo), 4 reps
+6d 80 +0.421875
+9d 7f -0.390625
+d1 80 +0.8125
+55 7f -0.671875
+31 81 +1.1875
+1d 7f -0.890625
+ c (relative cubeTo), implicit
+09 81 +1.03125
+0d 80 +0.046875
+99 81 +1.59375
+55 80 +0.328125
+e5 81 +1.890625
+91 80 +0.5625
+ c (relative cubeTo), implicit
+29 80 +0.15625
+21 80 +0.125
+3d 80 +0.234375
+3d 80 +0.234375
+49 80 +0.28125
+55 80 +0.328125
+ c (relative cubeTo), implicit
+05 80 +0.015625
+09 80 +0.03125
+09 80 +0.03125
+0d 80 +0.046875
+09 80 +0.03125
+11 80 +0.0625
+d0 a (relative arcTo), 1 reps
+65 80 +0.390625
+65 80 +0.390625
+00 0 × 360 degrees (0 degrees)
+00 0x0 (largeArc=0, sweep=0)
+c5 80 +0.765625
+15 80 +0.078125
+bb c (relative cubeTo), 12 reps
+80 +0
+80 +0
+05 80 +0.015625
+ed 7f -0.078125
+05 80 +0.015625
+ed 7f -0.078125
+ c (relative cubeTo), implicit
+80 +0
+80 +0
+80 +0
+f9 7f -0.03125
+80 +0
+f5 7f -0.046875
+ c (relative cubeTo), implicit
+80 +0
+f9 7f -0.03125
+80 +0
+f5 7f -0.046875
+80 +0
+f1 7f -0.0625
+ c (relative cubeTo), implicit
+80 +0
+f9 7f -0.03125
+fd 7f -0.015625
+f5 7f -0.046875
+fd 7f -0.015625
+f1 7f -0.0625
+ c (relative cubeTo), implicit
+80 +0
+f9 7f -0.03125
+fd 7f -0.015625
+f1 7f -0.0625
+f9 7f -0.03125
+e9 7f -0.09375
+ c (relative cubeTo), implicit
+fd 7f -0.015625
+f1 7f -0.0625
+f1 7f -0.0625
+dd 7f -0.140625
+e9 7f -0.09375
+c9 7f -0.21875
+ c (relative cubeTo), implicit
+e9 7f -0.09375
+d9 7f -0.15625
+c5 7f -0.234375
+a9 7f -0.34375
+89 7f -0.46875
+79 7f -0.53125
+ c (relative cubeTo), implicit
+c5 7f -0.234375
+d1 7f -0.1875
+71 7f -0.5625
+a1 7f -0.375
+05 7f -0.984375
+7d 7f -0.515625
+ c (relative cubeTo), implicit
+09 80 +0.03125
+80 +0
+15 80 +0.078125
+fd 7f -0.015625
+1d 80 +0.109375
+f9 7f -0.03125
+ c (relative cubeTo), implicit
+55 80 +0.328125
+f5 7f -0.046875
+95 80 +0.578125
+f9 7f -0.03125
+bd 80 +0.734375
+fd 7f -0.015625
+ c (relative cubeTo), implicit
+15 80 +0.078125
+05 80 +0.015625
+21 80 +0.125
+09 80 +0.03125
+29 80 +0.15625
+09 80 +0.03125
+ c (relative cubeTo), implicit
+80 +0
+80 +0
+80 +0
+80 +0
+80 +0
+80 +0
+d0 a (relative arcTo), 1 reps
+65 80 +0.390625
+65 80 +0.390625
+00 0 × 360 degrees (0 degrees)
+00 0x0 (largeArc=0, sweep=0)
+8d 80 +0.546875
+71 7f -0.5625
+b5 c (relative cubeTo), 6 reps
+80 +0
+80 +0
+f5 7f -0.046875
+f1 7f -0.0625
+f5 7f -0.046875
+f1 7f -0.0625
+ c (relative cubeTo), implicit
+80 +0
+80 +0
+f9 7f -0.03125
+fd 7f -0.015625
+f9 7f -0.03125
+f9 7f -0.03125
+ c (relative cubeTo), implicit
+fd 7f -0.015625
+fd 7f -0.015625
+f9 7f -0.03125
+f9 7f -0.03125
+f5 7f -0.046875
+f9 7f -0.03125
+ c (relative cubeTo), implicit
+f9 7f -0.03125
+fd 7f -0.015625
+f5 7f -0.046875
+fd 7f -0.015625
+f1 7f -0.0625
+f9 7f -0.03125
+ c (relative cubeTo), implicit
+f9 7f -0.03125
+fd 7f -0.015625
+f1 7f -0.0625
+f9 7f -0.03125
+e5 7f -0.109375
+f9 7f -0.03125
+ c (relative cubeTo), implicit
+ed 7f -0.078125
+f9 7f -0.03125
+d5 7f -0.171875
+f5 7f -0.046875
+b5 7f -0.296875
+f1 7f -0.0625
+e1 z (closePath); end path
+80 Set CREG[CSEL-0] to a 1 byte color
+7c RGBA ffffffff
+91 Set CREG[CSEL-1] to a 3 byte (direct) color
+17 13 11 RGBA 171311ff
+9a Set CREG[CSEL-2] to a 4 byte color
+00 00 00 54 RGBA 00000054
+93 Set CREG[CSEL-3] to a 3 byte (direct) color
+ff fc fb RGBA fffcfbff
+94 Set CREG[CSEL-4] to a 3 byte (direct) color
+c3 8c 74 RGBA c38c74ff
+95 Set CREG[CSEL-5] to a 3 byte (direct) color
+23 20 1f RGBA 23201fff
+c0 Start path, filled with CREG[CSEL-0]; M (absolute moveTo)
+59 7e -1.65625
+fd 73 -12.015625
+d3 a (relative arcTo), 4 reps
+a9 89 +9.65625
+a9 89 +9.65625
+00 0 × 360 degrees (0 degrees)
+04 0x2 (largeArc=0, sweep=1)
+59 76 -9.65625
+a9 89 +9.65625
+ a (relative arcTo), implicit
+a9 89 +9.65625
+a9 89 +9.65625
+00 0 × 360 degrees (0 degrees)
+04 0x2 (largeArc=0, sweep=1)
+59 76 -9.65625
+59 76 -9.65625
+ a (relative arcTo), implicit
+a9 89 +9.65625
+a9 89 +9.65625
+00 0 × 360 degrees (0 degrees)
+04 0x2 (largeArc=0, sweep=1)
+a9 89 +9.65625
+59 76 -9.65625
+ a (relative arcTo), implicit
+a9 89 +9.65625
+a9 89 +9.65625
+00 0 × 360 degrees (0 degrees)
+04 0x2 (largeArc=0, sweep=1)
+a9 89 +9.65625
+a9 89 +9.65625
+e1 z (closePath); end path
+c0 Start path, filled with CREG[CSEL-0]; M (absolute moveTo)
+a9 93 +19.65625
+fd 73 -12.015625
+d3 a (relative arcTo), 4 reps
+51 89 +9.3125
+51 89 +9.3125
+00 0 × 360 degrees (0 degrees)
+04 0x2 (largeArc=0, sweep=1)
+b1 76 -9.3125
+51 89 +9.3125
+ a (relative arcTo), implicit
+51 89 +9.3125
+51 89 +9.3125
+00 0 × 360 degrees (0 degrees)
+04 0x2 (largeArc=0, sweep=1)
+b1 76 -9.3125
+b1 76 -9.3125
+ a (relative arcTo), implicit
+51 89 +9.3125
+51 89 +9.3125
+00 0 × 360 degrees (0 degrees)
+04 0x2 (largeArc=0, sweep=1)
+51 89 +9.3125
+b1 76 -9.3125
+ a (relative arcTo), implicit
+51 89 +9.3125
+51 89 +9.3125
+00 0 × 360 degrees (0 degrees)
+04 0x2 (largeArc=0, sweep=1)
+51 89 +9.3125
+51 89 +9.3125
+e1 z (closePath); end path
+c1 Start path, filled with CREG[CSEL-1]; M (absolute moveTo)
+c1 7c -3.25
+fd 73 -12.015625
+d3 a (relative arcTo), 4 reps
+ed 83 +3.921875
+ed 83 +3.921875
+00 0 × 360 degrees (0 degrees)
+04 0x2 (largeArc=0, sweep=1)
+15 7c -3.921875
+ed 83 +3.921875
+ a (relative arcTo), implicit
+ed 83 +3.921875
+ed 83 +3.921875
+00 0 × 360 degrees (0 degrees)
+04 0x2 (largeArc=0, sweep=1)
+15 7c -3.921875
+15 7c -3.921875
+ a (relative arcTo), implicit
+ed 83 +3.921875
+ed 83 +3.921875
+00 0 × 360 degrees (0 degrees)
+04 0x2 (largeArc=0, sweep=1)
+ed 83 +3.921875
+15 7c -3.921875
+ a (relative arcTo), implicit
+ed 83 +3.921875
+ed 83 +3.921875
+00 0 × 360 degrees (0 degrees)
+04 0x2 (largeArc=0, sweep=1)
+ed 83 +3.921875
+ed 83 +3.921875
+e1 z (closePath); end path
+c1 Start path, filled with CREG[CSEL-1]; M (absolute moveTo)
+25 92 +18.140625
+fd 73 -12.015625
+d3 a (relative arcTo), 4 reps
+ed 83 +3.921875
+ed 83 +3.921875
+00 0 × 360 degrees (0 degrees)
+04 0x2 (largeArc=0, sweep=1)
+15 7c -3.921875
+ed 83 +3.921875
+ a (relative arcTo), implicit
+ed 83 +3.921875
+ed 83 +3.921875
+00 0 × 360 degrees (0 degrees)
+04 0x2 (largeArc=0, sweep=1)
+15 7c -3.921875
+15 7c -3.921875
+ a (relative arcTo), implicit
+ed 83 +3.921875
+ed 83 +3.921875
+00 0 × 360 degrees (0 degrees)
+04 0x2 (largeArc=0, sweep=1)
+ed 83 +3.921875
+15 7c -3.921875
+ a (relative arcTo), implicit
+ed 83 +3.921875
+ed 83 +3.921875
+00 0 × 360 degrees (0 degrees)
+04 0x2 (largeArc=0, sweep=1)
+ed 83 +3.921875
+ed 83 +3.921875
+e1 z (closePath); end path
+c2 Start path, filled with CREG[CSEL-2]; M (absolute moveTo)
+b1 7d -2.3125
+1d 7f -0.890625
+e7 h (relative horizontal lineTo)
+71 84 +4.4375
+b0 c (relative cubeTo), 1 reps
+cd 80 +0.796875
+80 +0
+75 81 +1.453125
+a5 80 +0.640625
+75 81 +1.453125
+75 81 +1.453125
+e9 v (relative vertical lineTo)
+51 85 +5.3125
+b0 c (relative cubeTo), 1 reps
+80 +0
+cd 80 +0.796875
+5d 7f -0.640625
+75 81 +1.453125
+8d 7e -1.453125
+75 81 +1.453125
+e7 h (relative horizontal lineTo)
+91 7b -4.4375
+b0 c (relative cubeTo), 1 reps
+35 7f -0.796875
+80 +0
+8d 7e -1.453125
+5d 7f -0.640625
+8d 7e -1.453125
+8d 7e -1.453125
+e9 v (relative vertical lineTo)
+b1 7a -5.3125
+b0 c (relative cubeTo), 1 reps
+80 +0
+35 7f -0.796875
+a5 80 +0.640625
+8d 7e -1.453125
+75 81 +1.453125
+8d 7e -1.453125
+e1 z (closePath); end path
+c3 Start path, filled with CREG[CSEL-3]; M (absolute moveTo)
+b1 7d -2.3125
+b9 7d -2.28125
+e7 h (relative horizontal lineTo)
+71 84 +4.4375
+b0 c (relative cubeTo), 1 reps
+cd 80 +0.796875
+80 +0
+75 81 +1.453125
+a5 80 +0.640625
+75 81 +1.453125
+75 81 +1.453125
+e9 v (relative vertical lineTo)
+51 85 +5.3125
+b0 c (relative cubeTo), 1 reps
+80 +0
+cd 80 +0.796875
+5d 7f -0.640625
+75 81 +1.453125
+8d 7e -1.453125
+75 81 +1.453125
+e7 h (relative horizontal lineTo)
+91 7b -4.4375
+b0 c (relative cubeTo), 1 reps
+35 7f -0.796875
+80 +0
+8d 7e -1.453125
+5d 7f -0.640625
+8d 7e -1.453125
+8d 7e -1.453125
+e9 v (relative vertical lineTo)
+b1 7a -5.3125
+b0 c (relative cubeTo), 1 reps
+80 +0
+35 7f -0.796875
+a5 80 +0.640625
+8d 7e -1.453125
+75 81 +1.453125
+8d 7e -1.453125
+e1 z (closePath); end path
+c2 Start path, filled with CREG[CSEL-2]; M (absolute moveTo)
+90 +8
+55 80 +0.328125
+b7 c (relative cubeTo), 8 reps
+80 +0
+ad 81 +1.671875
+41 7e -1.75
+89 82 +2.53125
+b5 7b -4.296875
+55 82 +2.328125
+ c (relative cubeTo), implicit
+f5 7f -0.046875
+80 +0
+e9 7f -0.09375
+cd 7e -1.203125
+7d 7f -0.515625
+d5 7e -1.171875
+ c (relative cubeTo), implicit
+7e -1
+15 80 +0.078125
+d1 7d -2.1875
+f5 7f -0.046875
+a1 7c -3.375
+f5 7f -0.046875
+ c (relative cubeTo), implicit
+c9 7e -1.21875
+80 +0
+99 7d -2.40625
+5d 80 +0.359375
+a1 7c -3.375
+09 80 +0.03125
+ c (relative cubeTo), implicit
+c9 7f -0.21875
+ed 7f -0.078125
+a5 7f -0.359375
+2d 81 +1.171875
+7d 7f -0.515625
+29 81 +1.15625
+ c (relative cubeTo), implicit
+85 7d -2.484375
+f1 7f -0.0625
+d9 7b -4.15625
+55 7f -0.671875
+d9 7b -4.15625
+ad 7d -2.328125
+ c (relative cubeTo), implicit
+80 +0
+95 7d -2.421875
+a1 83 +3.625
+9d 7b -4.390625
+1d 88 +8.109375
+9d 7b -4.390625
+ c (relative cubeTo), implicit
+7d 84 +4.484375
+80 +0
+1d 88 +8.109375
+f9 81 +1.96875
+1d 88 +8.109375
+65 84 +4.390625
+e1 z (closePath); end path
+c4 Start path, filled with CREG[CSEL-4]; M (absolute moveTo)
+f5 87 +7.953125
+ad 7e -1.328125
+b6 c (relative cubeTo), 7 reps
+80 +0
+25 81 +1.140625
+21 7f -0.875
+b5 81 +1.703125
+b9 7d -2.28125
+84 +2
+ c (relative cubeTo), implicit
+6d 7f -0.578125
+21 80 +0.125
+bd 7e -1.265625
+31 80 +0.1875
+7c -2
+3d 80 +0.234375
+ c (relative cubeTo), implicit
+e1 7e -1.125
+11 80 +0.0625
+95 7d -2.421875
+11 80 +0.0625
+39 7c -3.78125
+11 80 +0.0625
+ c (relative cubeTo), implicit
+a9 7e -1.34375
+80 +0
+65 7d -2.609375
+80 +0
+45 7c -3.734375
+f1 7f -0.0625
+ c (relative cubeTo), implicit
+65 7f -0.609375
+f9 7f -0.03125
+d5 7e -1.171875
+e9 7f -0.09375
+51 7e -1.6875
+d5 7f -0.171875
+ c (relative cubeTo), implicit
+61 7e -1.625
+bd 7f -0.265625
+59 7d -2.65625
+2d 7f -0.828125
+59 7d -2.65625
+f1 7d -2.0625
+ c (relative cubeTo), implicit
+80 +0
+b1 7d -2.3125
+9d 83 +3.609375
+cd 7b -4.203125
+11 88 +8.0625
+cd 7b -4.203125
+90 s (relative smooth cubeTo), 1 reps
+11 88 +8.0625
+e1 81 +1.875
+11 88 +8.0625
+35 84 +4.203125
+e1 z (closePath); end path
+c5 Start path, filled with CREG[CSEL-5]; M (absolute moveTo)
+0d 84 +4.046875
+f9 7a -5.03125
+d3 a (relative arcTo), 4 reps
+29 84 +4.15625
+b1 82 +2.6875
+00 0 × 360 degrees (0 degrees)
+04 0x2 (largeArc=0, sweep=1)
+d9 7b -4.15625
+b1 82 +2.6875
+ a (relative arcTo), implicit
+29 84 +4.15625
+b1 82 +2.6875
+00 0 × 360 degrees (0 degrees)
+04 0x2 (largeArc=0, sweep=1)
+d9 7b -4.15625
+51 7d -2.6875
+ a (relative arcTo), implicit
+29 84 +4.15625
+b1 82 +2.6875
+00 0 × 360 degrees (0 degrees)
+04 0x2 (largeArc=0, sweep=1)
+29 84 +4.15625
+51 7d -2.6875
+ a (relative arcTo), implicit
+29 84 +4.15625
+b1 82 +2.6875
+00 0 × 360 degrees (0 degrees)
+04 0x2 (largeArc=0, sweep=1)
+29 84 +4.15625
+b1 82 +2.6875
+e1 z (closePath); end path
diff --git a/shiny/iconvg/testdata/favicon.png b/shiny/iconvg/testdata/favicon.png
new file mode 100644
index 0000000..3b38a4b
--- /dev/null
+++ b/shiny/iconvg/testdata/favicon.png
Binary files differ
diff --git a/shiny/iconvg/testdata/favicon.svg b/shiny/iconvg/testdata/favicon.svg
new file mode 100644
index 0000000..81339cf
--- /dev/null
+++ b/shiny/iconvg/testdata/favicon.svg
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg id="svg4416" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="32" width="32" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 32 32.000001">
+ <path id="Z00" style="color-rendering:auto;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;image-rendering:auto" d="m16.092 1.002c-1.1057.01-2.2107.048844-3.3164.089844-2.3441.086758-4.511.88464-6.2832 2.1758a3.8208 3.5794 29.452 0 0 -.8947 -.6856 3.8208 3.5794 29.452 0 0 -5.0879 1.2383 3.8208 3.5794 29.452 0 0 1.5664 4.9961 3.8208 3.5794 29.452 0 0 .3593 .1758c-.2784.9536-.4355 1.9598-.4355 3.0078v20h28v-20c0-1.042-.152-2.0368-.418-2.9766a3.5794 3.8208 60.548 0 0 .43359 -.20703 3.5794 3.8208 60.548 0 0 1.5684 -4.9961 3.5794 3.8208 60.548 0 0 -5.0879 -1.2383 3.5794 3.8208 60.548 0 0 -.92969 .72461c-1.727-1.257-3.843-2.0521-6.1562-2.2148-1.1058-.078-2.2126-.098844-3.3184-.089844z" fill="#384e54"/>
+ <path id="Z01" style="color-rendering:auto;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;image-rendering:auto" d="m16 3c-4.835 0-7.9248 1.0791-9.7617 2.8906-.4777-.4599-1.2937-1.0166-1.6309-1.207-.9775-.5520-2.1879-.2576-2.7051.6582-.5171.9158-.1455 2.1063.8321 2.6582.2658.1501 1.2241.5845 1.7519.7441-.3281.9946-.4863 2.0829-.4863 3.2559v20h24c-.049-7.356 0-18 0-20 0-1.209-.166-2.3308-.516-3.3496.539-.2011 1.243-.5260 1.463-.6504.978-.5519 1.351-1.7424.834-2.6582s-1.729-1.2102-2.707-.6582c-.303.1711-.978.6356-1.463 1.0625-1.854-1.724-4.906-2.7461-9.611-2.7461z" fill="#76e1fe"/>
+ <path id="Z02" style="color-rendering:auto;text-decoration-color:#000000;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;block-progression:tb;text-decoration-line:none;text-decoration-style:solid;image-rendering:auto;white-space:normal;text-indent:0;text-transform:none" d="m3.0918 5.9219c-.060217.00947-.10772.020635-.14648.033203-.019384.00628-.035462.013581-.052734.021484-.00864.00395-.019118.00825-.03125.015625-.00607.00369-.011621.00781-.021484.015625-.00493.00391-.017342.015389-.017578.015625-.0002366.0002356-.025256.031048-.025391.03125a.19867 .19867 0 0 0 .26367 .28320c.0005595-.0002168.00207-.00128.00391-.00195a.19867 .19867 0 0 0 .00391 -.00195c.015939-.00517.045148-.013113.085937-.019531.081581-.012836.20657-.020179.36719.00391.1020.0152.2237.0503.3535.0976-.3277.0694-.5656.1862-.7227.3145-.1143.0933-.1881.1903-.2343.2695-.023099.0396-.039499.074216-.050781.10547-.00564.015626-.00989.029721-.013672.046875-.00189.00858-.00458.017085-.00586.03125-.0006392.00708-.0005029.014724 0 .027344.0002516.00631.00192.023197.00195.023437.0000373.0002412.0097.036937.00977.037109a.19867 .19867 0 0 0 .38477 -.039063 .19867 .19867 0 0 0 0 -.00195c.00312-.00751.00865-.015947.017578-.03125.0230-.0395.0660-.0977.1425-.1601.1530-.1250.4406-.2702.9863-.2871a.19930 .19930 0 0 0 .082031 -.019531c.12649.089206.25979.19587.39844.32422a.19867 .19867 0 1 0 .2696 -.2911c-.6099-.5646-1.1566-.7793-1.5605-.8398-.2020-.0303-.3679-.0229-.4883-.0039z" fill-rule="evenodd" fill="#384e54"/>
+ <path id="Z03" style="color-rendering:auto;text-decoration-color:#000000;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;block-progression:tb;text-decoration-line:none;text-decoration-style:solid;image-rendering:auto;white-space:normal;text-indent:0;text-transform:none" d="m28.543 5.8203c-.12043-.018949-.28631-.026379-.48828.00391-.40394.060562-.94869.27524-1.5586.83984a.19867 .19867 0 1 0 .26953 .29102c.21354-.19768.40814-.33222.59180-.44141.51624.023399.79659.16181.94531.28320.07652.062461.11952.12063.14258.16016.0094.016037.01458.025855.01758.033203a.19867 .19867 0 0 0 .38476 .039063c.000062-.0001719.0097-.036868.0098-.037109.000037-.0002412.0017-.017125.002-.023437.000505-.012624.000639-.020258 0-.027344-.0013-.01417-.004-.022671-.0059-.03125-.0038-.017158-.008-.031248-.01367-.046875-.01128-.031254-.02768-.067825-.05078-.10742-.04624-.079195-.12003-.17424-.23437-.26758-.11891-.097066-.28260-.18832-.49609-.25781.01785-.00328.03961-.011119.05664-.013672.16062-.024082.28561-.016738.36719-.00391.03883.00611.06556.012409.08203.017578.000833.0002613.0031.0017.0039.00195a.19867 .19867 0 0 0 .271 -.2793c-.000135-.0002016-.02515-.031014-.02539-.03125-.000236-.0002356-.01265-.011717-.01758-.015625-.0099-.00782-.01737-.01194-.02344-.015625-.01213-.00737-.02066-.011673-.0293-.015625-.01727-.0079-.03336-.013247-.05273-.019531-.03877-.012568-.08822-.025682-.14844-.035156z" fill-rule="evenodd" fill="#384e54"/>
+ <path id="Z04" style="color-rendering:auto;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;image-rendering:auto" d="m15.171 9.992a4.8316 4.8316 0 0 1 -4.832 4.832 4.8316 4.8316 0 0 1 -4.8311 -4.832 4.8316 4.8316 0 0 1 4.8311 -4.8316 4.8316 4.8316 0 0 1 4.832 4.8316z" fill="#fff"/>
+ <path id="Z05" style="color-rendering:auto;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;image-rendering:auto" d="m25.829 9.992a4.6538 4.6538 0 0 1 -4.653 4.654 4.6538 4.6538 0 0 1 -4.654 -4.654 4.6538 4.6538 0 0 1 4.654 -4.6537 4.6538 4.6538 0 0 1 4.653 4.6537z" fill="#fff"/>
+ <path id="Z06" style="color-rendering:auto;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;image-rendering:auto" d="m14.377 9.992a1.9631 1.9631 0 0 1 -1.963 1.963 1.9631 1.9631 0 0 1 -1.963 -1.963 1.9631 1.9631 0 0 1 1.963 -1.963 1.9631 1.9631 0 0 1 1.963 1.963z" fill="#171311"/>
+ <path id="Z07" style="color-rendering:auto;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;image-rendering:auto" d="m25.073 9.992a1.9631 1.9631 0 0 1 -1.963 1.963 1.9631 1.9631 0 0 1 -1.963 -1.963 1.9631 1.9631 0 0 1 1.963 -1.963 1.9631 1.9631 0 0 1 1.963 1.963z" fill="#171311"/>
+ <path id="Z08" style="color-rendering:auto;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;image-rendering:auto" d="m14.842 15.555h2.2156c.40215 0 .72590.3237.72590.7259v2.6545c0 .4021-.32375.7259-.72590.7259h-2.2156c-.40215 0-.72590-.3238-.72590-.7259v-2.6545c0-.4022.32375-.7259.72590-.7259z" fill-opacity=".32941"/>
+ <path id="Z09" style="color-rendering:auto;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;image-rendering:auto" d="m14.842 14.863h2.2156c.40215 0 .72590.3238.72590.7259v2.6546c0 .4021-.32375.7259-.72590.7259h-2.2156c-.40215 0-.72590-.3238-.72590-.7259v-2.6546c0-.4021.32375-.7259.72590-.7259z" fill="#fffcfb"/>
+ <path id="Z10" style="color-rendering:auto;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;image-rendering:auto" d="m20 16.167c0 .838-.87123 1.2682-2.1448 1.1659-.02366 0-.04795-.6004-.25415-.5832-.50367.042-1.0959-.02-1.686-.02-.61294 0-1.2063.1826-1.6855.017-.11023-.038-.17830.5838-.26153.5816-1.2437-.033-2.0788-.3383-2.0788-1.1618 0-1.2118 1.8156-2.1941 4.0554-2.1941 2.2397 0 4.0554.9823 4.0554 2.1941z" fill-opacity=".32941"/>
+ <path id="Z11" style="color-rendering:auto;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;image-rendering:auto" d="m19.977 15.338c0 .5685-.43366.8554-1.1381 1.0001-.29193.06-.63037.096-1.0037.1166-.56405.032-1.2078.031-1.8912.031-.67283 0-1.3072 0-1.8649-.029-.30627-.017-.58943-.043-.84316-.084-.81383-.1318-1.325-.417-1.325-1.0344 0-1.1601 1.8056-2.1006 4.033-2.1006s4.033.9405 4.033 2.1006z" fill="#c38c74"/>
+ <path id="Z12" style="color-rendering:auto;color:#000000;isolation:auto;mix-blend-mode:normal;shape-rendering:auto;solid-color:#000000;image-rendering:auto" d="m18.025 13.488a2.0802 1.3437 0 0 1 -2.0802 1.3437 2.0802 1.3437 0 0 1 -2.0802 -1.3437 2.0802 1.3437 0 0 1 2.0802 -1.3437 2.0802 1.3437 0 0 1 2.0802 1.3437z" fill="#23201f"/>
+</svg>