From 44a0f814764a245c489aba53b664e2822ba80713 Mon Sep 17 00:00:00 2001 From: Edward Muller Date: Mon, 12 Oct 2015 15:50:09 -0700 Subject: [PATCH 1/2] Vendor dependencies Using go1.5.1 and the GO15VENDOREXPERIMENT=1 --- Godeps/Godeps.json | 14 + Godeps/Readme | 5 + vendor/github.com/ajstarks/svgo/LICENSE | 3 + .../github.com/ajstarks/svgo/README.markdown | 668 ++++++++++++ .../ajstarks/svgo/android/android.go | 55 + .../ajstarks/svgo/barchart/barchart.go | 472 +++++++++ .../ajstarks/svgo/benchviz/benchviz.go | 238 +++++ .../ajstarks/svgo/bubtrail/bubtrail.go | 67 ++ .../ajstarks/svgo/bulletgraph/bulletgraph.go | 233 +++++ .../ajstarks/svgo/codepic/codepic.go | 182 ++++ .../ajstarks/svgo/colortab/colortab.go | 89 ++ .../ajstarks/svgo/colortab/svgcolors.txt | 147 +++ .../github.com/ajstarks/svgo/compx/comps.xml | 16 + .../github.com/ajstarks/svgo/compx/compx.go | 894 ++++++++++++++++ .../ajstarks/svgo/compx/testcomp.xml | 69 ++ vendor/github.com/ajstarks/svgo/cube/cube.go | 71 ++ vendor/github.com/ajstarks/svgo/doc.go | 118 +++ vendor/github.com/ajstarks/svgo/f50/f50.go | 120 +++ vendor/github.com/ajstarks/svgo/fe/fe.go | 53 + .../github.com/ajstarks/svgo/flower/flower.go | 79 ++ .../ajstarks/svgo/fontcompare/fontcompare.go | 52 + .../github.com/ajstarks/svgo/funnel/funnel.go | 29 + .../ajstarks/svgo/gradient/gradient.go | 58 ++ .../ajstarks/svgo/html5logo/html5logo.go | 41 + .../github.com/ajstarks/svgo/imfade/imfade.go | 32 + .../github.com/ajstarks/svgo/lewitt/lewitt.go | 84 ++ vendor/github.com/ajstarks/svgo/ltr/ltr.go | 178 ++++ .../github.com/ajstarks/svgo/marker/marker.go | 39 + vendor/github.com/ajstarks/svgo/newsvg | 39 + .../github.com/ajstarks/svgo/paths/paths.go | 31 + .../ajstarks/svgo/pattern/pattern.go | 33 + .../github.com/ajstarks/svgo/picserv/index.go | 127 +++ .../ajstarks/svgo/picserv/pic256.html | 124 +++ .../ajstarks/svgo/picserv/picserv.go | 672 ++++++++++++ .../ajstarks/svgo/planets/planets.go | 122 +++ vendor/github.com/ajstarks/svgo/pmap/pmap.go | 244 +++++ .../ajstarks/svgo/randcomp/randcomp.go | 59 ++ .../ajstarks/svgo/richter/richter.go | 35 + vendor/github.com/ajstarks/svgo/rl/rl.go | 34 + vendor/github.com/ajstarks/svgo/rpd/rpd.go | 80 ++ vendor/github.com/ajstarks/svgo/rpd/thing.xml | 5 + vendor/github.com/ajstarks/svgo/rr/rr.go | 208 ++++ .../ajstarks/svgo/shotchart/shotchart.go | 150 +++ .../ajstarks/svgo/skewabc/skewabc.go | 37 + .../svgo/stockproduct/stockproduct.go | 179 ++++ vendor/github.com/ajstarks/svgo/svg.go | 978 ++++++++++++++++++ vendor/github.com/ajstarks/svgo/svgdef.pdf | Bin 0 -> 234105 bytes vendor/github.com/ajstarks/svgo/svgdef.svg | 395 +++++++ .../github.com/ajstarks/svgo/svgdef/svgdef.go | 536 ++++++++++ .../ajstarks/svgo/svgopher/svgopher.go | 76 ++ .../ajstarks/svgo/svgplay/svgplay.go | 291 ++++++ .../ajstarks/svgo/svgplot/mksvgplotdef | 24 + .../ajstarks/svgo/svgplot/svgplot.go | 314 ++++++ .../github.com/ajstarks/svgo/svgplot/test.d | 51 + .../github.com/ajstarks/svgo/svgrid/svgrid.go | 107 ++ vendor/github.com/ajstarks/svgo/tsg/tsg.go | 126 +++ .../github.com/ajstarks/svgo/tumblrgrid/tlist | 4 + .../ajstarks/svgo/tumblrgrid/tumblrgrid.go | 218 ++++ .../ajstarks/svgo/turbulence/turbulence.go | 73 ++ .../github.com/ajstarks/svgo/vismem/vismem.go | 51 + .../ajstarks/svgo/webfonts/webfonts.go | 62 ++ .../github.com/ajstarks/svgo/websvg/websvg.go | 73 ++ 62 files changed, 9664 insertions(+) create mode 100644 Godeps/Godeps.json create mode 100644 Godeps/Readme create mode 100644 vendor/github.com/ajstarks/svgo/LICENSE create mode 100644 vendor/github.com/ajstarks/svgo/README.markdown create mode 100644 vendor/github.com/ajstarks/svgo/android/android.go create mode 100644 vendor/github.com/ajstarks/svgo/barchart/barchart.go create mode 100644 vendor/github.com/ajstarks/svgo/benchviz/benchviz.go create mode 100644 vendor/github.com/ajstarks/svgo/bubtrail/bubtrail.go create mode 100644 vendor/github.com/ajstarks/svgo/bulletgraph/bulletgraph.go create mode 100644 vendor/github.com/ajstarks/svgo/codepic/codepic.go create mode 100644 vendor/github.com/ajstarks/svgo/colortab/colortab.go create mode 100644 vendor/github.com/ajstarks/svgo/colortab/svgcolors.txt create mode 100644 vendor/github.com/ajstarks/svgo/compx/comps.xml create mode 100644 vendor/github.com/ajstarks/svgo/compx/compx.go create mode 100644 vendor/github.com/ajstarks/svgo/compx/testcomp.xml create mode 100644 vendor/github.com/ajstarks/svgo/cube/cube.go create mode 100644 vendor/github.com/ajstarks/svgo/doc.go create mode 100644 vendor/github.com/ajstarks/svgo/f50/f50.go create mode 100644 vendor/github.com/ajstarks/svgo/fe/fe.go create mode 100644 vendor/github.com/ajstarks/svgo/flower/flower.go create mode 100644 vendor/github.com/ajstarks/svgo/fontcompare/fontcompare.go create mode 100644 vendor/github.com/ajstarks/svgo/funnel/funnel.go create mode 100644 vendor/github.com/ajstarks/svgo/gradient/gradient.go create mode 100644 vendor/github.com/ajstarks/svgo/html5logo/html5logo.go create mode 100644 vendor/github.com/ajstarks/svgo/imfade/imfade.go create mode 100644 vendor/github.com/ajstarks/svgo/lewitt/lewitt.go create mode 100644 vendor/github.com/ajstarks/svgo/ltr/ltr.go create mode 100644 vendor/github.com/ajstarks/svgo/marker/marker.go create mode 100644 vendor/github.com/ajstarks/svgo/newsvg create mode 100644 vendor/github.com/ajstarks/svgo/paths/paths.go create mode 100644 vendor/github.com/ajstarks/svgo/pattern/pattern.go create mode 100644 vendor/github.com/ajstarks/svgo/picserv/index.go create mode 100644 vendor/github.com/ajstarks/svgo/picserv/pic256.html create mode 100644 vendor/github.com/ajstarks/svgo/picserv/picserv.go create mode 100644 vendor/github.com/ajstarks/svgo/planets/planets.go create mode 100644 vendor/github.com/ajstarks/svgo/pmap/pmap.go create mode 100644 vendor/github.com/ajstarks/svgo/randcomp/randcomp.go create mode 100644 vendor/github.com/ajstarks/svgo/richter/richter.go create mode 100644 vendor/github.com/ajstarks/svgo/rl/rl.go create mode 100644 vendor/github.com/ajstarks/svgo/rpd/rpd.go create mode 100644 vendor/github.com/ajstarks/svgo/rpd/thing.xml create mode 100644 vendor/github.com/ajstarks/svgo/rr/rr.go create mode 100644 vendor/github.com/ajstarks/svgo/shotchart/shotchart.go create mode 100644 vendor/github.com/ajstarks/svgo/skewabc/skewabc.go create mode 100644 vendor/github.com/ajstarks/svgo/stockproduct/stockproduct.go create mode 100644 vendor/github.com/ajstarks/svgo/svg.go create mode 100644 vendor/github.com/ajstarks/svgo/svgdef.pdf create mode 100644 vendor/github.com/ajstarks/svgo/svgdef.svg create mode 100644 vendor/github.com/ajstarks/svgo/svgdef/svgdef.go create mode 100644 vendor/github.com/ajstarks/svgo/svgopher/svgopher.go create mode 100644 vendor/github.com/ajstarks/svgo/svgplay/svgplay.go create mode 100644 vendor/github.com/ajstarks/svgo/svgplot/mksvgplotdef create mode 100644 vendor/github.com/ajstarks/svgo/svgplot/svgplot.go create mode 100644 vendor/github.com/ajstarks/svgo/svgplot/test.d create mode 100644 vendor/github.com/ajstarks/svgo/svgrid/svgrid.go create mode 100644 vendor/github.com/ajstarks/svgo/tsg/tsg.go create mode 100644 vendor/github.com/ajstarks/svgo/tumblrgrid/tlist create mode 100644 vendor/github.com/ajstarks/svgo/tumblrgrid/tumblrgrid.go create mode 100644 vendor/github.com/ajstarks/svgo/turbulence/turbulence.go create mode 100644 vendor/github.com/ajstarks/svgo/vismem/vismem.go create mode 100644 vendor/github.com/ajstarks/svgo/webfonts/webfonts.go create mode 100644 vendor/github.com/ajstarks/svgo/websvg/websvg.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json new file mode 100644 index 0000000..b22a6f2 --- /dev/null +++ b/Godeps/Godeps.json @@ -0,0 +1,14 @@ +{ + "ImportPath": "github.com/cupcake/sigil", + "GoVersion": "go1.5.1", + "Packages": [ + "./..." + ], + "Deps": [ + { + "ImportPath": "github.com/ajstarks/svgo", + "Comment": "go.weekly.2012-01-27-112-g7729261", + "Rev": "77292617dc6b7ef6c9813385a6b6089969997285" + } + ] +} diff --git a/Godeps/Readme b/Godeps/Readme new file mode 100644 index 0000000..4cdaa53 --- /dev/null +++ b/Godeps/Readme @@ -0,0 +1,5 @@ +This directory tree is generated automatically by godep. + +Please do not edit. + +See https://github.com/tools/godep for more information. diff --git a/vendor/github.com/ajstarks/svgo/LICENSE b/vendor/github.com/ajstarks/svgo/LICENSE new file mode 100644 index 0000000..ea5a772 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/LICENSE @@ -0,0 +1,3 @@ +The contents of this repository are Licensed under +the Creative Commons Attribution 3.0 license as described in +http://creativecommons.org/licenses/by/3.0/us/ diff --git a/vendor/github.com/ajstarks/svgo/README.markdown b/vendor/github.com/ajstarks/svgo/README.markdown new file mode 100644 index 0000000..2e5fadb --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/README.markdown @@ -0,0 +1,668 @@ +#SVGo: A Go library for SVG generation# + +The library generates SVG as defined by the Scalable Vector Graphics 1.1 Specification (). +Output goes to the specified io.Writer. + +## Supported SVG elements and functions ## + +### Shapes, lines, text + + circle, ellipse, polygon, polyline, rect (including roundrects), line, text + +### Paths + + general, arc, cubic and quadratic bezier paths, + +### Image and Gradients + + image, linearGradient, radialGradient, + +### Transforms ### + + translate, rotate, scale, skewX, skewY + +### Filter Effects + + filter, feBlend, feColorMatrix, feColorMatrix, feComponentTransfer, feComposite, feConvolveMatrix, feDiffuseLighting, + feDisplacementMap, feDistantLight, feFlood, feGaussianBlur, feImage, feMerge, feMorphology, feOffset, fePointLight, + feSpecularLighting, feSpotLight,feTile, feTurbulence + + +### Metadata elements ### + + desc, defs, g (style, transform, id), marker, mask, pattern, title, (a)ddress, link, script, use + +## Building and Usage ## + +See svgdef.[svg|png|pdf] for a graphical view of the function calls + + +Usage: (assuming GOPATH is set) + + go get github.com/ajstarks/svgo + go install github.com/ajstarks/svgo/... + + +You can use godoc to browse the documentation from the command line: + + $ godoc github.com/ajstarks/svgo + + +a minimal program, to generate SVG to standard output. + + package main + + import ( + "github.com/ajstarks/svgo" + "os" + ) + + func main() { + width := 500 + height := 500 + canvas := svg.New(os.Stdout) + canvas.Start(width, height) + canvas.Circle(width/2, height/2, 100) + canvas.Text(width/2, height/2, "Hello, SVG", "text-anchor:middle;font-size:30px;fill:white") + canvas.End() + } + +Drawing in a web server: (http://localhost:2003/circle) + + package main + + import ( + "log" + "github.com/ajstarks/svgo" + "net/http" + ) + + func main() { + http.Handle("/circle", http.HandlerFunc(circle)) + err := http.ListenAndServe(":2003", nil) + if err != nil { + log.Fatal("ListenAndServe:", err) + } + } + + func circle(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Content-Type", "image/svg+xml") + s := svg.New(w) + s.Start(500, 500) + s.Circle(250, 250, 125, "fill:none;stroke:black") + s.End() + } + +You may view the SVG output with a browser that supports SVG (tested on Chrome, Opera, Firefox and Safari), or any other SVG user-agent such as Batik Squiggle. + +### Graphics Sketching with SVGo and svgplay ### + +Combined with the svgplay command, SVGo can be used to "sketch" with code in a browser. + +To use svgplay and SVGo, first go to a directory with your code, and run: + + $ svgplay + 2014/06/25 22:05:28 ☠ ☠ ☠ Warning: this server allows a client connecting to 127.0.0.1:1999 to execute code on this computer ☠ ☠ ☠ + +Next open your browser to the svgplay server you just started. +svgplay only listens on localhost, and uses port 1999 (guess which year SVG was first introduced) by default + + http://localhost:1999/ + +Enter your code in the textarea, and when you are ready to run press Shift--Enter. The code will be compiled, with the results +on the right. To update, change the code and repeat. Note that compilation errors are shown in red under the code. In order for svgplay/SVGo to work, make sure that the io.Writer specified with the New function is os.Stdout. + + +If you want to sketch with an existing file, enter its URL: + + http://localhost:1999/foo.go + +![SVGplay](https://farm4.staticflickr.com/3859/14322978157_31c0114850.jpg) + + +### SVGo Papers and presentations ### + +* SVGo paper from SVGOpen 2011 + +* Programming Pictures with SVGo + +* SVGo Workshop + + +### Tutorial Video ### + +A video describing how to use the package can be seen on YouTube at + +## Package contents ## + +* svg.go: Library +* newsvg: Coding template command +* svgdef: Creates a SVG representation of the API +* android: The Android logo +* bubtrail: Bubble trails +* bulletgraph: Bullet Graphs (via Stephen Few) +* colortab: Display SVG named colors with RGB values +* compx: Component diagrams +* flower: Random "flowers" +* fontcompare: Compare two fonts +* f50: Get 50 photos from Flickr based on a query +* fe: Filter effects +* funnel: Funnel from transparent circles +* gradient: Linear and radial gradients +* html5logo: HTML5 logo with draggable elements +* imfade: Show image fading +* lewitt: Version of Sol Lewitt's Wall Drawing 91 +* ltr: Layer Tennis Remixes +* marker: Test markers +* paths: Demonstrate SVG paths +* pattern: Test patterns +* planets: Show the scale of the Solar system +* pmap: Proportion maps +* randcomp: Compare random number generators +* richter: Gerhard Richter's 256 colors +* rl: Random lines (port of a Processing demo) +* skewabc: Skew ABC +* stockproduct: Visualize product and stock prices +* svgopher: SVGo Mascot +* svgplay: SVGo sketching server +* svgplot: Plot data +* svgrid: Compose SVG files in a grid +* tsg: Twitter Search Grid +* tumblrgrid: Tumblr picture grid +* turbulence: Turbulence filter effect +* vismem: Visualize data from files +* webfonts: "Hello, World" with Google Web Fonts +* websvg: Generate SVG as a web server + + +## Functions and types ## + +Many functions use x, y to specify an object's location, and w, h to specify the object's width and height. +Where applicable, a final optional argument specifies the style to be applied to the object. +The style strings follow the SVG standard; name:value pairs delimited by semicolons, or a +series of name="value" pairs. For example: `"fill:none; opacity:0.3"` or `fill="none" opacity="0.3"` (see: ) + +The Offcolor type: + + type Offcolor struct { + Offset uint8 + Color string + Opacity float + } + +is used to specify the offset, color, and opacity of stop colors in linear and radial gradients + +The Filterspec type: + + type Filterspec struct { + In string + In2 string + Result string + } + +is used to specify inputs and results for filter effects + + +### Structure, Scripting, Metadata, Transformation and Links ### + + New(w io.Writer) *SVG + Constructor, Specify the output destination. + + Start(w int, h int, attributes ...string) + begin the SVG document with the width w and height h. Optionally add additional elememts + (such as additional namespaces or scripting events) + + + Startview(w, h, minx, miny, vw, vh int) + begin the SVG document with the width w, height h, with a viewBox at minx, miny, vw, vh. + + + Startunit(w int, h int, unit string, ns ...string) + begin the SVG document, with width and height in the specified units. Optionally add additional elememts + (such as additional namespaces or scripting events) + + + + Startpercent(w int, h int, ns ...string) + begin the SVG document, with width and height in percent. Optionally add additional elememts + (such as additional namespaces or scripting events) + + + + StartviewUnit(w, h int, unit string, minx, miny, vw, vh int) + begin the SVG document with the width w, height h, in the specified unit, with a viewBox at minx, miny, vw, vh. + + + End() + end the SVG document + + Script(scriptype string, data ...string) + Script defines a script with a specified type, (for example "application/javascript"). + if the first variadic argument is a link, use only the link reference. + Otherwise, treat variadic arguments as the text of the script (marked up as CDATA). + if no data is specified, simply close the script element. + + + Group(s ...string) + begin a group, with arbitrary attributes + + + Gstyle(s string) + begin a group, with the specified style. + + + Gid(s string) + begin a group, with the specified id. + + Gtransform(s string) + begin a group, with the specified transform, end with Gend(). + + + Translate(x, y int) + begins coordinate translation to (x,y), end with Gend(). + + + Scale(n float64) + scales the coordinate system by n, end with Gend(). + + + ScaleXY(x, y float64) + scales the coordinate system by x, y. End with Gend(). + + + SkewX(a float64) + SkewX skews the x coordinate system by angle a, end with Gend(). + + + SkewY(a float64) + SkewY skews the y coordinate system by angle a, end with Gend(). + + + SkewXY(ax, ay float64) + SkewXY skews x and y coordinate systems by ax, ay respectively, end with Gend(). + + + Rotate(r float64) + rotates the coordinate system by r degrees, end with Gend(). + + + TranslateRotate(x, y int, r float64) + translates the coordinate system to (x,y), then rotates to r degrees, end with Gend(). + + RotateTranslate(x, y int, r float64) + rotates the coordinate system r degrees, then translates to (x,y), end with Gend(). + + Gend() + end the group (must be paired with Gstyle, Gtransform, Gid). + + ClipPath(s ...string) + Begin a ClipPath + + + ClipEnd() + End a ClipPath + + + Def() + begin a definition block. + + + DefEnd() + end a definition block. + + Marker(id string, x, y, w, h int, s ...string) + define a marker + + + + MarkerEnd() + end a marker + + + Mask(id string, x int, y int, w int, h int, s ...string) + creates a mask with a specified id, dimension, and optional style. + + + MaskEnd() + ends the Mask element. + + + Pattern(id string, x, y, width, height int, putype string, s ...string) + define a Pattern with the specified dimensions, the putype can be either "user" or "obj", which sets the patternUnits + attribute to be either userSpaceOnUse or objectBoundingBox. + + + Desc(s string) + specify the text of the description. + + + Title(s string) + specify the text of the title. + + + Link(href string, title string) + begin a link named "href", with the specified title. + + + LinkEnd() + end the link. + + Use(x int, y int, link string, s ...string) + place the object referenced at link at the location x, y. + + +### Shapes ### + + Circle(x int, y int, r int, s ...string) + draw a circle, centered at x,y with radius r. + + + ![Circle](http://farm5.static.flickr.com/4144/5187953823_01a1741489_m.jpg) + + Ellipse(x int, y int, w int, h int, s ...string) + draw an ellipse, centered at x,y with radii w, and h. + + + ![Ellipse](http://farm2.static.flickr.com/1271/5187953773_a9d1fc406c_m.jpg) + + Polygon(x []int, y []int, s ...string) + draw a series of line segments using an array of x, y coordinates. + + + ![Polygon](http://farm2.static.flickr.com/1006/5187953873_337dc26597_m.jpg) + + Rect(x int, y int, w int, h int, s ...string) + draw a rectangle with upper left-hand corner at x,y, with width w, and height h. + + + ![Rect](http://farm2.static.flickr.com/1233/5188556032_86c90e354b_m.jpg) + + CenterRect(x int, y int, w int, h int, s ...string) + draw a rectangle with its center at x,y, with width w, and height h. + + Roundrect(x int, y int, w int, h int, rx int, ry int, s ...string) + draw a rounded rectangle with upper the left-hand corner at x,y, + with width w, and height h. The radii for the rounded portion + is specified by rx (width), and ry (height). + + ![Roundrect](http://farm2.static.flickr.com/1275/5188556120_e2a9998fee_m.jpg) + + Square(x int, y int, s int, style ...string) + draw a square with upper left corner at x,y with sides of length s. + + ![Square](http://farm5.static.flickr.com/4110/5187953659_54dcce242e_m.jpg) + +### Paths ### + + Path(p string, s ...style) + draw the arbitrary path as specified in p, according to the style specified in s. + + + Arc(sx int, sy int, ax int, ay int, r int, large bool, sweep bool, ex int, ey int, s ...string) + draw an elliptical arc beginning coordinate at sx,sy, ending coordinate at ex, ey + width and height of the arc are specified by ax, ay, the x axis rotation is r + + if sweep is true, then the arc will be drawn in a "positive-angle" direction (clockwise), + if false, the arc is drawn counterclockwise. + + if large is true, the arc sweep angle is greater than or equal to 180 degrees, + otherwise the arc sweep is less than 180 degrees. + + + ![Arc](http://farm2.static.flickr.com/1300/5188556148_df1a176074_m.jpg) + + + + Bezier(sx int, sy int, cx int, cy int, px int, py int, ex int, ey int, s ...string) + draw a cubic bezier curve, beginning at sx,sy, ending at ex,ey + with control points at cx,cy and px,py. + + + ![Bezier](http://farm2.static.flickr.com/1233/5188556246_a03e67d013.jpg) + + + + Qbezier(sx int, sy int, cx int, cy int, ex int, ey int, tx int, ty int, s ...string) + draw a quadratic bezier curve, beginning at sx, sy, ending at tx,ty + with control points are at cx,cy, ex,ey. + + + ![Qbezier](http://farm2.static.flickr.com/1018/5187953917_9a43cf64fb.jpg) + + + Qbez(sx int, sy int, cx int, cy int, ex int, ey int, s...string) + draws a quadratic bezier curver, with optional style beginning at sx,sy, ending at ex, sy + with the control point at cx, cy. + + + ![Qbez](http://farm6.static.flickr.com/5176/5569879349_5f726aab5e.jpg) + +### Lines ### + + Line(x1 int, y1 int, x2 int, y2 int, s ...string) + draw a line segment between x1,y1 and x2,y2. + + + ![Line](http://farm5.static.flickr.com/4154/5188556080_0be19da0bc.jpg) + + + Polyline(x []int, y []int, s ...string) + draw a polygon using coordinates specified in x,y arrays. + + + ![Polyline](http://farm2.static.flickr.com/1266/5188556384_a863273a69.jpg) + +### Image and Text ### + + Image(x int, y int, w int, h int, link string, s ...string) + place at x,y (upper left hand corner), the image with width w, and height h, referenced at link. + + + ![Image](http://farm5.static.flickr.com/4058/5188556346_e5ce3dcbc2_m.jpg) + + Text(x int, y int, t string, s ...string) + Place the specified text, t at x,y according to the style specified in s. + + + Textlines(x, y int, s []string, size, spacing int, fill, align string) + Places lines of text in s, starting at x,y, at the specified size, fill, and alignment, and spacing. + + Textpath(t string, pathid string, s ...string) + places optionally styled text along a previously defined path. + + ![Image](http://farm4.static.flickr.com/3149/5694580737_4b291df768_m.jpg) + +### Color ### + + RGB(r int, g int, b int) string + creates a style string for the fill color designated + by the (r)ed, g(reen), (b)lue components. + + + RGBA(r int, g int, b int, a float64) string + as above, but includes the color's opacity as a value + between 0.0 (fully transparent) and 1.0 (opaque). + +### Gradients ### + + LinearGradient(id string, x1, y1, x2, y2 uint8, sc []Offcolor) + constructs a linear color gradient identified by id, + along the vector defined by (x1,y1), and (x2,y2). + The stop color sequence defined in sc. Coordinates are expressed as percentages. + + ![LinearGradient](http://farm5.static.flickr.com/4153/5187954033_3972f63fa9.jpg) + + RadialGradient(id string, cx, cy, r, fx, fy uint8, sc []Offcolor) + constructs a radial color gradient identified by id, + centered at (cx,cy), with a radius of r. + (fx, fy) define the location of the focal point of the light source. + The stop color sequence defined in sc. + Coordinates are expressed as percentages. + + + ![RadialGradient](http://farm2.static.flickr.com/1302/5187954065_7ddba7b819.jpg) + +### Filter Effects ### + + Filter(id string, s ...string) + Filter begins a filter set +Standard reference: + + Fend() +Fend ends a filter set +Standard reference: + + FeBlend(fs Filterspec, mode string, s ...string) +FeBlend specifies a Blend filter primitive +Standard reference: + + FeColorMatrix(fs Filterspec, values [20]float64, s ...string) +FeColorMatrix specifies a color matrix filter primitive, with matrix values +Standard reference: + + FeColorMatrixHue(fs Filterspec, value float64, s ...string) +FeColorMatrix specifies a color matrix filter primitive, with hue values +Standard reference: + + FeColorMatrixSaturate(fs Filterspec, value float64, s ...string) +FeColorMatrix specifies a color matrix filter primitive, with saturation values +Standard reference: + + FeColorMatrixLuminence(fs Filterspec, s ...string) +FeColorMatrix specifies a color matrix filter primitive, with luminence values +Standard reference: + + FeComponentTransfer() +FeComponentTransfer begins a feComponent filter Element> +Standard reference: + + FeCompEnd() +FeCompEnd ends a feComponent filter Element> + + FeComposite(fs Filterspec, operator string, k1, k2, k3, k4 int, s ...string) +FeComposite specifies a feComposite filter primitive +Standard reference: + + FeConvolveMatrix(fs Filterspec, matrix [9]int, s ...string) +FeConvolveMatrix specifies a feConvolveMatrix filter primitive +Standard referencd: + + + FeDiffuseLighting(fs Filterspec, scale, constant float64, s ...string) +FeDiffuseLighting specifies a diffuse lighting filter primitive, +a container for light source Element>s, end with DiffuseEnd() + + FeDiffEnd() +FeDiffuseEnd ends a diffuse lighting filter primitive container +Standard reference: + + + FeDisplacementMap(fs Filterspec, scale float64, xchannel, ychannel string, s ...string) +FeDisplacementMap specifies a feDisplacementMap filter primitive +Standard reference: + + FeDistantLight(fs Filterspec, azimuth, elevation float64, s ...string) +FeDistantLight specifies a feDistantLight filter primitive +Standard reference: + + FeFlood(fs Filterspec, color string, opacity float64, s ...string) +FeFlood specifies a flood filter primitive +Standard reference: + + FeFuncLinear(channel string, slope, intercept float64) +FeFuncLinear is the linear form of feFunc +Standard reference: + + FeFuncGamma(channel, amplitude, exponent, offset float64) +FeFuncGamma is the gamma curve form of feFunc +Standard reference: + + FeFuncTable(channel string, tv []float64) +FeFuncGamma is the form of feFunc using a table of values +Standard reference: + + FeFuncDiscrete(channel string, tv []float64) +FeFuncGamma is the form of feFunc using discrete values +Standard reference: + + FeGaussianBlur(fs Filterspec, stdx, stdy float64, s ...string) +FeGaussianBlur specifies a Gaussian Blur filter primitive +Standard reference: + + FeImage(href string, result string, s ...string) +FeImage specifies a feImage filter primitive +Standard reference: + + FeMerge(nodes []string, s ...string) +FeMerge specifies a feMerge filter primitive, containing feMerge Element>s +Standard reference: + + FeMorphology(fs Filterspec, operator string, xradius, yradius float64, s ...string) +FeMorphologyLight specifies a feMorphologyLight filter primitive +Standard reference: + + FeOffset(fs Filterspec, dx, dy int, s ...string) +FeOffset specifies the feOffset filter primitive +Standard reference: + + FePointLight(x, y, z float64, s ...string) +FePointLight specifies a fePpointLight filter primitive +Standard reference: + + FeSpecularLighting(fs Filterspec, scale, constant float64, exponent int, color string, s ...string) +FeSpecularLighting specifies a specular lighting filter primitive, +a container for light source elements, end with SpecularEnd() + + + FeSpecEnd() +FeSpecularEnd ends a specular lighting filter primitive container +Standard reference: + + + FeSpotLight(fs Filterspec, x, y, z, px, py, pz float64, s ...string) +FeSpotLight specifies a feSpotLight filter primitive +Standard reference: + + FeTile(fs Filterspec, in string, s ...string) +FeTile specifies the tile utility filter primitive +Standard reference: + + + FeTurbulence(fs Filterspec, ftype string, bfx, bfy float64, octaves int, seed int64, stitch bool, s ...string) +FeTurbulence specifies a turbulence filter primitive +Standard reference: + +### Filter convenience functions (modeled on CSS filter effects) ### + + Blur(p float64) +Blur function by standard deviation + + Brightness(p float64) +Brightness function (0-100) + + Grayscale() +Apply a grayscale filter to the image + + HueRotate(a float64) +Rotate Hues (0-360 degrees) + + Invert() +Invert the image's colors + + Saturate(p float64) +Percent saturation, 0 is grayscale + + Sepia() +Apply sepia tone + + +### Utility ### + + Grid(x int, y int, w int, h int, n int, s ...string) + draws a grid of straight lines starting at x,y, with a width w, and height h, and a size of n. + + ![Grid](http://farm5.static.flickr.com/4133/5190957924_7a31d0db34.jpg) + +### Credits ### + +Thanks to Jonathan Wright for the io.Writer update. diff --git a/vendor/github.com/ajstarks/svgo/android/android.go b/vendor/github.com/ajstarks/svgo/android/android.go new file mode 100644 index 0000000..1fa57c4 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/android/android.go @@ -0,0 +1,55 @@ +// android draws bugdroid, the Android mascot +// +build !appengine + +package main + +import ( + "fmt" + "os" + + "github.com/ajstarks/svgo" +) + +var ( + width = 500 + height = 500 + canvas = svg.New(os.Stdout) +) + +const androidcolor = "rgb(164,198,57)" + +func background(v int) { canvas.Rect(0, 0, width, height, canvas.RGB(v, v, v)) } + +func android(x, y int, fill string, opacity float64) { + var linestyle = []string{`stroke="` + fill + `"`, `stroke-linecap="round"`, `stroke-width="5"`} + globalstyle := fmt.Sprintf("fill:%s;opacity:%.2f", fill, opacity) + canvas.Gstyle(globalstyle) + canvas.Arc(x+30, y+70, 35, 35, 0, false, true, x+130, y+70) // head + canvas.Line(x+60, y+25, x+50, y+10, linestyle[0], linestyle[1], linestyle[2]) // left antenna + canvas.Line(x+100, y+25, x+110, y+10, linestyle[0], linestyle[1], linestyle[2]) // right antenna + canvas.Circle(x+60, y+45, 5, "fill:white") // left eye + canvas.Circle(x+100, y+45, 5, `fill="white"`) // right eye + canvas.Roundrect(x+30, y+75, 100, 90, 10, 10) // body + canvas.Rect(x+30, y+75, 100, 80) + canvas.Roundrect(x+5, y+80, 20, 70, 10, 10) // left arm + canvas.Roundrect(x+135, y+80, 20, 70, 10, 10) // right arm + canvas.Roundrect(x+50, y+150, 20, 50, 10, 10) // left leg + canvas.Roundrect(x+90, y+150, 20, 50, 10, 10) // right leg + canvas.Gend() +} + +func main() { + canvas.Start(width, height) + canvas.Title("Android") + background(255) + + android(100, 100, androidcolor, 1.0) + canvas.Scale(3.0) + android(50, 50, "gray", 0.5) + canvas.Gend() + + canvas.Scale(0.5) + android(100, 100, "red", 1.0) + canvas.Gend() + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/barchart/barchart.go b/vendor/github.com/ajstarks/svgo/barchart/barchart.go new file mode 100644 index 0000000..7c0e767 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/barchart/barchart.go @@ -0,0 +1,472 @@ +// barchart - bar chart +package main + +import ( + "encoding/xml" + "flag" + "fmt" + "github.com/ajstarks/svgo" + "io" + "math" + "os" + "strconv" + "strings" +) + +var ( + width, height, iscale, fontsize, barheight, gutter, cornerRadius, labelimit int + bgcolor, barcolor, title, inbar, valformat string + showtitle, showdata, showgrid, showscale, endtitle, trace bool +) + +const ( + gstyle = "font-family:Calibri,sans-serif;font-size:%dpx" + borderstyle = "stroke:lightgray;stroke-width:1px" + scalestyle = "text-anchor:middle;font-size:75%" + btitlestyle = "font-style:italic;font-size:150%;text-anchor:" + notestyle = "font-style:italic;text-anchor:" + datastyle = "text-anchor:end;fill:" + titlestyle = "text-anchor:start;font-size:300%" + labelstyle = "fill:black;baseline-shift:-25%" +) + +// a Barchart Defintion +// +// This is a note +// More expository text +// +// +// +// +// +// + +type Barchart struct { + Top int `xml:"top,attr"` + Left int `xml:"left,attr"` + Right int `xml:"right,attr"` + Title string `xml:"title,attr"` + Bdata []bdata `xml:"bdata"` + Note []note `xml:"note"` +} + +type bdata struct { + Title string `xml:"title,attr"` + Scale string `xml:"scale,attr"` + Color string `xml:"color,attr"` + Unit string `xml:"unit,attr"` + Showdata bool `xml:"showdata,attr"` + Showgrid bool `xml:"showgrid,attr"` + Samebar bool `xml:"samebar,attr"` + Bitem []bitem `xml:"bitem"` + Bstack []bstack `xml:"bstack"` + Note []note `xml:"note"` +} + +type bitem struct { + Name string `xml:"name,attr"` + Value float64 `xml:"value,attr"` + Color string `xml:"color,attr"` + Samebar bool `xml:"samebar,attr"` +} + +type bstack struct { + Name string `xml:"name,attr"` + Value string `xml:"value,attr"` + Color string `xml:"color,attr"` +} + +type note struct { + Text string `xml:",chardata"` +} + +// dobc does file i/o +func dobc(location string, s *svg.SVG) { + var f *os.File + var err error + if len(location) > 0 { + f, err = os.Open(location) + } else { + f = os.Stdin + } + if err == nil { + readbc(f, s) + f.Close() + } else { + fmt.Fprintf(os.Stderr, "%v\n", err) + } +} + +// readbc reads and parses the XML specification +func readbc(r io.Reader, s *svg.SVG) { + var bc Barchart + if err := xml.NewDecoder(r).Decode(&bc); err == nil { + drawbc(bc, s) + } else { + fmt.Fprintf(os.Stderr, "%v\n", err) + } +} + +// drawbc draws the bar chart +func drawbc(bg Barchart, canvas *svg.SVG) { + + if bg.Left == 0 { + bg.Left = 250 + } + if bg.Right == 0 { + bg.Right = 50 + } + if bg.Top == 0 { + bg.Top = 50 + } + if len(title) > 0 { + bg.Title = title + } + labelimit = bg.Left/8 + cr := cornerRadius + maxwidth := width - (bg.Left + bg.Right) + x := bg.Left + y := bg.Top + sep := 10 + color := barcolor + scfmt := "%v" + canvas.Title(bg.Title) + + // for each bdata element... + for _, b := range bg.Bdata { + if trace { + fmt.Fprintf(os.Stderr, "# %s\n", b.Title) + } + // overide the color if specified + if len(b.Color) > 0 { + color = b.Color + } else { + color = barcolor + } + // extract the scale data from the XML attributes + // if not specified, compute the scale factors + sc := strings.Split(b.Scale, ",") + var scalemin, scalemax, scaleincr float64 + + if len(sc) != 3 { + if len(b.Bitem) > 0 { + scalemin, scalemax, scaleincr = scalevalues(b.Bitem) + } + + if len(b.Bstack) > 0 { + scalemin, scalemax, scaleincr = scalestack(b.Bstack) + } + } else { + scalemin, _ = strconv.ParseFloat(sc[0], 64) + scalemax, _ = strconv.ParseFloat(sc[1], 64) + scaleincr, _ = strconv.ParseFloat(sc[2], 64) + } + // label the graph + canvas.Text(x, y, b.Title, btitlestyle+anchor()) + + y += sep * 2 + chartop := y + + // draw the data items + canvas.Gstyle(datastyle + color) + + // stacked bars + for _, stack := range b.Bstack { + if trace { + fmt.Fprintf(os.Stderr, "%s~%s\n", stack.Value, stack.Name) + } + stackdata := stackvalues(stack.Value) + if len(stackdata) < 1 { + continue + } + sx := x + canvas.Text(x-sep, y+barheight/2, textlimit(stack.Name, labelimit), labelstyle) + barop := colorange(1.0, 0.3, len(stackdata)) + for ns, sd := range stackdata { + dw := vmap(sd, scalemin, scalemax, 0, float64(maxwidth)) + if len(stack.Color) > 0 { + canvas.Roundrect(sx, y, int(dw), barheight, cr, cr, fmt.Sprintf("fill:%s;fill-opacity:%.2f", stack.Color, barop[ns])) + } else { + canvas.Roundrect(sx, y, int(dw), barheight, cr, cr, fmt.Sprintf("fill-opacity:%.2f", barop[ns])) + } + + + if (showdata || b.Showdata) && sd > 0 { + var valuestyle = "fill-opacity:1;font-style:italic;font-size:75%;text-anchor:middle;baseline-shift:-25%;" + var ditem string + var datax int + if len(b.Unit) > 0 { + ditem = fmt.Sprintf(valformat+"%s", sd, b.Unit) + } else { + ditem = fmt.Sprintf(valformat, sd) + } + if len(inbar) > 0 { + valuestyle += inbar + } else { + valuestyle += "fill:black" + } + datax = sx + int(dw)/2 + canvas.Text(datax, y+barheight/2, ditem, valuestyle) + } + sx += int(dw) + } + y += barheight + gutter + } + + // plain bars + for _, d := range b.Bitem { + if trace { + fmt.Fprintf(os.Stderr, "%.2f~%s\n", d.Value, d.Name) + } + canvas.Text(x-sep, y+barheight/2, textlimit(d.Name, labelimit), labelstyle) + dw := vmap(d.Value, scalemin, scalemax, 0, float64(maxwidth)) + var barop float64 + if b.Samebar { + barop = 0.3 + } else { + barop = 1.0 + } + if len(d.Color) > 0 { + canvas.Roundrect(x, y, int(dw), barheight, cr, cr, fmt.Sprintf("fill:%s;fill-opacity:%.2f", d.Color, barop)) + } else { + canvas.Roundrect(x, y, int(dw), barheight, cr, cr, fmt.Sprintf("fill-opacity:%.2f", barop)) + } + if showdata || b.Showdata { + var valuestyle = "fill-opacity:1;font-style:italic;font-size:75%;text-anchor:start;baseline-shift:-25%;" + var ditem string + var datax int + if len(b.Unit) > 0 { + ditem = fmt.Sprintf(valformat+"%s", d.Value, b.Unit) + } else { + ditem = fmt.Sprintf(valformat, d.Value) + } + if len(inbar) > 0 { + valuestyle += inbar + datax = x + fontsize/2 + } else { + valuestyle += "fill:black" + datax = x + int(dw) + fontsize/2 + } + canvas.Text(datax, y+barheight/2, ditem, valuestyle) + } + if !d.Samebar { + y += barheight + gutter + } + } + canvas.Gend() + + // draw the scale and borders + chartbot := y + gutter + if showgrid || b.Showgrid { + canvas.Line(x, chartop, x+maxwidth, chartop, borderstyle) // top border + canvas.Line(x, chartbot-gutter, x+maxwidth, chartbot-gutter, borderstyle) // bottom border + } + if showscale { + if scaleincr < 1 { + scfmt = "%.1f" + } else { + scfmt = "%0.f" + } + canvas.Gstyle(scalestyle) + for sc := scalemin; sc <= scalemax; sc += scaleincr { + scx := vmap(sc, scalemin, scalemax, 0, float64(maxwidth)) + canvas.Text(x+int(scx), chartbot+fontsize, fmt.Sprintf(scfmt, sc)) + if showgrid || b.Showgrid { + canvas.Line(x+int(scx), chartbot, x+int(scx), chartop, borderstyle) // grid line + } + } + canvas.Gend() + } + + // apply the note if present + if len(b.Note) > 0 { + canvas.Gstyle(notestyle + anchor()) + y += fontsize * 2 + leading := 3 + for _, note := range b.Note { + canvas.Text(bg.Left, y, note.Text) + y += fontsize + leading + } + canvas.Gend() + } + y += sep * 7 // advance vertically for the next chart + } + // if requested, place the title below the last chart + if showtitle && len(bg.Title) > 0 { + y += fontsize * 2 + canvas.Text(bg.Left, y, bg.Title, titlestyle) + } + // apply overall note if present + if len(bg.Note) > 0 { + canvas.Gstyle(notestyle + anchor()) + y += fontsize * 2 + leading := 3 + for _, note := range bg.Note { + canvas.Text(bg.Left, y, note.Text) + y += fontsize + leading + } + canvas.Gend() + } +} + +func anchor() string { + if endtitle { + return "end" + } + return "start" +} + +// vmap maps one interval to another +func vmap(value float64, low1 float64, high1 float64, low2 float64, high2 float64) float64 { + return low2 + (high2-low2)*(value-low1)/(high1-low1) +} + +// maxitem finds the maxima is a collection of bar items +func maxitem(data []bitem) float64 { + max := -math.SmallestNonzeroFloat64 + for _, d := range data { + if d.Value > max { + max = d.Value + } + } + return max +} + +// maxstack finds the maxima is a stack of bars +func maxstack(stacks []bstack) float64 { + max := -math.SmallestNonzeroFloat64 + for _, s := range stacks { + sv := stackvalues(s.Value) + sum := 0.0 + for _, d := range sv { + sum += d + } + if sum > max { + max = sum + } + } + return max +} + +// scale values returns the min, max, increment from a set of bar items +func scalevalues(data []bitem) (float64, float64, float64) { + var m, max, increment float64 + rui := 5 + m = maxitem(data) + max = roundup(m, 100) + if max > 2 { + increment = roundup(max/float64(rui), 10) + } else { + increment = 0.4 + } + return 0, max, increment +} + +// scalestack returns the min, max, increment from a stack of bars +func scalestack(data []bstack) (float64, float64, float64) { + var m, max, increment float64 + rui := 5 + m = maxstack(data) + max = roundup(m, 100) + if max > 2 { + increment = roundup(max/float64(rui), 10) + } else { + increment = 0.4 + } + return 0, max, increment +} + +// roundup rouds a floating point number up +func roundup(n float64, m int) float64 { + i := int(n) + if i <= 2 { + return 2 + } + for ; i%m != 0; i++ { + } + return float64(i) +} + +// stack value returns the values from the value string of a stack +func stackvalues(s string) []float64 { + v := strings.Split(s, "/") + if len(v) <= 0 { + return nil + } + vals := make([]float64, len(v)) + for i, x := range v { + f, err := strconv.ParseFloat(x, 64) + if err != nil { + vals[i] = 0 + } else { + vals[i] = f + } + } + return vals +} + + +// colorange evenly distributes opacity across a range of values +func colorange(start, end float64, n int) []float64 { + v := make([]float64, n) + v[0] = start + v[n-1] = end + if n == 2 { + return v + } + incr := (end-start)/float64(n-1) + for i:=1; i < n-1; i++ { + v[i] = v[i-1] + incr + } + return v +} + + +func textlimit(s string, n int) string { + l := len(s) + if l <= n { + return s + } + + return s[0:n-3]+"..." +} + +// init sets up the command flags +func init() { + flag.StringVar(&bgcolor, "bg", "white", "background color") + flag.StringVar(&barcolor, "bc", "rgb(200,200,200)", "bar color") + flag.StringVar(&valformat, "vfmt", "%v", "value format") + flag.IntVar(&width, "w", 1024, "width") + flag.IntVar(&height, "h", 800, "height") + flag.IntVar(&barheight, "bh", 20, "bar height") + flag.IntVar(&gutter, "g", 5, "gutter") + flag.IntVar(&cornerRadius, "cr", 0, "corner radius") + flag.IntVar(&fontsize, "f", 18, "fontsize (px)") + flag.BoolVar(&showscale, "showscale", true, "show scale") + flag.BoolVar(&showgrid, "showgrid", false, "show grid") + flag.BoolVar(&showdata, "showdata", false, "show data values") + flag.BoolVar(&showtitle, "showtitle", false, "show title") + flag.BoolVar(&endtitle, "endtitle", false, "align title to the end") + flag.BoolVar(&trace, "trace", false, "show name/value pairs") + flag.StringVar(&inbar, "inbar", "", "data in bar format") + flag.StringVar(&title, "t", "", "title") +} + +// for every input file (or stdin), draw a bar graph +// as specified by command flags +func main() { + flag.Parse() + canvas := svg.New(os.Stdout) + canvas.Start(width, height) + canvas.Rect(0, 0, width, height, "fill:"+bgcolor) + canvas.Gstyle(fmt.Sprintf(gstyle, fontsize)) + if len(flag.Args()) == 0 { + dobc("", canvas) + } else { + for _, f := range flag.Args() { + dobc(f, canvas) + } + } + canvas.Gend() + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/benchviz/benchviz.go b/vendor/github.com/ajstarks/svgo/benchviz/benchviz.go new file mode 100644 index 0000000..5f2bb07 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/benchviz/benchviz.go @@ -0,0 +1,238 @@ +// benchviz: visualize benchmark data from benchcmp +package main + +import ( + "bufio" + "bytes" + "flag" + "fmt" + "io" + "math" + "os" + "strconv" + "strings" + + "github.com/ajstarks/svgo" +) + +// geometry defines the layout of the visualization +type geometry struct { + top, left, width, height, vwidth, vp, barHeight int + dolines, coldata bool + title, rcolor, scolor, style string + deltamax, speedupmax float64 +} + +// process reads the input and calls the visualization function +func process(canvas *svg.SVG, filename string, g geometry) int { + if filename == "" { + return g.visualize(canvas, filename, os.Stdin) + } + f, err := os.Open(filename) + if err != nil { + fmt.Fprintf(os.Stderr, "%v\n", err) + return 0 + } + defer f.Close() + return g.visualize(canvas, filename, f) +} + +// vmap maps world to canvas coordinates +func vmap(value, low1, high1, low2, high2 float64) float64 { + return low2 + (high2-low2)*(value-low1)/(high1-low1) +} + +// visualize performs the visualization of the input, reading a line a time +func (g *geometry) visualize(canvas *svg.SVG, filename string, f io.Reader) int { + var ( + err error + line, vs, bmtitle string + dmin, dmax float64 + ) + + bh := g.barHeight + vizwidth := g.vwidth + vspacing := g.barHeight + (g.barHeight / 3) // vertical spacing + bmtype := "delta" + + in := bufio.NewReader(f) + canvas.Gstyle(fmt.Sprintf("font-size:%dpx;font-family:sans-serif", bh)) + if g.title == "" { + bmtitle = filename + } else { + bmtitle = g.title + } + canvas.Text(g.left, g.top, bmtitle, "font-size:150%") + + height := 0 + for x, y, nr := g.left+g.vp, g.top+vspacing, 0; err == nil; nr++ { + line, err = in.ReadString('\n') + fields := strings.Split(strings.TrimSpace(line), ` `) + + if len(fields) <= 1 || len(line) < 2 { + continue + } + name := fields[0] + value := fields[len(fields)-1] + if len(value) > 2 { + vs = value[:len(value)-1] + } + v, _ := strconv.ParseFloat(vs, 64) + av := math.Abs(v) + + switch { + case strings.HasPrefix(value, "delt"): + bmtype = "delta" + dmin = 0.0 + dmax = g.deltamax // 100.0 + y += vspacing * 2 + continue + + case strings.HasPrefix(value, "speed"): + bmtype = "speedup" + dmin = 0.0 + dmax = g.speedupmax // 10.0 + y += vspacing * 2 + continue + + case strings.HasPrefix(name, "#"): + y += vspacing + canvas.Text(g.left, y, line[1:], "font-style:italic;fill:gray") + continue + } + + bw := int(vmap(av, dmin, dmax, 0, float64(vizwidth))) + switch g.style { + case "bar": + g.bars(canvas, x, y, bw, bh, vspacing/2, bmtype, name, value, v) + case "inline": + g.inline(canvas, g.left, y, bw, bh, bmtype, name, value, v) + default: + g.bars(canvas, x, y, bw, bh, vspacing/2, bmtype, name, value, v) + } + y += vspacing + height = y + } + canvas.Gend() + return height +} + +// inline makes the inline style pf visualization +func (g *geometry) inline(canvas *svg.SVG, x, y, w, h int, bmtype, name, value string, v float64) { + var color string + switch bmtype { + case "delta": + if v > 0 { + color = g.rcolor + } else { + color = g.scolor + } + case "speedup": + if v < 1.0 { + color = g.rcolor + } else { + color = g.scolor + } + } + canvas.Text(x-10, y, value, "text-anchor:end") + canvas.Text(x, y, name) + canvas.Rect(x, y-h, w, h, "fill-opacity:0.3;fill:"+color) +} + +// bars creates barchart style visualization +func (g *geometry) bars(canvas *svg.SVG, x, y, w, h, vs int, bmtype, name, value string, v float64) { + canvas.Gstyle("font-style:italic;font-size:75%") + toffset := h / 4 + var tx int + var tstyle string + switch bmtype { + case "delta": + if v > 0 { + canvas.Rect(x-w, y-h/2, w, h, "fill-opacity:0.3;fill:"+g.rcolor) + tx = x - w - toffset + tstyle = "text-anchor:end" + } else { + canvas.Rect(x, y-h/2, w, h, "fill-opacity:0.3;fill:"+g.scolor) + tx = x + w + toffset + tstyle = "text-anchor:start" + } + case "speedup": + if v < 1.0 { + canvas.Rect(x-w, y-h/2, w, h, "fill-opacity:0.3;fill:"+g.rcolor) + tx = x - w - toffset + tstyle = "text-anchor:end" + } else { + canvas.Rect(x, y-h/2, w, h, "fill-opacity:0.3;fill:"+g.scolor) + tx = x + w + toffset + tstyle = "text-anchor:start" + } + } + if g.coldata { + canvas.Text(x-toffset, y+toffset, value, "text-anchor:end") + } else { + canvas.Text(tx, y+toffset, value, tstyle) + } + canvas.Gend() + canvas.Text(g.left, y+(h/2), name, "text-anchor:start") + if g.dolines { + canvas.Line(g.left, y+vs, g.left+(g.width-g.left), y+vs, "stroke:lightgray;stroke-width:1") + } +} + +func main() { + var ( + width = flag.Int("w", 1024, "width") + top = flag.Int("top", 50, "top") + left = flag.Int("left", 100, "left margin") + vp = flag.Int("vp", 512, "visualization point") + vw = flag.Int("vw", 300, "visual area width") + bh = flag.Int("bh", 20, "bar height") + smax = flag.Float64("sm", 10, "maximum speedup") + dmax = flag.Float64("dm", 100, "maximum delta") + title = flag.String("title", "", "title") + speedcolor = flag.String("scolor", "green", "speedup color") + regresscolor = flag.String("rcolor", "red", "regression color") + style = flag.String("style", "bar", "set the style (bar or inline)") + lines = flag.Bool("line", false, "show lines between entries") + coldata = flag.Bool("col", false, "show data in a single column") + ) + flag.Parse() + + g := geometry{ + width: *width, + top: *top, + left: *left, + vp: *vp, + vwidth: *vw, + barHeight: *bh, + title: *title, + scolor: *speedcolor, + rcolor: *regresscolor, + style: *style, + dolines: *lines, + coldata: *coldata, + speedupmax: *smax, + deltamax: *dmax, + } + + // For every named file or stdin, render the SVG in memory, accumulating the height. + var b bytes.Buffer + canvas := svg.New(&b) + height := 0 + if len(flag.Args()) > 0 { + for _, f := range flag.Args() { + height = process(canvas, f, g) + g.top = height + 50 + } + } else { + height = process(canvas, "", g) + } + g.height = height + 15 + + // Write the rendered SVG to stdout + out := svg.New(os.Stdout) + out.Start(g.width, g.height) + out.Rect(0, 0, g.width, g.height, "fill:white;stroke-width:2px;stroke:lightgray") + b.WriteTo(os.Stdout) + out.End() +} diff --git a/vendor/github.com/ajstarks/svgo/bubtrail/bubtrail.go b/vendor/github.com/ajstarks/svgo/bubtrail/bubtrail.go new file mode 100644 index 0000000..99ceaa8 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/bubtrail/bubtrail.go @@ -0,0 +1,67 @@ +// bubtrail draws a randmonized trail of bubbles +// +build !appengine + +package main + +import ( + "flag" + "fmt" + "math/rand" + "os" + "time" + + "github.com/ajstarks/svgo" +) + +var ( + width = 1200 + height = 600 + opacity = 0.5 + size = 40 + niter = 200 + canvas = svg.New(os.Stdout) +) + +func init() { + flag.IntVar(&size, "s", 40, "bubble size") + flag.IntVar(&niter, "n", 200, "number of iterations") + flag.Float64Var(&opacity, "o", 0.5, "opacity") + flag.Parse() + rand.Seed(int64(time.Now().Nanosecond()) % 1e9) +} + +func background(v int) { canvas.Rect(0, 0, width, height, canvas.RGB(v, v, v)) } + +func random(howsmall, howbig int) int { + if howsmall >= howbig { + return howsmall + } + return rand.Intn(howbig-howsmall) + howsmall +} + +func main() { + var style string + + canvas.Start(width, height) + canvas.Title("Bubble Trail") + background(200) + canvas.Gstyle(fmt.Sprintf("fill-opacity:%.2f;stroke:none", opacity)) + for i := 0; i < niter; i++ { + x := random(0, width) + y := random(height/3, (height*2)/3) + r := random(0, 10000) + switch { + case r >= 0 && r <= 2500: + style = "fill:rgb(255,255,255)" + case r > 2500 && r <= 5000: + style = "fill:rgb(127,0,0)" + case r > 5000 && r <= 7500: + style = "fill:rgb(127,127,127)" + case r > 7500 && r <= 10000: + style = "fill:rgb(0,0,0)" + } + canvas.Circle(x, y, size, style) + } + canvas.Gend() + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/bulletgraph/bulletgraph.go b/vendor/github.com/ajstarks/svgo/bulletgraph/bulletgraph.go new file mode 100644 index 0000000..d4269e0 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/bulletgraph/bulletgraph.go @@ -0,0 +1,233 @@ +// bulletgraph - bullet graphs +// (Design Specification http://www.perceptualedge.com/articles/misc/Bullet_Graph_Design_Spec.pdf) +// +build !appengine + +package main + +import ( + "encoding/xml" + "flag" + "fmt" + "io" + "os" + "strconv" + "strings" + + "github.com/ajstarks/svgo" +) + +var ( + width, height, fontsize, barheight, gutter, circleradius int + bgcolor, barcolor, datacolor, compcolor, title, font string + showtitle, circlemark bool + gstyle = "font-family:'%s',sans-serif;font-size:%dpx" +) + +// a Bulletgraph Defintion +// +// This is a note +// More expository text +// +// +// +// +// +// + +// Bulletgraph is the top-level drawing +type Bulletgraph struct { + Top int `xml:"top,attr"` + Left int `xml:"left,attr"` + Right int `xml:"right,attr"` + Title string `xml:"title,attr"` + Bdata []bdata `xml:"bdata"` + Note []note `xml:"note"` +} + +type bdata struct { + Title string `xml:"title,attr"` + Subtitle string `xml:"subtitle,attr"` + Scale string `xml:"scale,attr"` + Qmeasure string `xml:"qmeasure,attr"` + Cmeasure float64 `xml:"cmeasure,attr"` + Measure float64 `xml:"measure,attr"` +} + +type note struct { + Text string `xml:",chardata"` +} + +// dobg does file i/o +func dobg(location string, s *svg.SVG) { + var f *os.File + var err error + if len(location) > 0 { + f, err = os.Open(location) + } else { + f = os.Stdin + } + if err == nil { + readbg(f, s) + f.Close() + } else { + fmt.Fprintf(os.Stderr, "%v\n", err) + } +} + +// readbg reads and parses the XML specification +func readbg(r io.Reader, s *svg.SVG) { + var bg Bulletgraph + if err := xml.NewDecoder(r).Decode(&bg); err == nil { + drawbg(bg, s) + } else { + fmt.Fprintf(os.Stderr, "%v\n", err) + } +} + +// drawbg draws the bullet graph +func drawbg(bg Bulletgraph, canvas *svg.SVG) { + qmheight := barheight / 3 + + if bg.Left == 0 { + bg.Left = 250 + } + if bg.Right == 0 { + bg.Right = 50 + } + if bg.Top == 0 { + bg.Top = 50 + } + if len(title) > 0 { + bg.Title = title + } + + maxwidth := width - (bg.Left + bg.Right) + x := bg.Left + y := bg.Top + scalesep := 4 + tx := x - fontsize + + canvas.Title(bg.Title) + // for each bdata element... + for _, v := range bg.Bdata { + + // extract the data from the XML attributes + sc := strings.Split(v.Scale, ",") + qm := strings.Split(v.Qmeasure, ",") + + // you must have min,max,increment for the scale, at least one qualitative measure + if len(sc) != 3 || len(qm) < 1 { + continue + } + // get the qualitative measures + qmeasures := make([]float64, len(qm)) + for i, q := range qm { + qmeasures[i], _ = strconv.ParseFloat(q, 64) + } + scalemin, _ := strconv.ParseFloat(sc[0], 64) + scalemax, _ := strconv.ParseFloat(sc[1], 64) + scaleincr, _ := strconv.ParseFloat(sc[2], 64) + + // label the graph + canvas.Text(tx, y+(barheight/2), fmt.Sprintf("%s (%g)", v.Title, v.Measure), "text-anchor:end;font-weight:bold") + canvas.Text(tx, y+(barheight/2)+fontsize, v.Subtitle, "fill:darkgray;text-anchor:end;font-size:75%") + + // draw the scale + scfmt := "%g" + if fraction(scaleincr) > 0 { + scfmt = "%.1f" + } + canvas.Gstyle("text-anchor:middle;font-size:75%") + for sc := scalemin; sc <= scalemax; sc += scaleincr { + scx := vmap(sc, scalemin, scalemax, 0, float64(maxwidth)) + canvas.Text(x+int(scx), y+scalesep+barheight+fontsize/2, fmt.Sprintf(scfmt, sc)) + } + canvas.Gend() + + // draw the qualitative measures + canvas.Gstyle("fill-opacity:0.5;fill:" + barcolor) + canvas.Rect(x, y, maxwidth, barheight) + for _, q := range qmeasures { + qbarlength := vmap(q, scalemin, scalemax, 0, float64(maxwidth)) + canvas.Rect(x, y, int(qbarlength), barheight) + } + canvas.Gend() + + // draw the measure and the comparative measure + barlength := int(vmap(v.Measure, scalemin, scalemax, 0, float64(maxwidth))) + canvas.Rect(x, y+qmheight, barlength, qmheight, "fill:"+datacolor) + cmx := int(vmap(v.Cmeasure, scalemin, scalemax, 0, float64(maxwidth))) + if circlemark { + canvas.Circle(x+cmx, y+barheight/2, circleradius, "fill-opacity:0.3;fill:"+compcolor) + } else { + cbh := barheight / 4 + canvas.Line(x+cmx, y+cbh, x+cmx, y+barheight-cbh, "stroke-width:3;stroke:"+compcolor) + } + + y += barheight + gutter // adjust vertical position for the next iteration + } + // if requested, place the title below the last bar + if showtitle && len(bg.Title) > 0 { + y += fontsize * 2 + canvas.Text(bg.Left, y, bg.Title, "text-anchor:start;font-size:200%") + } + + if len(bg.Note) > 0 { + canvas.Gstyle("font-size:100%;text-anchor:start") + y += fontsize * 2 + leading := 3 + for _, note := range bg.Note { + canvas.Text(bg.Left, y, note.Text) + y += fontsize + leading + } + canvas.Gend() + } +} + +//vmap maps one interval to another +func vmap(value float64, low1 float64, high1 float64, low2 float64, high2 float64) float64 { + return low2 + (high2-low2)*(value-low1)/(high1-low1) +} + +// fraction returns the fractions portion of a floating point number +func fraction(n float64) float64 { + i := int(n) + return n - float64(i) +} + +// init sets up the command flags +func init() { + flag.StringVar(&bgcolor, "bg", "white", "background color") + flag.StringVar(&barcolor, "bc", "rgb(240,240,240)", "bar color") + flag.StringVar(&datacolor, "dc", "rgb(200,200,200)", "data color") + flag.StringVar(&compcolor, "cc", "rgb(127,0,0)", "comparative color") + flag.StringVar(&font, "font", "Calibri", "font") + flag.IntVar(&width, "w", 1024, "width") + flag.IntVar(&height, "h", 800, "height") + flag.IntVar(&barheight, "bh", 32, "bar height") + flag.IntVar(&circleradius, "cr", 8, "circle radius") + flag.IntVar(&gutter, "g", 36, "gutter") + flag.IntVar(&fontsize, "f", 18, "fontsize (px)") + flag.BoolVar(&circlemark, "circle", false, "circle mark") + flag.BoolVar(&showtitle, "showtitle", true, "show title") + flag.StringVar(&title, "t", "", "title") + flag.Parse() +} + +// for every input file (or stdin), draw a bullet graph +// as specified by command flags +func main() { + canvas := svg.New(os.Stdout) + canvas.Start(width, height) + canvas.Rect(0, 0, width, height, "fill:"+bgcolor) + canvas.Gstyle(fmt.Sprintf(gstyle, font, fontsize)) + if len(flag.Args()) == 0 { + dobg("", canvas) + } else { + for _, f := range flag.Args() { + dobg(f, canvas) + } + } + canvas.Gend() + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/codepic/codepic.go b/vendor/github.com/ajstarks/svgo/codepic/codepic.go new file mode 100644 index 0000000..7ec73f2 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/codepic/codepic.go @@ -0,0 +1,182 @@ +// codepic -- produce code+output sample suitable for slides +// +build !appengine + +package main + +import ( + "bufio" + "encoding/xml" + "flag" + "fmt" + "io" + "os" + "strings" + + "github.com/ajstarks/svgo" +) + +var ( + canvas = svg.New(os.Stdout) + font string + codeframe, picframe, syntax bool + linespacing, fontsize, top, left, boxwidth, width, height int +) + +const ( + framestyle = "stroke:gray;stroke-dasharray:1,1;fill:none" + codefmt = "font-family:%s;font-size:%dpx" + labelfmt = "text-anchor:middle;" + codefmt + kwfmt = `%s` + commentfmt = `%s` + textfmt = "%s\n" + svgofmt = `font-weight="bold" fill="rgb(0,0,127)"` + gokwfmt = `font-style="italic" fill="rgb(127,0,0)"` +) + +// SVG is the incoming SVG file, capture everything into between and +// in the Doc string. This code will be translated to form the "picture" portion +type SVG struct { + Width int `xml:"width,attr"` + Height int `xml:"height,attr"` + Doc string `xml:",innerxml"` +} + +var gokw = []string{ + "defer ", "go ", "range ", "chan ", " continue", "if ", "for ", "func ", + "uint8", "uint", "uint16", "uint32", "complex64", "complex128", " byte", "int8", "int16", "int32", + "int64", " int", "float64", "float32", " string", "import ", "const ", + "package ", "return", "var ", "type ", "switch ", "case ", "default:", +} + +var svgokw = []string{ + ".Start", ".Startview,", ".End", ".Script", ".Gstyle", ".Gtransform", ".Scale", ".Offcolor", + ".ScaleXY", ".SkewX", ".SkewY", ".SkewXY,", ".Rotate", ".TranslateRotate", ".RotateTranslate", ".Translate", + ".Group", ".Gid", ".Gend", ".ClipPath", ".ClipEnd", ".DefEnd", ".Def", ".Desc", ".Title", ".Linkf", + ".LinkEnd", ".Use", ".Mask", ".MaskEnd", ".Circle", ".Ellipse", ".Polygon", ".Rect", ".CenterRect", + ".Roundrect", ".Square", ".Path", ".Arc", ".Bezier", ".Qbez", ".Qbezier", ".Line", ".Polyline", ".Image", + ".Textpath", ".Textlines,", ".Text", ".RGBA", ".RGB", ".LinearGradient", ".RadialGradient", ".Grid", +} + +// codepic makes a code+picture SVG file, given a go source file +// and conventionally named output -- given .go, .svg +func codepic(filename string) { + var basename string + + bn := strings.Split(filename, ".") + if len(bn) > 0 { + basename = bn[0] + } else { + fmt.Fprintf(os.Stderr, "cannot get the basename for %s\n", filename) + return + } + canvas.Start(width, height) + canvas.Title(basename) + canvas.Rect(0, 0, width, height, "fill:white") + placepic(width/2, top, basename) + canvas.Gstyle(fmt.Sprintf(codefmt, font, fontsize)) + placecode(left+fontsize, top+fontsize*2, filename) + canvas.Gend() + canvas.End() +} + +// placecode places the code section on the left +func placecode(x, y int, filename string) { + var rerr error + var line string + var ic bool + f, err := os.Open(filename) + if err != nil { + fmt.Fprintf(os.Stderr, "%v\n", err) + return + } + defer f.Close() + in := bufio.NewReader(f) + + for xp := left + fontsize; rerr == nil; y += linespacing { + line, rerr = in.ReadString('\n') + if len(line) > 0 { + line, ic = svgtext(xp, y, line[0:len(line)-1]) + if !ic && syntax { + line = keyword(line, gokwfmt, gokw) + line = keyword(line, svgofmt, svgokw) + } + io.WriteString(canvas.Writer, line) + } + } + if codeframe { + canvas.Rect(top, left, left+boxwidth, y, framestyle) + } +} + +// keyword styles keywords in a line of code +func keyword(line string, style string, kw []string) string { + for _, k := range kw { + line = strings.Replace(line, k, fmt.Sprintf(kwfmt, style, k), 1) + } + return line +} + +// svgtext +func svgtext(x, y int, s string) (string, bool) { + var iscomment = false + s = strings.Replace(s, "&", "&", -1) + s = strings.Replace(s, "<", "<", -1) + s = strings.Replace(s, ">", ">", -1) + + if syntax { + i := strings.Index(s, "// ") + if i >= 0 { + iscomment = true + s = strings.Replace(s, s[i:], fmt.Sprintf(commentfmt, s[i:]), 1) + } + } + return fmt.Sprintf(textfmt, x, y, s), iscomment +} + +// placepic places the picture on the right +func placepic(x, y int, basename string) { + var s SVG + f, err := os.Open(basename + ".svg") + if err != nil { + fmt.Fprintf(os.Stderr, "%v\n", err) + return + } + defer f.Close() + if err := xml.NewDecoder(f).Decode(&s); err != nil { + fmt.Fprintf(os.Stderr, "Unable to parse (%v)\n", err) + return + } + canvas.Text(x, height-10, basename+".go", fmt.Sprintf(labelfmt, font, fontsize*2)) + canvas.Group(`clip-path="url(#pic)"`, fmt.Sprintf(`transform="translate(%d,%d)"`, x, y)) + canvas.ClipPath(`id="pic"`) + canvas.Rect(0, 0, s.Width, s.Height) + canvas.ClipEnd() + io.WriteString(canvas.Writer, s.Doc) + canvas.Gend() + if picframe { + canvas.Rect(x, y, s.Width, s.Height, framestyle) + } +} + +// init initializes flags +func init() { + flag.BoolVar(&codeframe, "codeframe", false, "frame the code") + flag.BoolVar(&picframe, "picframe", false, "frame the picture") + flag.BoolVar(&syntax, "syntax", false, "syntax coloring") + flag.IntVar(&width, "w", 1024, "width") + flag.IntVar(&height, "h", 768, "height") + flag.IntVar(&linespacing, "ls", 16, "linespacing") + flag.IntVar(&fontsize, "fs", 14, "fontsize") + flag.IntVar(&top, "top", 20, "top") + flag.IntVar(&left, "left", 20, "left") + flag.IntVar(&boxwidth, "boxwidth", 450, "boxwidth") + flag.StringVar(&font, "font", "Inconsolata", "font name") + flag.Parse() +} + +// for every file, make a code+pic SVG file +func main() { + for _, f := range flag.Args() { + codepic(f) + } +} diff --git a/vendor/github.com/ajstarks/svgo/colortab/colortab.go b/vendor/github.com/ajstarks/svgo/colortab/colortab.go new file mode 100644 index 0000000..979fe6a --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/colortab/colortab.go @@ -0,0 +1,89 @@ +// colortab -- make a color/code placemat +// +build !appengine + +package main + +import ( + "bufio" + "flag" + "fmt" + "os" + "strings" + + "github.com/ajstarks/svgo" +) + +func main() { + var ( + canvas = svg.New(os.Stdout) + filename = flag.String("f", "svgcolors.txt", "input file") + fontname = flag.String("font", "Calibri,sans-serif", "fontname") + outline = flag.Bool("o", false, "outline") + neg = flag.Bool("n", false, "negative") + showrgb = flag.Bool("rgb", false, "show RGB") + showcode = flag.Bool("showcode", true, "only show colors") + circsw = flag.Bool("circle", true, "circle swatch") + fontsize = flag.Int("fs", 12, "fontsize") + width = flag.Int("w", 1600, "width") + height = flag.Int("h", 900, "height") + rowsize = flag.Int("r", 32, "rowsize") + colw = flag.Int("c", 320, "column size") + swatch = flag.Int("s", 16, "swatch size") + gutter = flag.Int("g", 11, "gutter") + err error + colorfmt, tcolor, line string + ) + + flag.Parse() + f, oerr := os.Open(*filename) + if oerr != nil { + fmt.Fprintf(os.Stderr, "%v\n", oerr) + return + } + canvas.Start(*width, *height) + canvas.Title("SVG Color Table") + if *neg { + canvas.Rect(0, 0, *width, *height, "fill:black") + tcolor = "white" + } else { + canvas.Rect(0, 0, *width, *height, "fill:white") + tcolor = "black" + } + top := 32 + left := 32 + in := bufio.NewReader(f) + canvas.Gstyle(fmt.Sprintf("font-family:%s;font-size:%dpt;fill:%s", + *fontname, *fontsize, tcolor)) + for x, y, nr := left, top, 0; err == nil; nr++ { + line, err = in.ReadString('\n') + fields := strings.Split(strings.TrimSpace(line), "\t") + if nr%*rowsize == 0 && nr > 0 { + x += *colw + y = top + } + if len(fields) == 3 { + colorfmt = "fill:" + fields[1] + if *outline { + colorfmt = colorfmt + ";stroke-width:1;stroke:" + tcolor + } + if *circsw { + canvas.Circle(x, y, *swatch/2, colorfmt) + } else { + canvas.CenterRect(x, y, *swatch, *swatch, colorfmt) + } + canvas.Text(x+*swatch+*fontsize/2, y+(*swatch/4), fields[0], "stroke:none") + var label string + if *showcode { + if *showrgb { + label = fields[1] + } else { + label = fields[2] + } + canvas.Text(x+((*colw*4)/5), y+(*swatch/4), label, "text-anchor:end;fill:gray") + } + } + y += (*swatch + *gutter) + } + canvas.Gend() + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/colortab/svgcolors.txt b/vendor/github.com/ajstarks/svgo/colortab/svgcolors.txt new file mode 100644 index 0000000..88ae603 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/colortab/svgcolors.txt @@ -0,0 +1,147 @@ +aliceblue #F0F8FF 240,248,255 +antiquewhite #FAEBD7 250,235,215 +aqua #00FFFF 0,255,25 +aquamarine #7FFFD4 127,255,21 +azure #F0FFFF 240,255,255 +beige #F5F5DC 245,245,220 +bisque #FFE4C4 255,228,196 +black #000000 0,0,0 +blanchedalmond #FFEBCD 255,235,205 +blue #0000FF 0,0,255 +blueviolet #8A2BE2 138,43,226 +brown #A52A2A 165,42,42 +burlywood #DEB887 222,184,135 +cadetblue #5F9EA0 95,158,160 +chartreuse #7FFF00 127,255,0 +chocolate #D2691E 210,105,30 +coral #FF7F50 255,127,80 +cornflowerblue #6495ED 100,149,237 +cornsilk #FFF8DC 255,248,220 +crimson #DC143C 220,20,60 +cyan #00FFFF 0,255,255 +darkblue #00008B 0,0,139 +darkcyan #008B8B 0,139,139 +darkgoldenrod #B8860B 184,134,11 +darkgray #A9A9A9 169,169,169 +darkgreen #006400 0,100,0 +darkgrey #A9A9A9 169,169,169 +darkkhaki #BDB76B 189,183,107 +darkmagenta #8B008B 139,0,139 +darkolivegreen #556B2F 85,107,47 +darkorange #FF8C00 255,140,0 +darkorchid #9932CC 153,50,204 +darkred #8B0000 139,0,0 +darksalmon #E9967A 233,150,122 +darkseagreen #8FBC8F 143,188,143 +darkslateblue #483D8B 72,61,139 +darkslategray #2F4F4F 47,79,79 +darkslategrey #2F4F4F 47,79,79 +darkturquoise #00CED1 0,206,209 +darkviolet #9400D3 148,0,211 +deeppink #FF1493 255,20,147 +deepskyblue #00BFFF 0,191,255 +dimgray #696969 105,105,105 +dimgrey #696969 105,105,105 +dodgerblue #1E90FF 30,144,255 +firebrick #B22222 178,34,34 +floralwhite #FFFAF0 255,250,240 +forestgreen #228B22 34,139,34 +fuchsia #FF00FF 255,0,255 +gainsboro #DCDCDC 220,220,220 +ghostwhite #F8F8FF 248,248,255 +gold #FFD700 255,215,0 +goldenrod #DAA520 218,165,32 +gray #808080 128,128,128 +green #008000 0,128,0 +greenyellow #ADFF2F 173,255,47 +grey #808080 128,128,128 +honeydew #F0FFF0 240,255,240 +hotpink #FF69B4 255,105,180 +indianred #CD5C5C 205,92,92 +indigo #4B0082 75,0,130 +ivory #FFFFF0 255,255,240 +khaki #F0E68C 240,230,140 +lavender #E6E6FA 230,230,250 +lavenderblush #FFF0F5 255,240,245 +lawngreen #7CFC00 124,252,0 +lemonchiffon #FFFACD 255,250,205 +lightblue #ADD8E6 173,216,230 +lightcoral #F08080 240,128,128 +lightcyan #E0FFFF 224,255,255 +lightgoldenrodyellow #FAFAD2 250,250,210 +lightgray #D3D3D3 211,211,211 +lightgreen #90EE90 144,238,144 +lightgrey #D3D3D3 211,211,211 +lightpink #FFB6C1 255,182,193 +lightsalmon #FFA07A 255,160,122 +lightseagreen #20B2AA 32,178,170 +lightskyblue #87CEFA 135,206,250 +lightslategray #778899 119,136,153 +lightslategrey #778899 119,136,153 +lightsteelblue #B0C4DE 176,196,222 +lightyellow #FFFFE0 255,255,224 +lime #00FF00 0,255,0 +limegreen #32CD32 50,205,50 +linen #FAF0E6 250,240,230 +magenta #FF00FF 255,0,255 +maroon #800000 128,0,0 +mediumaquamarine #66CDAA 102,205,170 +mediumblue #0000CD 0,0,205 +mediumorchid #BA55D3 186,85,211 +mediumpurple #9370DB 147,112,219 +mediumseagreen #3CB371 60,179,113 +mediumslateblue #7B68EE 123,104,238 +mediumspringgreen #00FA9A 0,250,154 +mediumturquoise #48D1CC 72,209,204 +mediumvioletred #C71585 199,21,133 +midnightblue #191970 25,25,112 +mintcream #F5FFFA 245,255,250 +mistyrose #FFE4E1 255,228,225 +moccasin #FFE4B5 255,228,181 +navajowhite #FFDEAD 255,222,173 +navy #000080 0,0,128 +oldlace #FDF5E6 253,245,230 +olive #808000 128,128,0 +olivedrab #6B8E23 107,142,35 +orange #FFA500 255,165,0 +orangered #FF4500 255,69,0 +orchid #DA70D6 218,112,214 +palegoldenrod #EEE8AA 238,232,170 +palegreen #98FB98 152,251,152 +paleturquoise #AFEEEE 175,238,238 +palevioletred #DB7093 219,112,147 +papayawhip #FFEFD5 255,239,213 +peachpuff #FFDAB9 255,218,185 +peru #CD853F 205,133,63 +pink #FFC0CB 255,192,203 +plum #DDA0DD 221,160,221 +powderblue #B0E0E6 176,224,230 +purple #800080 128,0,128 +red #FF0000 255,0,0 +rosybrown #BC8F8F 188,143,143 +royalblue #4169E1 65,105,225 +saddlebrown #8B4513 139,69,19 +salmon #FA8072 250,128,114 +sandybrown #F4A460 244,164,96 +seagreen #2E8B57 46,139,87 +seashell #FFF5EE 255,245,238 +sienna #A0522D 160,82,45 +silver #C0C0C0 192,192,192 +skyblue #87CEEB 135,206,235 +slateblue #6A5ACD 106,90,205 +slategray #708090 112,128,144 +slategrey #708090 112,128,144 +snow #FFFAFA 255,250,250 +springgreen #00FF7F 0,255,127 +steelblue #4682B4 70,130,180 +tan #D2B48C 210,180,140 +teal #008080 0,128,128 +thistle #D8BFD8 216,191,216 +tomato #FF6347 255,99,71 +turquoise #40E0D0 64,224,208 +violet #EE82EE 238,130,238 +wheat #F5DEB3 245,222,179 +white #FFFFFF 255,255,255 +whitesmoke #F5F5F5 245,245,245 +yellow #FFFF00 255,255,0 +yellowgreen #9ACD32 154,205,50 diff --git a/vendor/github.com/ajstarks/svgo/compx/comps.xml b/vendor/github.com/ajstarks/svgo/compx/comps.xml new file mode 100644 index 0000000..178afc2 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/compx/comps.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/vendor/github.com/ajstarks/svgo/compx/compx.go b/vendor/github.com/ajstarks/svgo/compx/compx.go new file mode 100644 index 0000000..c9c1891 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/compx/compx.go @@ -0,0 +1,894 @@ +// compx: display components and connections on a grid, given a XML description +// +build !appengine + +package main + +import ( + "encoding/xml" + "flag" + "fmt" + "github.com/ajstarks/svgo" + "io" + "math" + "os" + "strconv" + "strings" + "time" +) + +// Component XML structures +type Component struct { + Top int `xml:"top,attr"` + Left int `xml:"left,attr"` + Gutter int `xml:"gutter,attr"` + Gw int `xml:"gw,attr"` + Gh int `xml:"gh,attr"` + Gc string `xml:"gc,attr"` + Legend []legend `xml:"legend"` + Note []note `xml:"note"` + Group []group `xml:"group"` + Comp []comp `xml:"comp"` +} + +type group struct { + Brow int `xml:"brow,attr"` + Bcol int `xml:"bcol,attr"` + Erow int `xml:"erow,attr"` + Ecol int `xml:"ecol,attr"` + Width int `xml:"width,attr"` + Height int `xml:"height,attr"` + Label string `xml:"label,attr"` + Color string `xml:"color,attr"` + Opacity float64 `xml:"opacity,attr"` +} + +type note struct { + Row int `xml:"row,attr"` + Col int `xml:"col,attr"` + Width int `xml:"width,attr"` + Height int `xml:"height,attr"` + Size int `xml:"size,attr"` + Spacing int `xml:"spacing,attr"` + Align string `xml:"align,attr"` + Nitem []nitem `xml:"nitem"` +} + +type legend struct { + Title string `xml:"title,attr"` + Row int `xml:"row,attr"` + Col int `xml:"col,attr"` + Width int `xml:"width,attr"` + Height int `xml:"height,attr"` + Size int `xml:"size,attr"` + Litem []litem `xml:"litem"` +} + +type comp struct { + Id string `xml:"id,attr"` + Col int `xml:"col,attr"` + Row int `xml:"row,attr"` + Width int `xml:"width,attr"` + Height int `xml:"height,attr"` + Name string `xml:"name,attr"` + Os string `xml:"os,attr"` + Sw string `xml:"sw,attr"` + Color string `xml:"color,attr"` + Shape string `xml:"shape,attr"` + Image string `xml:"image,attr"` + Connect []Connect `xml:"connect"` +} + +type litem struct { + Color string `xml:"color,attr"` + Type string `xml:"type,attr"` + Label string `xml:",chardata"` +} + +type nitem struct { + Color string `xml:"color,attr"` + Align string `xml:"align,attr"` + Text string `xml:",chardata"` +} + +// Connect defines connections +type Connect struct { + Sloc string `xml:"sloc,attr"` + Dloc string `xml:"dloc,attr"` + Dest string `xml:"dest,attr"` + Mark string `xml:"mark,attr"` + Color string `xml:"color,attr"` + Dir string `xml:"dir,attr"` + Label string `xml:",chardata"` +} + +type gcomp struct { + x, y, w, h int +} + +var ( + width, height, fontscale int + linesize, labelfs, notchsize, groupmargin int + showtitle, showtimestamp, roundbox, arc, italiclabel bool + title, bgcolor, guide string + gridw = 0 + gridh = 0 + globalcolor = "black" + canvas = svg.New(os.Stdout) +) + +const ( + lcolor = "rgb(190,190,190)" + boxradius = 10 + lopacity = "1.0" + defcolor = "black" + linefmt = "stroke:%s;fill:none" + globalstyle = "font-family:Calibri,sans-serif;font-size:%dpx;fill:black;text-anchor:middle;stroke-linecap:round;stroke-width:%dpx;stroke-opacity:%s" + ltstyle = "text-anchor:%s;fill:black" + legendstyle = "text-anchor:start;fill:black;font-size:%dpx" + gridstyle = "fill:none; stroke:gray; stroke-opacity:0.3" + notefmt = "font-size:%dpx" + ntfmt = "text-anchor:%s;fill:%s" +) + +func background(fc string) { canvas.Rect(0, 0, width, height, "fill:"+fc) } + +// docomp does XML file processing +func docomp(location string) { + var f *os.File + var err error + if len(location) > 0 { + f, err = os.Open(location) + } else { + f = os.Stdin + } + + if err == nil { + readcomp(f) + f.Close() + } else { + fmt.Fprintf(os.Stderr, "%v\n", err) + } +} + +// readcomp reads the XML into the component data structure +func readcomp(r io.Reader) { + var c Component + if err := xml.NewDecoder(r).Decode(&c); err == nil { + drawc(c) + } else { + fmt.Fprintf(os.Stderr, "Unable to parse components (%v)\n", err) + } +} + +// drawc interprets the compoment data structure, and displays it +func drawc(c Component) { + gridw = c.Gw + gridh = c.Gh + if len(c.Gc) == 0 { + globalcolor = c.Gc + } else { + globalcolor = c.Gc + } + + // Groups + for _, group := range c.Group { + dogroup(group, c.Top, c.Left, c.Gutter) + } + + // Legends + for _, leg := range c.Legend { + dolegend(leg, c.Top, c.Left, c.Gutter, labelfs, labelfs+4) + } + + // Notes + for _, note := range c.Note { + donote(note, c.Top, c.Left, c.Gutter) + } + + // Components + for _, x := range c.Comp { + for _, y := range x.Connect { + connect(gc(x, c.Top, c.Left, c.Gutter), y.Sloc, + lookup(y.Dest, c.Comp, c.Top, c.Left, c.Gutter), + y.Dloc, y.Label, y.Mark, y.Dir, y.Color) + } + display(x, c.Top, c.Left, c.Gutter) + } + + if len(guide) > 0 { + grid(c.Top, c.Left, c.Gutter) + } + if showtitle { + dotitle(c.Left, 30, title) + } + if showtimestamp { + timestamp(30) + } +} + +// lookup returns a graphic object given an id +func lookup(id string, c []comp, t, l, g int) gcomp { + var x gcomp + for _, v := range c { + if id == v.Id { + return gc(v, t, l, g) + } + } + return x +} + +// dotitle positions the title relative to the bottom of the drawing +func dotitle(left, offset int, t string) { + canvas.Text(left, height-offset, t, "font-size:200%;text-anchor:start") +} + +// timestamp draws a timestamp in the lower right of the drawing +func timestamp(offset int) { + t := time.Now() + canvas.Text(width-offset, height-offset, t.Format(time.ANSIC), "text-anchor:end") +} + +// grid displays a grid overlay, useful for determining optimal positioning +func grid(top, left, gutter int) { + gs := strings.SplitN(guide, `x`, 4) + if len(gs) != 4 { + return + } + w, _ := strconv.Atoi(gs[0]) + h, _ := strconv.Atoi(gs[1]) + nr, _ := strconv.Atoi(gs[2]) + nc, _ := strconv.Atoi(gs[3]) + canvas.Gstyle(gridstyle) + y := top + for r := 0; r < nr; r++ { + x := left + for c := 0; c < nc; c++ { + canvas.Rect(x, y, w, h) + canvas.Text(x+w/2, y+h/2, fmt.Sprintf("%d,%d", r, c), + "font-size:150%;fill:lightgray;stroke:none") + x += w + gutter + } + y += h + gutter + } + canvas.Gend() +} + +// dogroup displays a colored rectangular area +func dogroup(g group, top, left, gutter int) { + margin := groupmargin + bx := colx(g.Bcol, g.Width, gutter, left) + by := rowy(g.Brow, g.Height, gutter, top) + ex := colx(g.Ecol, g.Width, gutter, left) + ey := rowy(g.Erow, g.Height, gutter, top) + gw := (ex + g.Width) - bx + gh := (ey + g.Height) - by + var gop float64 + if g.Opacity <= 0 { + gop = 1.0 + } else { + gop = g.Opacity + } + canvas.Rect(bx-margin, by-margin, gw+margin*2, gh+margin*2, + fmt.Sprintf("fill-opacity:%.2f;fill:%s", gop, g.Color)) + if len(g.Label) > 0 { + canvas.Text(bx+gw/2, by+gh/2, g.Label, "fill:gray") + } +} + +// dolegend displays the legend +func dolegend(leg legend, top, left, gutter, fs, ls int) { + if leg.Size > 0 { + fs = leg.Size + ls = fs + 4 + } + fsh := fs / 2 + x := colx(leg.Col, leg.Width, gutter, left) + y := rowy(leg.Row, leg.Height, gutter, top) + + canvas.Gstyle(fmt.Sprintf(legendstyle, fs)) + for _, v := range leg.Litem { + if v.Type == "line" { + canvas.Rect(x, y+fs/4, fs, fs/4, "fill:"+v.Color) + } else { + canvas.Square(x, y, fs, "fill:"+v.Color) + } + canvas.Text(x+(fs*2), y+fsh, v.Label, "baseline-shift:-30%") + y += ls + } + canvas.Gend() +} + +// donote displays a note +func donote(n note, top, left, gutter int) { + var align, color string + + size := n.Size + ls := n.Spacing + x := colx(n.Col, n.Width, gutter, left) + y := rowy(n.Row, n.Height, gutter, top) + if n.Align == "middle" { + y += n.Height / 2 + } + if size <= 0 { + size = labelfs + } + if ls == 0 { + ls = size + 2 + } + xp := x + canvas.Gstyle(fmt.Sprintf(notefmt, size)) + for _, v := range n.Nitem { + switch v.Align { + case "left", "start", "begin": + align = "start" + xp = x + case "right", "end": + align = "end" + xp = x + n.Width + case "middle", "mid", "center": + align = "middle" + xp = x + (n.Width / 2) + default: + align = "start" + xp = x + } + if len(v.Color) == 0 { + color = "black" + } else { + color = v.Color + } + canvas.Text(xp, y, v.Text, fmt.Sprintf(ntfmt, align, color)) + y += ls + } + canvas.Gend() +} + +// gc computes the components coordinates +func gc(c comp, top, left, gutter int) gcomp { + var g gcomp + + // the object and grid dimensions equal, unless explicitly overridden + + if gridw > 0 && gridh > 0 { + g.x = colx(c.Col, gridw, gutter, left) + g.y = rowy(c.Row, gridh, gutter, top) + } else { + g.x = colx(c.Col, c.Width, gutter, left) + g.y = rowy(c.Row, c.Height, gutter, top) + } + g.w = c.Width + g.h = c.Height + return g +} + +// display a component in the context of the grid +func display(c comp, top, left, gutter int) { + g := gc(c, top, left, gutter) + component(g, c) +} + +// component positions and draws a components and its attributes +func component(g gcomp, c comp) { + x := g.x + y := g.y + w := g.w + h := g.h + fs := w / fontscale + fs2 := fs / 2 + w2 := w / 2 + h3 := h / 3 + + var boxcolor string + if len(c.Color) == 0 { + boxcolor = globalcolor + } else { + boxcolor = c.Color + } + rectstyle := fmt.Sprintf("stroke:%s;stroke-width:1;fill:%s", boxcolor, boxcolor) + + if len(c.Image) > 0 { + canvas.Image(x, y, w, h, c.Image) + if len(c.Name) > 0 { + canvas.Text(x+w2, y+h/3, c.Name, + fmt.Sprintf("font-size:%dpx;fill:%s;baseline-shift:50%%", fs, boxcolor)) + } + return + } + + if strings.HasPrefix(c.Shape, "#") { + uselibrary(x, y, w, h, c.Shape) + return + } + + switch c.Shape { + + case "mobile", "screen": + screen(x, y, w, h, 10, boxcolor, bgcolor) + canvas.Gstyle(fmt.Sprintf("font-size:%dpx", fs)) + canvas.Text(x+w/2, y+h/3, c.Name) + if len(c.Os) > 0 { + canvas.Text(x+w/2, y+h3+fs+2, c.Os, "font-size:60%") + } + if len(c.Sw) > 0 { + canvas.Text(x+w/2, y+h3+fs*2, c.Sw, "font-size:75%") + } + canvas.Gend() + + case "server": + server(x, y, w, h, 10, boxcolor, lcolor) + canvas.Text(x+w/2, y+h-10, c.Name, fmt.Sprintf("font-size:%dpx;fill:white", fs)) + + case "desktop": + l := h / 20 + desktop(x, y, w, h, l, boxcolor, bgcolor) + canvas.Gstyle(fmt.Sprintf("font-size:%dpx", fs)) + canvas.Text(x+w/2, y+h/3, c.Name) + if len(c.Os) > 0 { + canvas.Text(x+w/2, y+h3+fs+2, c.Os, "font-size:60%") + } + if len(c.Sw) > 0 { + canvas.Text(x+w/2, y+h3+fs*2, c.Sw, "font-size:75%") + } + canvas.Gend() + + case "message": + l := h / 20 + pmy := h / 8 + message(x, y, w, h, l, lcolor, boxcolor) + canvas.Gstyle(fmt.Sprintf("font-size:%dpx;fill:white", fs)) + if len(c.Os) > 0 { + canvas.Text(x+w2, y+pmy+fs, c.Os, "font-size:75%") + } + canvas.Text(x+w2, y+h-10, c.Name, fmt.Sprintf("font-size:%dpx;fill:%s", fs, bgcolor)) + canvas.Gend() + + case "cloud": + r := w / 3 + xc := (x + w/2) + r/4 + yc := y + h/2 + cloud(xc, yc, r, boxcolor) + canvas.Text(xc-(r/4), yc+r/2, c.Name, fmt.Sprintf("font-size:%dpx;fill:white", fs)) + + case "db": + cylinder(x, y+(h/4), w, h-(h/2), h/4, lcolor, boxcolor) + canvas.Text(x+w2, y+h3, c.Name, fmt.Sprintf("font-size:%dpx;fill:white", fs)) + if len(c.Sw) > 0 { + canvas.Text(x+w2, y+2*h3, c.Sw, "font-size:75%") + } + + case "folder": + l := w / 10 + folder(x, y, w, h, l, boxcolor, lcolor) + yp := y + h/2 + canvas.Gstyle(fmt.Sprintf("font-size:%dpx;fill:white", fs)) + canvas.Text(x+w/2, yp, c.Name) + if len(c.Os) > 0 { + canvas.Text(x+w/2, yp+fs+2, c.Os, "font-size:60%") + } + if len(c.Sw) > 0 { + canvas.Text(x+w/2, yp+fs*2, c.Sw, "font-size:75%") + } + canvas.Gend() + + case "face": + fr := (w / 4) - (fs / 2) // (h*3)/8 + face(x+w/2, y+h/2, fr, linesize, boxcolor, bgcolor) + canvas.Text(x+w/2, y+(h/2)+fr+15, c.Name, fmt.Sprintf("font-size:%dpx;fill:black", fs)) + + case "role": + role(x, y, w, h, boxcolor) + canvas.Text(x+w/2, y+h-5, c.Name, fmt.Sprintf("font-size:%dpx;fill:%s", fs, bgcolor)) + + case "eaec": + l := w / 10 + eaec(x, y, w, h, l, boxcolor, bgcolor) + canvas.Text(x+w/2, y+h-5, c.Name, fmt.Sprintf("font-size:%dpx;fill:%s", fs, bgcolor)) + + case "plain": + if roundbox { + canvas.Roundrect(x, y, w, h, fs2, fs2, rectstyle) + } else { + canvas.Rect(x, y, w, h, rectstyle) + } + canvas.Text(x+w2, y+(h/2), c.Name, fmt.Sprintf("font-size:%dpx;fill:white;baseline-shift:-25%%", fs)) + + default: + canvas.Rect(x, y, w, h3, rectstyle) + canvas.Rect(x, y+h3, w, h-h3, "fill:white;stroke-width:1;stroke:gray") + canvas.Gstyle(fmt.Sprintf("font-size:%dpx", fs)) + canvas.Text(x+w2, y+h3, c.Name, "fill:white;baseline-shift:50%") + canvas.Text(x+w2, y+h3+fs2, c.Os, "font-size:60%") + wordstack(x+w2, (y+h)-fs2, fs, strings.Split(c.Sw, `\n`), "fill-opacity:0.75;font-size:75%") + canvas.Gend() + } +} + +// uselibrary draws a previously defined object +func uselibrary(x, y, w, h int, name string) { + canvas.Use(x, y, name, fmt.Sprintf(`width="%d"`, w), fmt.Sprintf(`height="%d"`, h)) +} + +// Object functions +func cylinder(x, y, w, h, eh int, fill, tfill string) { + f := "fill:" + fill + tf := "fill:" + tfill + canvas.Rect(x, y, w, h, f) + canvas.Ellipse(x+w/2, y+h, w/2, eh, f) + canvas.Ellipse(x+w/2, y, w/2, eh, tf) +} + +// folder object +func folder(x, y, w, h, l int, bcolor, color string) { + nl := w / 10 + xl := x + nl + xw := x + w + yl := y + nl + yh := y + h + l2 := nl * 2 + l3 := nl * 3 + lh := nl / 2 + var ( + xn = []int{xl, xl + l2, xl + l3, xw, xw, xl} + yn = []int{y, y, y + lh, y + lh, yh, yh} + xf = []int{xw, xw - l, x, x + l} + yf = []int{yh, yl + lh, yl + lh, yh} + ) + canvas.Polygon(xn, yn, "fill:"+color) + canvas.Polygon(xf, yf, "fill:"+bcolor) +} + +// cloud object +func cloud(x, y, r int, style string) { + small := r / 2 + medium := (r * 6) / 10 + canvas.Gstyle("fill:" + style) + canvas.Circle(x, y, r) + canvas.Circle(x+r, y+small, small) + canvas.Circle(x-r-small, y+small, small) + canvas.Circle(x-r, y, medium) + canvas.Rect(x-r-small, y, r*2+small, r) + canvas.Gend() +} + +// message object +func message(x, y, w, h, l int, bcolor, scolor string) { + et := h / 3 + w2 := w / 2 + px := w / 8 + py := h / 8 + e1x := []int{x, x, x + w, x + w, x + w2, x} + e1y := []int{y + et, y + h, y + h, y + et, y + (et * 2), y + et} + e2x := []int{x, x + w2, x + w, x + w2, x} + e2y := []int{y + et, y, y + et, y + (et * 2), y + et} + + canvas.Polygon(e2x, e2y, "fill:"+bcolor) + canvas.Polygon(e1x, e1y, "fill:"+scolor) + canvas.Roundrect(x+px, y+py, w-(px*2), h-py, l, l, "fill:"+scolor) + canvas.Line(x, y+et, x+w2, y+(et*2), "stroke-width:1;stroke:"+bcolor) + canvas.Line(x+w, y+et, x+w2, y+(et*2), "stroke-width:1;stroke:"+bcolor) +} + +// eaec person object +func eaec(x, y, w, h, l int, scolor, bcolor string) { + wu := w / 8 + hu := h / 12 + wh := w / 2 + hh := h / 2 + sx := []int{x + wu*2, x + wu*6, x + wh} + sy := []int{y + hu*6, y + hu*6, y + hu*11} + tx := []int{x + wh, x + wh + wu, x + wh, x + wh - wu, x + wh} + ty := []int{y + hu*6, y + hu*7, y + hu*10, y + hu*7, y + hu*6} + + canvas.Ellipse(x+wh, y+hu*4, wu+wu/2, hu*2, "fill:"+bcolor) + canvas.Roundrect(x+wu, y+hh, w-wu*2, hu*6, l, l, "fill:"+bcolor) + canvas.Polygon(sx, sy, "fill:"+scolor) + canvas.Polygon(tx, ty, "fill:"+bcolor) +} + +// screen object +func screen(x, y, w, h, l int, bcolor, color string) { + canvas.Roundrect(x, y, w, h, l, l, "fill:"+bcolor) + canvas.Rect(x+l, y+l, w-(l*2), h-(l*2), "fill:"+color) +} + +// kb (keyboard) object +func kb(x, y, w, h, l int, color string) { + var xp = []int{x + l, x, x + w, x + w - l} + var yp = []int{y, y + h, y + h, y} + canvas.Polygon(xp, yp, "fill:"+color) +} + +// desktop object +func desktop(x, y, w, h, l int, bcolor, color string) { + screen(x, y, w, h-l*3, l, bcolor, color) + kb(x, y+h-(l*2), w+l, l*2, l*2, bcolor) +} + +// face object +func face(x, y, r, l int, color, fcolor string) { + fu := r / 10 // "face unit" + ep := 3 * fu + my := y + ep + canvas.Circle(x, y, r, fmt.Sprintf("fill:%s;stroke-width:%dpx;stroke:%s", fcolor, l, color)) + canvas.Circle(x+ep, y-ep, r/10, "fill:"+color) + canvas.Circle(x-ep, y-ep, r/10, "fill:"+color) + canvas.Qbez(x+ep, my, x, y+ep*2, x-ep, my, fmt.Sprintf("fill:%s;stroke-width:%dpx;stroke:%s", color, l, color)) +} + +// server object +func server(x, y, w, h, l int, bcolor, color string) { + var xp = []int{x + (l * 2), (x + w) - (l * 2), (x + w) - l, x + l} + var yp = []int{y, y, y + l, y + l} + canvas.Polygon(xp, yp, "fill:"+color) + canvas.Roundrect(x, y+l, w, h-l, 5, 5, "fill:"+bcolor) + canvas.Gstyle("stroke:" + color) + yl := y + (l / 2) + h/4 + spacing := w / 5 + for r := 0; r < 2; r++ { + xl := x + l + for c := 0; c < 2; c++ { + canvas.Line(xl, yl, xl+spacing, yl) + xl += spacing + 10 + } + yl += h / 4 + } + canvas.Gend() + canvas.Circle((x+w)-l, y+h/2, l/2, "fill:"+color) +} + +// role object +func role(x, y, w, h int, color string) { + hs := h / 20 + var xp = []int{x, x, x + w/3, x + w/2, x + (w / 2) + (w / 6), x + w, x + w} + var yp = []int{y + h, y + (16 * hs), y + (12 * hs), y + (14 * hs), y + (12 * hs), y + (16 * hs), y + h} + + // var xp = []int{x, x, x + w/2, x + w, x + w} + // var yp = []int{y + h, y + (h5 * 4), y + (h5 * 2), y + (h5 * 4), y + h} + canvas.Gstyle("fill:" + color) + canvas.Polygon(xp, yp) + canvas.Ellipse(x+w/2, (y + h/3), w/5, h/3) // "stroke:white;stroke-width:2") + canvas.Gend() +} + +// sloper computes the slope and r of a line +func sloper(x1, y1, x2, y2 int) (m, r float64) { + dy := float64(y1 - y2) + dx := float64(x1 - x2) + m = dy / dx + r = math.Atan2(dy, dx) * (180 / math.Pi) + return m, r +} + +// rowy computes the y position of a row +func rowy(n, h, g, t int) int { return t + (n * g) + (n * h) } + +// colx computes the x position of a column +func colx(n, w, g, l int) int { return l + (n * g) + (n * w) } + +// compass returns the coordinates of a compass point +func compass(g gcomp, point string) (cx, cy int, dir string) { + switch point { + case "nw": + cx, cy, dir = g.x, g.y, "r" + case "nnw": + cx, cy, dir = g.x+g.w/4, g.y, "d" + case "nne": + cx, cy, dir = (g.x+g.w)-(g.w/4), g.y, "d" + case "n": + cx, cy, dir = g.x+(g.w/2), g.y, "d" + case "ne": + cx, cy, dir = g.x+g.w, g.y, "l" + case "w": + cx, cy, dir = g.x, g.y+g.h/2, "r" + case "wnw": + cx, cy, dir = g.x, g.y+g.h/4, "r" + case "wsw": + cx, cy, dir = g.x, (g.y+g.h)-(g.h/4), "r" + case "ese": + cx, cy, dir = g.x+g.w, (g.y+g.h)-(g.h/4), "l" + case "ene": + cx, cy, dir = g.x+g.w, g.y+(g.h/4), "l" + case "c": + cx, cy, dir = g.x+(g.w/2), g.y+(g.h/2), "n" + case "e": + cx, cy, dir = g.x+g.w, g.y+(g.h/2), "l" + case "sw": + cx, cy, dir = g.x, g.y+g.h, "r" + case "ssw": + cx, cy, dir = g.x+(g.w/4), g.y+g.h, "u" + case "sse": + cx, cy, dir = (g.x+g.w)-(g.w/4), g.y+g.h, "u" + case "s": + cx, cy, dir = g.x+(g.w/2), g.y+g.h, "u" + case "se": + cx, cy, dir = g.x+g.w, g.y+g.h, "l" + } + return cx, cy, dir +} + +// connect two components +func connect(c1 gcomp, p1 string, c2 gcomp, p2 string, label string, mark string, dir string, color string) { + x1, y1, d1 := compass(c1, p1) + x2, y2, d2 := compass(c2, p2) + linelabel(x1, y1, x2, y2, label, mark, d1, d2, dir, color) +} + +// linestyle returns the style for lines +func linestyle(color string) string { + return fmt.Sprintf(linefmt, color) +} + +// linelabel determines the connection and arrow geometry +func linelabel(x1, y1, x2, y2 int, label string, mark string, d1 string, d2 string, dir string, color string) { + aw := linesize * 4 + ah := linesize * 3 + + if len(color) == 0 { + color = lcolor + } + switch mark { + case "b": + lx1, ly1 := arrow(x1, y1, aw, ah, d1, color) + lx2, ly2 := arrow(x2, y2, aw, ah, d2, color) + doline(lx1, ly1, lx2, ly2, linestyle(color), dir, label) + + case "s": + lx1, ly1 := arrow(x1, y1, aw, ah, d1, color) + doline(lx1, ly1, x2, y2, linestyle(color), dir, label) + + case "d": + lx2, ly2 := arrow(x2, y2, aw, ah, d2, color) + doline(x1, y1, lx2, ly2, linestyle(color), dir, label) + + default: + doline(x1, y1, x2, y2, linestyle(color), dir, label) + } +} + +// doline draws a line between to coordinates +func doline(x1, y1, x2, y2 int, style, direction, label string) { + var labelstyle string + var upflag bool + + if italiclabel { + labelstyle = "font-style:italic;" + } + + tadjust := 6 + mx := (x2 - x1) / 2 + my := (y2 - y1) / 2 + lx := x1 + mx + ly := y1 + my + m, _ := sloper(x1, y1, x2, y2) + hline := m == 0 + vline := m == math.Inf(-1) || m == math.Inf(1) + straight := hline || vline + + switch { + case m < 0: // upwards line + upflag = true + labelstyle += "text-anchor:end;" + lx -= tadjust + case hline: // horizontal line + labelstyle += "text-anchor:middle;baseline-shift:20%;" + ly -= tadjust + case m > 0: // downwards line + upflag = false + labelstyle += "text-anchor:start;" + lx += tadjust + } + if arc && !straight { + cx, cy := x1, y2 // initial control points + // fmt.Fprintf(os.Stderr, "%s slope = %.3f\n", label, m) + if upflag { + if direction == "ccw" { + cx, cy = x2, y1 + } else { + cx, cy = x1, y2 + } + } else { + if direction == "ccw" { + cx, cy = x1, y2 + } else { + cx, cy = x2, y1 + } + } + canvas.Qbez(x1, y1, cx, cy, x2, y2, style) + labelstyle += "text-anchor:middle" + canvas.Text(lx, ly, label, labelstyle) + } else { + canvas.Line(x1, y1, x2, y2, style) + canvas.Text(lx, ly, label, labelstyle) // midpoint + } +} + +// wordstack displays text in a left-justified stack +func wordstack(x, y, fs int, s []string, style ...string) { + ls := fs + 2 + for i := len(s); i > 0; i-- { + canvas.Text(x, y, s[i-1], style...) + y -= ls + } +} + +// arrow constructs line-ending arrows according to connecting points +func arrow(x, y, w, h int, dir string, color string) (xl, yl int) { + var xp = []int{x, x, x, x} + var yp = []int{y, y, y, y} + + n := notchsize + switch dir { + case "r": + xp[1] = x - w + yp[1] = y - h/2 + xp[2] = (x - w) + n + yp[2] = y + xp[3] = x - w + yp[3] = y + h/2 + xl, yl = xp[2], y + case "l": + xp[1] = x + w + yp[1] = y - h/2 + xp[2] = (x + w) - n + yp[2] = y + xp[3] = x + w + yp[3] = y + h/2 + xl, yl = xp[2], y + case "u": + xp[1] = x - w/2 + yp[1] = y + h + xp[2] = x + yp[2] = (y + h) - n + xp[3] = x + w/2 + yp[3] = y + h + xl, yl = x, yp[2] + case "d": + xp[1] = x - w/2 + yp[1] = y - h + xp[2] = x + yp[2] = (y - h) + n + xp[3] = x + w/2 + yp[3] = y - h + xl, yl = x, yp[2] + } + canvas.Polygon(xp, yp, "fill:"+color+";fill-opacity:"+lopacity) + return xl, yl +} + +// init processes command line arguments +func init() { + flag.IntVar(&width, "w", 1024, "width") + flag.IntVar(&height, "h", 768, "height") + flag.IntVar(&linesize, "l", 4, "line weight") + flag.IntVar(&labelfs, "lf", 16, "label font size (px)") + flag.IntVar(&fontscale, "f", 10, "font scaling factor") + flag.IntVar(¬chsize, "n", 0, "arrow notch size") + flag.IntVar(&groupmargin, "gm", 10, "group margin") + flag.StringVar(&bgcolor, "bg", "white", "background color") + flag.StringVar(&title, "t", "comp grid", "title") + flag.BoolVar(&italiclabel, "il", false, "italic labels") + flag.BoolVar(&showtitle, "showtitle", false, "Show the title") + flag.BoolVar(&showtimestamp, "time", false, "Show a timestamp") + flag.BoolVar(&roundbox, "roundbox", false, "make boxes round") + flag.BoolVar(&arc, "arc", false, "use arcs to connect") + flag.StringVar(&guide, "g", "", "grid guide: WxHxRxC") + flag.Parse() +} + +// for every file (or stdin) make a component diagram +func main() { + canvas.Start(width, height) + canvas.Title(title) + background(bgcolor) + canvas.Gstyle(fmt.Sprintf(globalstyle, labelfs, linesize, lopacity)) + + if len(flag.Args()) == 0 { + docomp("") + } else { + for _, f := range flag.Args() { + docomp(f) + } + } + canvas.Gend() + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/compx/testcomp.xml b/vendor/github.com/ajstarks/svgo/compx/testcomp.xml new file mode 100644 index 0000000..acbfb92 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/compx/testcomp.xml @@ -0,0 +1,69 @@ + + + + Component + Another Thing + + + Public + Confidential + Restricted + Highly Restricted + + + Note + This is the test pattern for compx + for best results, set the width to be + at least 1300 + + the management + + + Here is another Note + This one is bigger + + + a stupid note + you did not specify anything + + + + + + + + + + + + + + + [1] + [2] + [3] + North to East + + + [4] + [5] + [6] + [7] + [8] + West to North + + + [9] + [10] + [11] + South to West + + + [12] + [13] + [14] + [15] + [16] + East to South + + diff --git a/vendor/github.com/ajstarks/svgo/cube/cube.go b/vendor/github.com/ajstarks/svgo/cube/cube.go new file mode 100644 index 0000000..1c4897a --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/cube/cube.go @@ -0,0 +1,71 @@ +// cube: draw cubes +package main + +import ( + "crypto/rand" + "flag" + "fmt" + "os" + + "github.com/ajstarks/svgo" +) + +var canvas = svg.New(os.Stdout) + +// randcolor returns a random color +func randcolor() string { + rgb := []byte{0, 0, 0} // read error returns black + rand.Read(rgb) + return fmt.Sprintf("fill:rgb(%d,%d,%d)", rgb[0], rgb[1], rgb[2]) +} + +// rcube makes a cube with three visible faces, each with a random color +func rcube(x, y, l int) { + tx := []int{x, x + (l * 3), x, x - (l * 3), x} + ty := []int{y, y + (l * 2), y + (l * 4), y + (l * 2), y} + + lx := []int{x - (l * 3), x, x, x - (l * 3), x - (l * 3)} + ly := []int{y + (l * 2), y + (l * 4), y + (l * 8), y + (l * 6), y + (l * 2)} + + rx := []int{x + (l * 3), x + (l * 3), x, x, x + (l * 3)} + ry := []int{y + (l * 2), y + (l * 6), y + (l * 8), y + (l * 4), y + (l * 2)} + + canvas.Polygon(tx, ty, randcolor()) + canvas.Polygon(lx, ly, randcolor()) + canvas.Polygon(rx, ry, randcolor()) +} + +// lattice draws a grid of cubes, n rows deep. +// The grid begins at (xp, yp), with hspace between cubes in a row, and vspace between rows. +func lattice(xp, yp, w, h, size, hspace, vspace, n int, bgcolor string) { + if bgcolor == "" { + canvas.Rect(0, 0, w, h, randcolor()) + } else { + canvas.Rect(0, 0, w, h, "fill:"+bgcolor) + } + y := yp + for r := 0; r < n; r++ { + for x := xp; x < w; x += hspace { + rcube(x, y, size) + } + y += vspace + } +} + +func main() { + var ( + width = flag.Int("w", 600, "canvas width") + height = flag.Int("h", 600, "canvas height") + x = flag.Int("x", 60, "begin x location") + y = flag.Int("y", 60, "begin y location") + size = flag.Int("size", 20, "cube size") + rows = flag.Int("rows", 3, "rows") + hs = flag.Int("hs", 120, "horizontal spacing") + vs = flag.Int("vs", 160, "vertical spacing") + bg = flag.String("bg", "", "background") + ) + flag.Parse() + canvas.Start(*width, *height) + lattice(*x, *y, *width, *height, *size, *hs, *vs, *rows, *bg) + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/doc.go b/vendor/github.com/ajstarks/svgo/doc.go new file mode 100644 index 0000000..a6b22f9 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/doc.go @@ -0,0 +1,118 @@ +/* +Package svg generates SVG as defined by the Scalable Vector Graphics 1.1 Specification (). +Output goes to the specified io.Writer. + +Supported SVG elements and functions + +Shapes, lines, text + + circle, ellipse, polygon, polyline, rect (including roundrects), line, text + +Paths + + general, arc, cubic and quadratic bezier paths, + +Image and Gradients + + image, linearGradient, radialGradient, + +Transforms + + translate, rotate, scale, skewX, skewY + +Filter Effects + + filter, feBlend, feColorMatrix, feColorMatrix, feComponentTransfer, feComposite, feConvolveMatrix, feDiffuseLighting, + feDisplacementMap, feDistantLight, feFlood, feGaussianBlur, feImage, feMerge, feMorphology, feOffset, fePointLight, + feSpecularLighting, feSpotLight,feTile, feTurbulence + + +Metadata elements + + desc, defs, g (style, transform, id), mask, marker, pattern, title, (a)ddress, link, script, use + +Usage: (assuming GOPATH is set) + + go get github.com/ajstarks/svgo + go install github.com/ajstarks/svgo/... + + +You can use godoc to browse the documentation from the command line: + + $ godoc github.com/ajstarks/svgo + + +a minimal program, to generate SVG to standard output. + + package main + + import ( + "github.com/ajstarks/svgo" + "os" + ) + + func main() { + width := 500 + height := 500 + canvas := svg.New(os.Stdout) + canvas.Start(width, height) + canvas.Circle(width/2, height/2, 100) + canvas.Text(width/2, height/2, "Hello, SVG", "text-anchor:middle;font-size:30px;fill:white") + canvas.End() + } + +Drawing in a web server: (http://localhost:2003/circle) + + package main + + import ( + "log" + "github.com/ajstarks/svgo" + "net/http" + ) + + func main() { + http.Handle("/circle", http.HandlerFunc(circle)) + err := http.ListenAndServe(":2003", nil) + if err != nil { + log.Fatal("ListenAndServe:", err) + } + } + + func circle(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Content-Type", "image/svg+xml") + s := svg.New(w) + s.Start(500, 500) + s.Circle(250, 250, 125, "fill:none;stroke:black") + s.End() + } + +Functions and types + +Many functions use x, y to specify an object's location, and w, h to specify the object's width and height. +Where applicable, a final optional argument specifies the style to be applied to the object. +The style strings follow the SVG standard; name:value pairs delimited by semicolons, or a +series of name="value" pairs. For example: `"fill:none; opacity:0.3"` or `fill="none" opacity="0.3"` (see: ) + +The Offcolor type: + + type Offcolor struct { + Offset uint8 + Color string + Opacity float + } + +is used to specify the offset, color, and opacity of stop colors in linear and radial gradients + +The Filterspec type: + + type Filterspec struct { + In string + In2 string + Result string + } + +is used to specify inputs and results for filter effects + +*/ +package svg diff --git a/vendor/github.com/ajstarks/svgo/f50/f50.go b/vendor/github.com/ajstarks/svgo/f50/f50.go new file mode 100644 index 0000000..3f96a1c --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/f50/f50.go @@ -0,0 +1,120 @@ +// f50 -- given a search term, display 10x5 image grid, sorted by interestingness +// +build !appengine + +package main + +import ( + "encoding/xml" + "fmt" + "net/http" + "net/url" + "os" + + "github.com/ajstarks/svgo" +) + +// FlickrResp defines the Flickr response +type FlickrResp struct { + Stat string `xml:"stat,attr"` + Photos Photos `xml:"photos"` +} + +// Photos defines a set of Flickr photos +type Photos struct { + Page string `xml:"page,attr"` + Pages string `xml:"pages,attr"` + Perpage string `xml:"perpage,attr"` + Total string `xml:"total,attr"` + Photo []Photo `xml:"photo"` +} + +// Photo defines a Flickr photo +type Photo struct { + Id string `xml:"id,attr"` + Owner string `xml:"owner,attr"` + Secret string `xml:"secret,attr"` + Server string `xml:"server,attr"` + Farm string `xml:"farm,attr"` + Title string `xml:"title,attr"` + Ispublic string `xml:"ispublic,attr"` + Isfriend string `xml:"isfriend,attr"` + IsFamily string `xml:"isfamily,attr"` +} + +var ( + width = 805 + height = 500 + canvas = svg.New(os.Stdout) +) + +const ( + apifmt = "https://api.flickr.com/services/rest/?method=%s&api_key=%s&%s=%s&per_page=50&sort=interestingness-desc" + urifmt = "http://farm%s.static.flickr.com/%s/%s.jpg" + apiKey = "YOURKEY" + textStyle = "font-family:Calibri,sans-serif; font-size:48px; fill:white; text-anchor:start" + imageWidth = 75 + imageHeight = 75 +) + +// FlickrAPI calls the API given a method with single name/value pair +func flickrAPI(method, name, value string) string { + return fmt.Sprintf(apifmt, method, apiKey, name, value) +} + +// makeURI converts the elements of a photo into a Flickr photo URI +func makeURI(p Photo, imsize string) string { + im := p.Id + "_" + p.Secret + + if len(imsize) > 0 { + im += "_" + imsize + } + return fmt.Sprintf(urifmt, p.Farm, p.Server, im) +} + +// imageGrid reads the response from Flickr, and creates a grid of images +func imageGrid(f FlickrResp, x, y, cols, gutter int, imgsize string) { + if f.Stat != "ok" { + fmt.Fprintf(os.Stderr, "Status: %v\n", f.Stat) + return + } + xpos := x + for i, p := range f.Photos.Photo { + if i%cols == 0 && i > 0 { + xpos = x + y += (imageHeight + gutter) + } + canvas.Link(makeURI(p, ""), p.Title) + canvas.Image(xpos, y, imageWidth, imageHeight, makeURI(p, "s")) + canvas.LinkEnd() + xpos += (imageWidth + gutter) + } +} + +// fs calls the Flickr API to perform a photo search +func fs(s string) { + var f FlickrResp + r, weberr := http.Get(flickrAPI("flickr.photos.search", "text", s)) + if weberr != nil { + fmt.Fprintf(os.Stderr, "%v\n", weberr) + return + } + defer r.Body.Close() + xmlerr := xml.NewDecoder(r.Body).Decode(&f) + if xmlerr != nil || r.StatusCode != http.StatusOK { + fmt.Fprintf(os.Stderr, "%v (status=%d)\n", xmlerr, r.StatusCode) + return + } + canvas.Title(s) + imageGrid(f, 5, 5, 10, 5, "s") + canvas.Text(20, height-40, s, textStyle) +} + +// for each search term on the commandline, create a photo grid +func main() { + for i := 1; i < len(os.Args); i++ { + canvas.Start(width, height) + canvas.Rect(0, 0, width, height, "fill:black") + fs(url.QueryEscape(os.Args[i])) + canvas.End() + } +} diff --git a/vendor/github.com/ajstarks/svgo/fe/fe.go b/vendor/github.com/ajstarks/svgo/fe/fe.go new file mode 100644 index 0000000..1681192 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/fe/fe.go @@ -0,0 +1,53 @@ +// fe: SVG Filter Effect example from http://www.w3.org/TR/SVG/filters.html#AnExample +// +build !appengine + +package main + + +import ( + "github.com/ajstarks/svgo" + "os" +) + +func main() { + + canvas := svg.New(os.Stdout) + width := 410 + height := 120 + + canvas.Start(width, height) + canvas.Title(`SVGo Filter Example`) + canvas.Desc(`Combines multiple filter primitives to produce a 3D lighting effect`) + + gfs := svg.Filterspec{In: "SourceAlpha", Result: "blur"} + ofs := svg.Filterspec{In: "blur", Result: "offsetBlur"} + sfs := svg.Filterspec{In: "blur", Result: "specOut"} + cfs1 := svg.Filterspec{In: "specOut", In2: "SourceAlpha", Result: "specOut"} + cfs2 := svg.Filterspec{In: "SourceGraphic", In2: "specOut", Result: "litPaint"} + + // define the filters + canvas.Def() + canvas.Filter("myFilter") + canvas.FeGaussianBlur(gfs, 4, 4) + canvas.FeOffset(ofs, 4, 4) + canvas.FeSpecularLighting(sfs, 5, .75, 20, "#bbbbbb") + canvas.FePointLight(-5000, -10000, 20000) + canvas.FeSpecEnd() + canvas.FeComposite(cfs1, "in", 0, 0, 0, 0) + canvas.FeComposite(cfs2, "arithmetic", 0, 1, 1, 0) + canvas.FeMerge([]string{ofs.Result, cfs2.Result}) + canvas.Fend() + canvas.DefEnd() + + // specify the graphic + canvas.Gid("SVG") + canvas.Path("M50,90 C0,90 0,30 50,30 L150,30 C200,30 200,90 150,90 z", "fill:none;stroke:#D90000;stroke-width:10") + canvas.Path("M60,80 C30,80 30,40 60,40 L140,40 C170,40 170,80 140,80 z", "fill:#D90000") + canvas.Text(52, 76, "SVG", "fill:white;stroke:black;font-size:45;font-family:Verdana") + canvas.Gend() + + canvas.Rect(0, 0, width, height, "stroke:black;fill:white") + canvas.Use(0, 0, "#SVG") // plain graphic + canvas.Use(200, 0, "#SVG", `filter="url(#myFilter)"`) // filter applied + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/flower/flower.go b/vendor/github.com/ajstarks/svgo/flower/flower.go new file mode 100644 index 0000000..515ddb2 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/flower/flower.go @@ -0,0 +1,79 @@ +// flower - draw random flowers, inspired by Evelyn Eastmond's DesignBlocks gererated "grain2" +// +build !appengine + +package main + +import ( + "flag" + "fmt" + "math" + "math/rand" + "os" + "time" + + "github.com/ajstarks/svgo" +) + +var ( + canvas = svg.New(os.Stdout) + niter = flag.Int("n", 200, "number of iterations") + width = flag.Int("w", 500, "width") + height = flag.Int("h", 500, "height") + thickness = flag.Int("t", 10, "max petal thinkness") + np = flag.Int("p", 15, "max number of petals") + psize = flag.Int("s", 30, "max length of petals") + opacity = flag.Int("o", 50, "max opacity (10-100)") +) + +const flowerfmt = `stroke:rgb(%d,%d,%d); stroke-opacity:%.2f; stroke-width:%d` + +func radial(xp int, yp int, n int, l int, style ...string) { + var x, y, r, t, limit float64 + limit = 2.0 * math.Pi + r = float64(l) + canvas.Gstyle(style[0]) + for t = 0.0; t < limit; t += limit / float64(n) { + x = r * math.Cos(t) + y = r * math.Sin(t) + canvas.Line(xp, yp, xp+int(x), yp+int(y)) + } + canvas.Gend() +} + +func random(howsmall, howbig int) int { + if howsmall >= howbig { + return howsmall + } + return rand.Intn(howbig-howsmall) + howsmall +} + +func randrad(w int, h int, n int) { + var x, y, r, g, b, o, s, t, p int + for i := 0; i < n; i++ { + x = rand.Intn(w) + y = rand.Intn(h) + r = rand.Intn(255) + g = rand.Intn(255) + b = rand.Intn(255) + o = random(10, *opacity) + s = random(10, *psize) + t = random(2, *thickness) + p = random(10, *np) + radial(x, y, p, s, fmt.Sprintf(flowerfmt, r, g, b, float64(o)/100.0, t)) + } +} + +func background(v int) { canvas.Rect(0, 0, *width, *height, canvas.RGB(v, v, v)) } + +func init() { + flag.Parse() + rand.Seed(int64(time.Now().Nanosecond()) % 1e9) +} + +func main() { + canvas.Start(*width, *height) + canvas.Title("Random Flowers") + background(255) + randrad(*width, *height, *niter) + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/fontcompare/fontcompare.go b/vendor/github.com/ajstarks/svgo/fontcompare/fontcompare.go new file mode 100644 index 0000000..120aac1 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/fontcompare/fontcompare.go @@ -0,0 +1,52 @@ +// fontcompare: compare two fonts +// +build !appengine + +package main + +import ( + "fmt" + "os" + + "github.com/ajstarks/svgo" +) + +var ( + canvas = svg.New(os.Stdout) + width = 1000 + height = 600 + chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789(){}[],.:;-+*/\\&_^%$#@!~`'\"<>" + gstyle = "font-family:%s;font-size:%dpt;text-anchor:middle;fill:%s;fill-opacity:%.2f" +) + +func letters(top, left int, font, color string, opacity float32) { + rows := 7 + cols := 13 + glyph := 0 + fontsize := 32 + spacing := fontsize * 2 + x := left + y := top + canvas.Gstyle(fmt.Sprintf(gstyle, font, fontsize, color, opacity)) + for r := 0; r < rows; r++ { + for c := 0; c < cols; c++ { + canvas.Text(x, y, chars[glyph:glyph+1]) + glyph++ + x += spacing + } + x = left + y += spacing + } + canvas.Gend() +} + +func main() { + if len(os.Args) > 2 { + canvas.Start(width, height) + canvas.Rect(0, 0, width, height, "fill:white") + canvas.Text(80, 540, os.Args[1], "font-size:14pt; fill:blue; font-family:"+os.Args[1]) + canvas.Text(80, 560, os.Args[2], "font-size:14pt; fill:red; font-family:"+os.Args[2]) + letters(100, 100, os.Args[1], "blue", 0.5) + letters(100, 100, os.Args[2], "red", 0.5) + canvas.End() + } +} diff --git a/vendor/github.com/ajstarks/svgo/funnel/funnel.go b/vendor/github.com/ajstarks/svgo/funnel/funnel.go new file mode 100644 index 0000000..901a6bd --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/funnel/funnel.go @@ -0,0 +1,29 @@ +// funnel draws a funnel-like shape +// +build !appengine + +package main + +import ( + "os" + + "github.com/ajstarks/svgo" +) + +var canvas = svg.New(os.Stdout) +var width = 320 +var height = 480 + +func funnel(bg int, fg int, grid int, dim int) { + h := dim / 2 + canvas.Rect(0, 0, width, height, canvas.RGB(bg, bg, bg)) + for size := grid; size < width; size += grid { + canvas.Ellipse(h, size, size/2, size/2, canvas.RGBA(fg, fg, fg, 0.2)) + } +} + +func main() { + canvas.Start(width, height) + canvas.Title("Funnel") + funnel(0, 255, 25, width) + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/gradient/gradient.go b/vendor/github.com/ajstarks/svgo/gradient/gradient.go new file mode 100644 index 0000000..534321e --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/gradient/gradient.go @@ -0,0 +1,58 @@ +// gradient shows sample gradient fills +// +build !appengine + +package main + +import ( + "os" + "strconv" + + "github.com/ajstarks/svgo" +) + +func main() { + width := 500 + height := 500 + + lg := []svg.Offcolor{ + {0, "rgb(255,255,0)", 1.0}, + {100, "rgb(255,0,0)", .5}, + {0, "rgb(200,200,200)", 0.0}, + {100, "rgb(0,0,255)", 1.0}} + + rainbow := []svg.Offcolor{ + {10, "#00cc00", 1}, + {30, "#006600", 1}, + {70, "#cc0000", 1}, + {90, "#000099", 1}} + + rg := []svg.Offcolor{ + {1, "powderblue", 1}, + {10, "lightskyblue", 1}, + {100, "darkblue", 1}} + + g := svg.New(os.Stdout) + g.Start(width, height) + g.Title("Gradients") + g.Rect(0, 0, width, height, "fill:white") + g.Def() + g.LinearGradient("h", 0, 100, 0, 0, lg) + g.LinearGradient("v", 0, 0, 100, 0, lg) + g.LinearGradient("rainbow", 0, 0, 100, 0, rainbow) + g.RadialGradient("rad100", 50, 50, 100, 25, 25, rg) + g.RadialGradient("rad50", 50, 50, 50, 20, 50, rg) + for i := 50; i < 100; i += 10 { + g.RadialGradient("grad"+strconv.Itoa(i), 50, 50, uint8(i), 20, 50, rg) + } + g.DefEnd() + + g.Ellipse(width/2, height/2, 100, 100, "fill:url(#rad100)") + g.Rect(300, 200, 100, 100, "fill:url(#h)") + g.Rect(100, 200, 100, 100, "fill:url(#v)") + g.Roundrect(10, 10, width-20, 50, 10, 10, "fill:url(#rainbow)") + + for i := 50; i < 100; i += 10 { + g.Circle(i*5, 100, 15, "fill:url(#grad"+strconv.Itoa(i)+")") + } + g.End() +} diff --git a/vendor/github.com/ajstarks/svgo/html5logo/html5logo.go b/vendor/github.com/ajstarks/svgo/html5logo/html5logo.go new file mode 100644 index 0000000..f532528 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/html5logo/html5logo.go @@ -0,0 +1,41 @@ +// html5logo draws the w3c HTML5 logo, with scripting added +// +build !appengine + +package main + +import ( + "github.com/ajstarks/svgo" + "os" +) + +func main() { + // HTML5 logo data from + // "Understanding and Optimizing Web Graphics", Session 508, + // Dean Jackson, Apple WWDC 2011 + // + // Draggable elements via Jeff Schiller's dragsvg Javascript library + + // shield + var sx = []int{71, 30, 481, 440, 255} + var sy = []int{460, 0, 0, 460, 512} + // highlight + var hx = []int{256, 405, 440, 256} + var hy = []int{472, 431, 37, 37} + // "five" + var fx = []int{181, 176, 392, 393, 396, 397, 114, 115, 129, 325, 318, 256, 192, 188, 132, 139, 256, 371, 372, 385, 387, 371} + var fy = []int{208, 150, 150, 138, 109, 94, 94, 109, 265, 265, 338, 355, 338, 293, 293, 382, 414, 382, 372, 223, 208, 208} + + canvas := svg.New(os.Stdout) + width := 512 + height := 512 + + // begin the document with the onload event, and namespace for dragging + canvas.Start(width, height, `onload="initializeDraggableElements();"`, `xmlns:drag="http://www.codedread.com/dragsvg"`) + canvas.Title("HTML5 Logo") + canvas.Rect(0, 0, width, height) // black background + canvas.Script("application/javascript", "http://www.codedread.com/dragsvg.js") // reference the drag script + canvas.Polygon(sx, sy, `drag:enable="true"`, canvas.RGB(227, 79, 38)) // draggable shield + canvas.Polygon(hx, hy, `drag:enable="true"`, canvas.RGBA(255, 255, 255, 0.3)) // draggable highlight + canvas.Polygon(fx, fy, `drag:enable="true"`, canvas.RGB(219, 219, 219)) // draggable five + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/imfade/imfade.go b/vendor/github.com/ajstarks/svgo/imfade/imfade.go new file mode 100644 index 0000000..c00b82f --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/imfade/imfade.go @@ -0,0 +1,32 @@ +// imfade progressively fades the Go gopher image +// +build !appengine + +package main + +import ( + "fmt" + "os" + + "github.com/ajstarks/svgo" +) + +var canvas = svg.New(os.Stdout) + +func main() { + width := 768 + height := 128 + image := "gophercolor128x128.png" + if len(os.Args) > 1 { + image = os.Args[1] + } + canvas.Start(width, height) + canvas.Title("Image Fade") + opacity := 1.0 + for i := 0; i < width-128; i += 100 { + canvas.Image(i, 0, 128, 128, image, fmt.Sprintf("opacity:%.2f", opacity)) + opacity -= 0.10 + } + canvas.Grid(0, 0, width, height, 16, "stroke:gray; opacity:0.2") + + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/lewitt/lewitt.go b/vendor/github.com/ajstarks/svgo/lewitt/lewitt.go new file mode 100644 index 0000000..fea90da --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/lewitt/lewitt.go @@ -0,0 +1,84 @@ +// lewitt: inspired by by Sol LeWitt's Wall Drawing 91: +// +build !appengine + +package main + +// +// A six-inch (15 cm) grid covering the wall. +// Within each square, not straight lines from side to side, using +// red, yellow and blue pencils. Each square contains at least +// one line of each color. +// +// This version violates the original instructions in that straight lines +// as well as arcs are used + +import ( + "flag" + "fmt" + "math/rand" + "os" + "time" + + "github.com/ajstarks/svgo" +) + +var canvas = svg.New(os.Stdout) + +const tilestyle = `stroke-width:1; stroke:rgb(128,128,128); stroke-opacity:0.5; fill:white` +const penstyle = `stroke:rgb%s; fill:none; stroke-opacity:%.2f; stroke-width:%d` + +var width = 720 +var height = 720 + +var nlines = flag.Int("n", 20, "number of lines/square") +var nw = flag.Int("w", 3, "maximum pencil width") +var pencils = []string{"(250, 13, 44)", "(247, 212, 70)", "(52, 114, 245)"} + +func background(v int) { canvas.Rect(0, 0, width, height, canvas.RGB(v, v, v)) } + +func lewitt(x int, y int, gsize int, n int, w int) { + var x1, x2, y1, y2 int + var op float64 + canvas.Rect(x, y, gsize, gsize, tilestyle) + for i := 0; i < n; i++ { + choice := rand.Intn(len(pencils)) + op = float64(random(1, 10)) / 10.0 + x1 = random(x, x+gsize) + y1 = random(y, y+gsize) + x2 = random(x, x+gsize) + y2 = random(y, y+gsize) + if random(0, 100) > 50 { + canvas.Line(x1, y1, x2, y2, fmt.Sprintf(penstyle, pencils[choice], op, random(1, w))) + } else { + canvas.Arc(x1, y1, gsize, gsize, 0, false, true, x2, y2, fmt.Sprintf(penstyle, pencils[choice], op, random(1, w))) + } + } +} + +func random(howsmall, howbig int) int { + if howsmall >= howbig { + return howsmall + } + return rand.Intn(howbig-howsmall) + howsmall +} + +func init() { + flag.Parse() + rand.Seed(int64(time.Now().Nanosecond()) % 1e9) +} + +func main() { + + canvas.Start(width, height) + canvas.Title("Sol Lewitt's Wall Drawing 91") + background(255) + gsize := 120 + nc := width / gsize + nr := height / gsize + for cols := 0; cols < nc; cols++ { + for rows := 0; rows < nr; rows++ { + lewitt(cols*gsize, rows*gsize, gsize, *nlines, *nw) + } + } + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/ltr/ltr.go b/vendor/github.com/ajstarks/svgo/ltr/ltr.go new file mode 100644 index 0000000..d58a9e1 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/ltr/ltr.go @@ -0,0 +1,178 @@ +// ltr: Layer Tennis remixes + +package main + +import ( + "flag" + "fmt" + "os" + + "github.com/ajstarks/svgo" +) + +var ( + canvas = svg.New(os.Stdout) + poster, opacity, row, col, offset bool + title string + width, height int +) + +const ( + stdwidth = 900 + stdheight = 280 + ni = 11 +) + +// imagefiles returns a list of files in the specifed directory +// or nil on error. Each file includes the prepended directory name +func imagefiles(directory string) []string { + f, ferr := os.Open(directory) + if ferr != nil { + return nil + } + defer f.Close() + files, derr := f.Readdir(-1) + if derr != nil || len(files) == 0 { + return nil + } + names := make([]string, len(files)) + for i, v := range files { + names[i] = directory + "/" + v.Name() + } + return names +} + +// ltposter creates poster style: a title, followed by a list +// of volleys +func ltposter(x, y, w, h int, f []string) { + canvas.Image(x, y, w*2, h*2, f[0]) // first file, assumed to be the banner + y = y + (h * 2) + for i := 1; i < len(f); i += 2 { + canvas.Image(x, y, w, h, f[i]) + canvas.Image(x+w, y, w, h, f[i+1]) + if i%2 == 1 { + y += h + } + } +} + +// ltcol creates a single column of volley images +func ltcol(x, y, w, h int, f []string) { + for i := 0; i < len(f); i++ { + canvas.Image(x, y, w, h, f[i]) + y += h + } +} + +// ltop creates a view with each volley stacked together with +// semi-transparent opacity +func ltop(x, y, w, h int, f []string) { + for i := 1; i < len(f); i++ { // skip the first file, assumed to be the banner + canvas.Image(x, y, w, h, f[i], "opacity:0.2") + } +} + +// ltrow creates a row-wise view of volley images. +func ltrow(x, y, w, h int, f []string) { + for i := 0; i < len(f); i++ { + canvas.Image(x, y, w, h, f[i]) + x += w + } +} + +// ltoffset creates a view where each volley is offset from its opposing volley. +func ltoffset(x, y, w, h int, f []string) { + for i := 1; i < len(f); i++ { // skip the first file, assumed to be the banner + + if i%2 == 0 { + x += w + } else { + x = 0 + } + canvas.Image(x, y, w, h, f[i]) + y += h + } +} + +// dotitle creates the title +func dotitle(s string) { + if len(title) > 0 { + canvas.Title(title) + } else { + canvas.Title(s) + } +} + +// init sets up the command line flags. +func init() { + flag.BoolVar(&poster, "poster", false, "poster style") + flag.BoolVar(&opacity, "opacity", false, "opacity style") + flag.BoolVar(&row, "row", false, "display is a single row") + flag.BoolVar(&col, "col", false, "display in a single column") + flag.BoolVar(&offset, "offset", false, "display in a row, even layers offset") + flag.IntVar(&width, "width", stdwidth, "image width") + flag.IntVar(&height, "height", stdheight, "image height") + flag.StringVar(&title, "title", "", "title") + flag.Parse() +} + +func main() { + x := 0 + y := 0 + nd := len(flag.Args()) + for i, dir := range flag.Args() { + filelist := imagefiles(dir) + if len(filelist) != ni || filelist == nil { + fmt.Fprintf(os.Stderr, "in the %s directory, need %d images, read %d\n", dir, ni, len(filelist)) + continue + } + switch { + + case opacity: + if i == 0 { + canvas.Start(width*nd, height*nd) + dotitle(dir) + } + ltop(x, y, width, height, filelist) + y += height + + case poster: + if i == 0 { + canvas.Start(width, ((height*(ni-1)/4)+height)*nd) + dotitle(dir) + } + ltposter(x, y, width/2, height/2, filelist) + y += (height * 3) + (height / 2) + + case col: + if i == 0 { + canvas.Start(width*nd, height*ni) + dotitle(dir) + } + ltcol(x, y, width, height, filelist) + x += width + + case row: + if i == 0 { + canvas.Start(width*ni, height*nd) + dotitle(dir) + } + ltrow(x, y, width, height, filelist) + y += height + + case offset: + n := ni - 1 + pw := width * 2 + ph := nd * (height * (n)) + if i == 0 { + canvas.Start(pw, ph) + canvas.Rect(0, 0, pw, ph, "fill:white") + dotitle(dir) + } + ltoffset(x, y, width, height, filelist) + y += n * height + + } + } + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/marker/marker.go b/vendor/github.com/ajstarks/svgo/marker/marker.go new file mode 100644 index 0000000..bb7b642 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/marker/marker.go @@ -0,0 +1,39 @@ +// marker test +// +build !appengine + +package main + +import ( + "github.com/ajstarks/svgo" + "os" +) + +func main() { + canvas := svg.New(os.Stdout) + canvas.Start(500, 500) + canvas.Title("Marker") + + canvas.Def() + canvas.Marker("dot", 5, 5, 8, 8) + canvas.Circle(5, 5, 3, "fill:black") + canvas.MarkerEnd() + + canvas.Marker("box", 5, 5, 8, 8) + canvas.CenterRect(5, 5, 6, 6, "fill:green") + canvas.MarkerEnd() + + canvas.Marker("arrow", 2, 6, 13, 13) + canvas.Path("M2,2 L2,11 L10,6 L2,2", "fill:blue") + canvas.MarkerEnd() + canvas.DefEnd() + + x := []int{100, 250, 100} + y := []int{100, 250, 400} + canvas.Polyline(x, y, + `fill="none"`, + `stroke="red"`, + `marker-start="url(#dot)"`, + `marker-mid="url(#arrow)"`, + `marker-end="url(#box)"`) + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/newsvg b/vendor/github.com/ajstarks/svgo/newsvg new file mode 100644 index 0000000..46c7099 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/newsvg @@ -0,0 +1,39 @@ +#!/bin/sh + +if test $# -lt 1 +then + echo "specify a file" + exit 2 +fi + +if test ! -f $1 +then +cat < $1 +package main + +import ( + "github.com/ajstarks/svgo" + "os" +) + +var ( + width = 500 + height = 500 + canvas = svg.New(os.Stdout) +) + +func background(v int) { canvas.Rect(0, 0, width, height, canvas.RGB(v, v, v)) } + + +func main() { + canvas.Start(width, height) + background(255) + + // your code here + + canvas.Grid(0, 0, width, height, 10, "stroke:black;opacity:0.1") + canvas.End() +} +! +fi +$EDITOR $1 diff --git a/vendor/github.com/ajstarks/svgo/paths/paths.go b/vendor/github.com/ajstarks/svgo/paths/paths.go new file mode 100644 index 0000000..5a9283a --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/paths/paths.go @@ -0,0 +1,31 @@ +// paths draws the W3C logo as a paths +// +build !appengine + +package main + +import ( + "fmt" + "os" + + "github.com/ajstarks/svgo" +) + +var canvas = svg.New(os.Stdout) + +func w3c() { + w3path := `M36,5l12,41l12-41h33v4l-13,21c30,10,2,69-21,28l7-2c15,27,33,-22,3,-19v-4l12-20h-15l-17,59h-1l-13-42l-12,42h-1l-20-67h9l12,41l8-28l-4-13h9` + cpath := `M94,53c15,32,30,14,35,7l-1-7c-16,26-32,3-34,0M122,16c-10-21-34,0-21,30c-5-30 16,-38 23,-21l5-10l-2-9` + canvas.Path(w3path, "fill:#005A9C") + canvas.Path(cpath) +} + +func main() { + canvas.Startview(700, 200, 0, 0, 700, 200) + canvas.Title("Paths") + for i := 0; i < 5; i++ { + canvas.Gtransform(fmt.Sprintf("translate(%d,0)", i*130)) + w3c() + canvas.Gend() + } + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/pattern/pattern.go b/vendor/github.com/ajstarks/svgo/pattern/pattern.go new file mode 100644 index 0000000..0545683 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/pattern/pattern.go @@ -0,0 +1,33 @@ +// pattern: test the pattern function +package main + +import ( + "fmt" + "github.com/ajstarks/svgo" + "os" +) + +func main() { + canvas := svg.New(os.Stdout) + w, h := 500, 500 + pct := 5 + pw, ph := (w*pct)/100, (h*pct)/100 + canvas.Start(w, h) + + // define the pattern + canvas.Def() + canvas.Pattern("hatch", 0, 0, pw, ph, "user") + canvas.Gstyle("fill:none;stroke-width:1") + canvas.Path(fmt.Sprintf("M0,0 l%d,%d", pw, ph), "stroke:red") + canvas.Path(fmt.Sprintf("M%d,0 l-%d,%d", pw, pw, ph), "stroke:blue") + canvas.Gend() + canvas.PatternEnd() + canvas.DefEnd() + + // use the pattern + canvas.Gstyle("stroke:black; stroke-width:2") + canvas.Circle(w/2, h/2, h/8, "fill:url(#hatch)") + canvas.CenterRect((w*4)/5, h/2, h/4, h/4, "fill:url(#hatch)") + canvas.Gend() + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/picserv/index.go b/vendor/github.com/ajstarks/svgo/picserv/index.go new file mode 100644 index 0000000..9feb426 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/picserv/index.go @@ -0,0 +1,127 @@ +package main +const ( +index = ` + + pic256 + + + +

Pic256

+

Programmed pictures in a 256x256 square

+

Defaults

+ +
rotext
+
flower
+
cube
+
funnel
+
rshape
+
lewitt
+
mondrian
+
face
+
clock
+
pacman
+
tux
+
ubuntu
+ +

Variations

+ +

rotext

+

+

char=a
+
char=b&ti=40
+
char=c&ti=60
+
char=d&ti=90&font=Courier
+

+ +

flower

+

+

petals=10&n=100
+
petals=15&n=50
+
petals=30&n=20
+
petals=30&n=10
+

+ +

cube

+

+

y=80&row=1
+
y=50&row=2
+
&row=3
+
y=0&row=4
+

+ +

funnel

+

+

step=10
+
step=15
+
step=25
+
step=25&bg=white&fg=black
+

+ +

rshape

+

+

shape=c
+
shape=r
+
same=f
+
shape=r&same=t
+

+ +

lewitt

+

+

pen=1&lines=20
+
pen=2&lines=30
+
pen=3&lines=40
+
pen=5&?lines=100
+

+ + +

mondrian

+

+

random=true
+
random=t
+
random=1
+
random=f
+

+ +

face

+

+

mood=happy&glance=u
+
mood=neutral&glance=d
+
mood=sad&glance=l
+
mood=happy&glance=r
+

+ +

clock

+

+

clock
+
hour=23
+
hour=12&min=34
+
hour=6&min=30&sec=0
+

+ +

pacman

+

+

pacman
+
angle=10
+
angle=40
+
angle=60
+

+ + + +`) diff --git a/vendor/github.com/ajstarks/svgo/picserv/pic256.html b/vendor/github.com/ajstarks/svgo/picserv/pic256.html new file mode 100644 index 0000000..6873184 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/picserv/pic256.html @@ -0,0 +1,124 @@ + + + pic256 + + + +

Pic256

+

Programmed pictures in a 256x256 square

+

Defaults

+ +
rotext
+
flower
+
cube
+
funnel
+
rshape
+
lewitt
+
mondrian
+
face
+
clock
+
pacman
+
tux
+
ubuntu
+ +

Variations

+ +

rotext

+

+

char=a
+
char=b&ti=40
+
char=c&ti=60
+
char=d&ti=90&font=Courier
+

+ +

flower

+

+

petals=10&n=100
+
petals=15&n=50
+
petals=30&n=20
+
petals=30&n=10
+

+ +

cube

+

+

y=80&row=1
+
y=50&row=2
+
&row=3
+
y=0&row=4
+

+ +

funnel

+

+

step=10
+
step=15
+
step=25
+
step=25&bg=white&fg=black
+

+ +

rshape

+

+

shape=c
+
shape=r
+
same=f
+
shape=r&same=t
+

+ +

lewitt

+

+

pen=1&lines=20
+
pen=2&lines=30
+
pen=3&lines=40
+
pen=5&?lines=100
+

+ + +

mondrian

+

+

random=true
+
random=t
+
random=1
+
random=f
+

+ +

face

+

+

mood=happy&glance=u
+
mood=neutral&glance=d
+
mood=sad&glance=l
+
mood=happy&glance=r
+

+ +

clock

+

+

clock
+
hour=23
+
hour=12&min=34
+
hour=6&min=30&sec=0
+

+ +

pacman

+

+

pacman
+
angle=10
+
angle=40
+
angle=60
+

+ + + diff --git a/vendor/github.com/ajstarks/svgo/picserv/picserv.go b/vendor/github.com/ajstarks/svgo/picserv/picserv.go new file mode 100644 index 0000000..48970cd --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/picserv/picserv.go @@ -0,0 +1,672 @@ +// picserv: serve pictures +package main + +import ( + "flag" + "fmt" + "io" + "log" + "math" + "math/rand" + "net/http" + "net/url" + "strconv" + "time" + + "github.com/ajstarks/svgo" +) + +var listen = flag.String("listen", ":1958", "http service address") + +const ( + arcstyle = "stroke:red;stroke-linecap:round;fill:none;stroke-width:10" + rotextfmt = "fill:%s;font-family:%s;font-size:%dpt" + flowerfmt = "stroke:rgb(%d,%d,%d); stroke-opacity:%.2f; stroke-width:%d" + tilestyle = "stroke-width:1; stroke:rgb(128,128,128); stroke-opacity:0.5; fill:white" + penstyle = "stroke:rgb%s; fill:none; stroke-opacity:%.2f; stroke-width:%d" + width = 256 + height = 256 +) + +// include index +//go:generate ih -v index -o index.go pic256.html + +// init seeds the RNG +func init() { + rand.Seed(time.Now().Unix() % 1e9) +} + +// serve stuff +func main() { + flag.Parse() + http.Handle("/", http.HandlerFunc(picindex)) + http.Handle("/index/", http.HandlerFunc(picindex)) + http.Handle("/pic256.html", http.HandlerFunc(picindex)) + http.Handle("/rotext/", http.HandlerFunc(rotext)) + http.Handle("/rshape/", http.HandlerFunc(rshape)) + http.Handle("/face/", http.HandlerFunc(face)) + http.Handle("/flower/", http.HandlerFunc(flower)) + http.Handle("/cube/", http.HandlerFunc(cube)) + http.Handle("/lewitt/", http.HandlerFunc(lewitt)) + http.Handle("/mondrian/", http.HandlerFunc(mondrian)) + http.Handle("/funnel/", http.HandlerFunc(funnel)) + http.Handle("/clock/", http.HandlerFunc(clock)) + http.Handle("/pacman/", http.HandlerFunc(pacman)) + http.Handle("/ubuntu/", http.HandlerFunc(ubuntu)) + http.Handle("/tux/", http.HandlerFunc(tux)) + log.Printf("listen on %s", *listen) + err := http.ListenAndServe(*listen, nil) + if err != nil { + log.Fatal("ListenAndServe:", err) + } +} + +// qstring returns the string value of the query string +func qstring(q url.Values, key, defval string, length int) string { + var retval string + p, ok := q[key] + if ok { + retval = p[0] + } else { + return defval + } + if len(retval) > length { + return retval[:length] + } + return retval +} + +// qfloat returns the float64 value of a query string, within limits +func qfloat(q url.Values, key string, defval float64, min, max float64) float64 { + var retval float64 + var err error + p, ok := q[key] + if ok { + retval, err = strconv.ParseFloat(p[0], 64) + if err != nil { + return defval + } + } else { + return defval + } + if retval < min || retval > max { + return defval + } + return retval +} + +// qfint returns the integer value of a query string, within limits +func qint(q url.Values, key string, defval int, min, max int) int { + var retval int + var err error + p, ok := q[key] + if ok { + retval, err = strconv.Atoi(p[0]) + if err != nil { + return defval + } + } else { + return defval + } + if retval < min || retval > max { + return defval + } + return retval +} + +// qbool returns the boolean value of a query string +func qbool(q url.Values, key string, defval bool) bool { + p, ok := q[key] + if ok { + switch p[0] { + case "t", "true", "T", "1", "on": + return true + case "f", "false", "F", "0", "off": + return false + default: + return defval + } + } else { + return defval + } +} + +func random(howsmall, howbig int) int { + if howsmall >= howbig { + return howsmall + } + return rand.Intn(howbig-howsmall) + howsmall +} + +func randcolor() string { + return fmt.Sprintf("fill:rgb(%d,%d,%d)", rand.Intn(255), rand.Intn(255), rand.Intn(255)) +} + +// picindex shows an HTML document that describes the service +// The "index" variable is a string that holds the document, +// made with go generate +func picindex(w http.ResponseWriter, req *http.Request) { + log.Printf("index: %s %s %s", req.RemoteAddr, req.URL.Path, req.UserAgent()) + io.WriteString(w, index) +} + +// rotext makes rotated and faded text +func rotext(w http.ResponseWriter, req *http.Request) { + + log.Printf("rotext: %s", req.RemoteAddr) + query := req.URL.Query() + + rchar := qstring(query, "char", "a", 3) // the string + ti := qfloat(query, "ti", 10, 5, 360) // angle interval + bg := qstring(query, "bg", "black", 20) // background color + fg := qstring(query, "fg", "white", 20) // text color + font := qstring(query, "font", "serif", 50) // font name + a, ai := 1.0, 0.03 + + w.Header().Set("Content-type", "image/svg+xml") + canvas := svg.New(w) + canvas.Start(width, height) + canvas.Title("Rotated Text") + canvas.Rect(0, 0, width, height, "fill:"+bg) + canvas.Gstyle(fmt.Sprintf(rotextfmt, fg, font, width/(len(rchar)+1))) + for t := 0.0; t <= 360.0; t += ti { + canvas.TranslateRotate(width/2, height/2, t) + canvas.Text(0, 0, rchar, fmt.Sprintf("fill-opacity:%.2f", a)) + canvas.Gend() + a -= ai + } + canvas.Gend() + canvas.End() +} + +// face draws a face, with mood (happy, sad, neutral), +// and glance (up, down, left, right, middle) +func face(w http.ResponseWriter, req *http.Request) { + + log.Printf("face: %s", req.RemoteAddr) + query := req.URL.Query() + + mood := qstring(query, "mood", "h", 10) + glance := qstring(query, "glance", "m", 10) + ex1 := width / 4 // left eye x 25% from the left + ex2 := (width * 3) / 4 // right eye x 25% from the right + ey := height / 3 // eye y one third from the bottom + sy := (height * 2) / 3 // mouth y two-thirds from the bottom + er := width / 12 // eye radius + ax := height / 3 // mouth arc x + ay := height / 3 // mounth arc y + aflag := false + pupilsize := er / 3 + xoffset := 0 + yoffset := 0 + + // adjust mouth according to mood + switch mood { + case "n", "neutral": + ay = 0 + case "s", "sad": + sy = (height * 4) / 5 + aflag = true + } + + // adjust pupils according to glance + switch glance { + case "l", "left": + xoffset = -pupilsize + case "r", "right": + xoffset = pupilsize + case "d", "down": + yoffset = pupilsize + case "u", "up": + yoffset = -pupilsize + } + + w.Header().Set("Content-type", "image/svg+xml") + canvas := svg.New(w) + canvas.Start(width, height) + canvas.Title("Face") + canvas.Rect(0, 0, width, height, "fill:white") // background + canvas.Circle(ex1, ey, er) // lefteye + canvas.Circle(ex2, ey, er) // righteye + canvas.Circle(ex1+xoffset, ey+yoffset, pupilsize, "fill:white") // left pupil + canvas.Circle(ex2+xoffset, ey+yoffset, pupilsize, "fill:white") // right pupil + canvas.Arc(ex1, sy, ax, ay, 0, false, aflag, ex2, sy, arcstyle) // mouth + canvas.End() +} + +// rshape draws random shapes +func rshape(w http.ResponseWriter, req *http.Request) { + + log.Printf("rshape: %s", req.RemoteAddr) + query := req.URL.Query() + + n := qint(query, "n", 150, 5, 200) // number of shapes + shape := qstring(query, "shape", "c", 10) // type of shape + bg := qstring(query, "bg", "white", 20) // background color + samesize := qbool(query, "same", false) // regular or oblong + canvas := svg.New(w) + + // draw rect, square, ellipse or circle according to the specified shape + shapefunc := canvas.Ellipse + switch shape { + case "r", "box": + shapefunc = canvas.Rect + samesize = false + case "s", "sq", "square": + shapefunc = canvas.Rect + samesize = true + case "e", "ellipse": + shapefunc = canvas.Ellipse + samesize = false + case "c", "circle", "dot": + shapefunc = canvas.Ellipse + samesize = true + } + + w.Header().Set("Content-type", "image/svg+xml") + var s1, s2 int + canvas.Start(width, height) + canvas.Title("Random Shapes") + canvas.Rect(0, 0, width, height, "fill:"+bg) + for i := 0; i < n; i++ { + s1 = rand.Intn(width / 5) + if samesize { + s2 = s1 + } else { + s2 = rand.Intn(height / 5) + } + shapefunc(rand.Intn(width), rand.Intn(height), s1, s2, + fmt.Sprintf("fill-opacity:%.2f;fill:rgb(%d,%d,%d)", + rand.Float64(), rand.Intn(256), rand.Intn(256), rand.Intn(256))) + } + canvas.End() +} + +func flower(w http.ResponseWriter, req *http.Request) { + + log.Printf("flower: %s", req.RemoteAddr) + query := req.URL.Query() + + n := qint(query, "n", 200, 10, 200) // number of "flowers" + np := qint(query, "petals", 15, 10, 60) // number of "petals" per flower + opacity := qint(query, "op", 50, 20, 100) // opacity + psize := qint(query, "size", 30, 5, 50) // length of the petals + thickness := qint(query, "thick", 10, 3, 20) // petal thickness + + limit := 2.0 * math.Pi + + w.Header().Set("Content-type", "image/svg+xml") + canvas := svg.New(w) + canvas.Start(width, height) + canvas.Title("Flowers") + canvas.Rect(0, 0, width, height, "fill:white") + + for i := 0; i < n; i++ { + x := rand.Intn(width) + y := rand.Intn(height) + r := float64(random(10, psize)) + + canvas.Gstyle(fmt.Sprintf(flowerfmt, rand.Intn(255), rand.Intn(255), rand.Intn(255), + float64(random(10, opacity))/100.0, random(2, thickness))) + for theta := 0.0; theta < limit; theta += limit / float64(random(10, np)) { + xr := r * math.Cos(theta) + yr := r * math.Sin(theta) + canvas.Line(x, y, x+int(xr), y+int(yr)) + } + canvas.Gend() + } + canvas.End() +} + +// rcube makes a cube with three visible faces, each with a random color +func rcube(canvas *svg.SVG, x, y, l int) { + + // top face + tx := []int{x, x + (l * 3), x, x - (l * 3), x} + ty := []int{y, y + (l * 2), y + (l * 4), y + (l * 2), y} + + // left face + lx := []int{x - (l * 3), x, x, x - (l * 3), x - (l * 3)} + ly := []int{y + (l * 2), y + (l * 4), y + (l * 8), y + (l * 6), y + (l * 2)} + + // right face + rx := []int{x + (l * 3), x + (l * 3), x, x, x + (l * 3)} + ry := []int{y + (l * 2), y + (l * 6), y + (l * 8), y + (l * 4), y + (l * 2)} + + canvas.Polygon(tx, ty, randcolor()) + canvas.Polygon(lx, ly, randcolor()) + canvas.Polygon(rx, ry, randcolor()) +} + +// cube draws a grid of cubes, n rows deep. +// The grid begins at (xp, yp), with hspace between cubes in a row, and vspace between rows. +func cube(w http.ResponseWriter, req *http.Request) { + + log.Printf("cube: %s", req.RemoteAddr) + query := req.URL.Query() + + bgcolor := qstring(query, "bg", randcolor(), 30) // background color + n := qint(query, "row", 3, 1, 20) // number of rows + hspace := qint(query, "hs", width/5, 0, width) // horizontal space + vspace := qint(query, "vs", height/4, 0, height) // vertical space + size := qint(query, "size", width/30, 2, width/4) // cube size + xp := qint(query, "x", width/10, 0, width/2) // initial x position + yp := qint(query, "y", height/10, 0, height/2) // initial y position + + w.Header().Set("Content-type", "image/svg+xml") + canvas := svg.New(w) + canvas.Start(width, height) + canvas.Title("Cubes") + canvas.Rect(0, 0, width, height, bgcolor) + y := yp + for r := 0; r < n; r++ { + for x := xp; x < width; x += hspace { + rcube(canvas, x, y, size) + } + y += vspace + } + canvas.End() +} + +var pencils = []string{"(250, 13, 44)", "(247, 212, 70)", "(52, 114, 245)"} + +func lew(canvas *svg.SVG, x int, y int, gsize int, n int, w int) { + var x1, x2, y1, y2 int + var op float64 + canvas.Rect(x, y, gsize, gsize, tilestyle) + for i := 0; i < n; i++ { + choice := rand.Intn(len(pencils)) + op = float64(random(1, 10)) / 10.0 + x1 = random(x, x+gsize) + y1 = random(y, y+gsize) + x2 = random(x, x+gsize) + y2 = random(y, y+gsize) + if random(0, 100) > 50 { + canvas.Line(x1, y1, x2, y2, fmt.Sprintf(penstyle, pencils[choice], op, random(1, w))) + } else { + canvas.Arc(x1, y1, gsize, gsize, 0, false, true, x2, y2, fmt.Sprintf(penstyle, pencils[choice], op, random(1, w))) + } + } +} + +// lewitt simulates Sol Lewitt's Wall Drawing 91 +func lewitt(w http.ResponseWriter, req *http.Request) { + query := req.URL.Query() + log.Printf("lewitt: %s", req.RemoteAddr) + + nlines := qint(query, "lines", 20, 5, 100) + nw := qint(query, "pen", 3, 1, 5) + + w.Header().Set("Content-type", "image/svg+xml") + canvas := svg.New(w) + canvas.Start(width, height) + canvas.Title("Sol Lewitt's Wall Drawing 91") + canvas.Rect(0, 0, width, height, "fill:white") + gsize := width / 6 + nc := width / gsize + nr := height / gsize + for cols := 0; cols < nc; cols++ { + for rows := 0; rows < nr; rows++ { + lew(canvas, cols*gsize, rows*gsize, gsize, nlines, nw) + } + } + canvas.End() +} + +// pmcolor returns a random color from Mondrian's set, or a specified standard color +func pmcolor(randcolor bool, standard string) string { + moncolors := []string{"white", "red", "blue", "yellow"} + if randcolor { + return moncolors[rand.Intn(10000)%4] + } + return standard +} + +// mondrian draws a view inspired by Piet Mondrian's Composition red, blue, white and yellow +func mondrian(w http.ResponseWriter, req *http.Request) { + log.Printf("mondrian: %s", req.RemoteAddr) + query := req.URL.Query() + rc := qbool(query, "random", false) + w3 := width / 3 + w6 := w3 / 2 + w23 := w3 * 2 + + w.Header().Set("Content-type", "image/svg+xml") + canvas := svg.New(w) + canvas.Start(width, height) + canvas.Title("Mondrian Composition in red, blue, white and yellow") + canvas.Gstyle("stroke:black;stroke-width:6") + canvas.Rect(0, 0, w3, w3, "fill:"+pmcolor(rc, "white")) + canvas.Rect(0, w3, w3, w3, "fill:"+pmcolor(rc, "white")) + canvas.Rect(0, w23, w3, w3, "fill:"+pmcolor(rc, "blue")) + canvas.Rect(w3, 0, w23, w23, "fill:"+pmcolor(rc, "red")) + canvas.Rect(w3, w23, w23, w3, "fill:"+pmcolor(rc, "white")) + canvas.Rect(width-w6, height-w3, w3-w6, w6, "fill:"+pmcolor(rc, "white")) + canvas.Rect(width-w6, height-w6, w3-w6, w6, "fill:"+pmcolor(rc, "yellow")) + canvas.Gend() + canvas.Rect(0, 0, width, height, "fill:none;stroke:black;stroke-width:12") + canvas.End() +} + +// funnel makes a funnel from fading ellipses +func funnel(w http.ResponseWriter, req *http.Request) { + log.Printf("funnel: %s", req.RemoteAddr) + query := req.URL.Query() + bg := qstring(query, "bg", "black", 20) + fg := qstring(query, "fg", "white", 20) + grid := qint(query, "step", 25, 10, height/3) + h := width / 2 + + w.Header().Set("Content-type", "image/svg+xml") + canvas := svg.New(w) + canvas.Start(width, height) + canvas.Title("Funnel") + canvas.Rect(0, 0, width, height, "fill:"+bg) + canvas.Gstyle("fill-opacity:0.2;fill:" + fg) + for size := grid; size < width; size += grid { + canvas.Ellipse(h, size, size/2, size/2) + } + canvas.Gend() + canvas.End() +} + +var ( + digits = [12]string{"12", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"} + hrangles = [12]float64{90, 60, 30, 0, 330, 300, 270, 240, 210, 180, 150, 120} + minangles = [60]float64{ + 90, 84, 78, 72, 66, 60, 54, 48, 42, 36, 30, 24, 18, 12, 6, + 0, 354, 348, 342, 336, 330, 324, 318, 312, 306, + 300, 294, 288, 282, 276, 270, 264, 258, 252, 246, 240, 234, 228, 222, 216, + 210, 204, 198, 192, 186, 180, 174, 168, 162, 156, + 150, 144, 138, 132, 126, 120, 114, 108, 102, 96, + } +) + +const ( + radians = math.Pi / 180.0 + hrcolor = "rgb(127,0,0)" + secolor = "rgb(0,0,255)" + mincolor = "rgb(127,127,127)" + bgcolor = "rgb(140,140,140)" + linefmt = "stroke:%s;stroke-width:%d" + digitfmt = "font-family:Helvetica,Calibri,sans-serif;text-anchor:middle;font-size:%dpx" +) + +// clock draws an analog clock +func clock(w http.ResponseWriter, req *http.Request) { + log.Printf("clock: %s", req.RemoteAddr) + query := req.URL.Query() + size := width / 3 + basesize := size / 12 + fs := (size * 2) + (size / 2) + + w.Header().Set("Content-type", "image/svg+xml") + canvas := svg.New(w) + canvas.Start(width, height) + + // clock face + cx, cy := width/2, height/2 + now := time.Now() + hour, min, sec := now.Hour(), now.Minute(), now.Second() + + hour = qint(query, "hour", hour, 0, 23) + min = qint(query, "min", min, 0, 59) + sec = qint(query, "sec", sec, 0, 59) + + canvas.Rect(0, 0, width, height, "fill:black") + canvas.Roundrect(cx-(fs/2), cy-(fs/2), fs, fs, basesize, basesize, "fill:"+bgcolor) + canvas.Circle(cx, cy, size+(size/6), "fill:white") + canvas.Gstyle(fmt.Sprintf(digitfmt, basesize*2)) + + // draw the clock-face digits + r := float64(size) + rx := float64(cx) + ry := float64(cy) + for h := 12; h > 0; h-- { + t := hrangles[h%12] * radians + x := rx + r*math.Cos(t) + y := ry + r*math.Sin(t) + canvas.Text(int(x), height-int(y), digits[h%12], "baseline-shift:-30%") + } + canvas.Gend() + + // hour hand: special case: if the minute is greater than 30, + // adjust the hour hand the move proportionally closer to the upcoming hour. + t := hrangles[hour%12] + if min > 30 { + t = t - (30.0 * (float64(min) / 60.0)) + } + hr := r * 0.6 + hx := rx + hr*math.Cos(t*radians) + hy := ry + hr*math.Sin(t*radians) + + // minute hand + mr := r * 0.9 + t = minangles[min] * radians + mx := rx + mr*math.Cos(t) + my := ry + mr*math.Sin(t) + + // second hand + sr := r + t = minangles[sec] * radians + sx := rx + sr*math.Cos(t) + sy := ry + sr*math.Sin(t) + + // draw the hands and center dot + canvas.Line(cx, cy, int(hx), height-int(hy), fmt.Sprintf(linefmt, hrcolor, basesize)) + canvas.Line(cx, cy, int(mx), height-int(my), fmt.Sprintf(linefmt, mincolor, basesize/2)) + canvas.Line(cx, cy, int(sx), height-int(sy), fmt.Sprintf(linefmt, secolor, basesize/4)) + canvas.Circle(cx, cy, basesize, "fill:black") + canvas.End() +} + +// pacman draws pacman with dots +func pacman(w http.ResponseWriter, req *http.Request) { + log.Printf("pacman: %s", req.RemoteAddr) + query := req.URL.Query() + angle := qfloat(query, "angle", 30.0, 10.0, 70.0) + + w.Header().Set("Content-type", "image/svg+xml") + canvas := svg.New(w) + cx, cy := width/2, height/2 + r := width / 5 + p := r / 8 + canvas.Start(width, height) + canvas.Rect(0, 0, width, height) + + // draw dots + canvas.Gstyle("fill:white") + for x := 0; x < 100; x += 12 { + if x < 50 { + canvas.Circle((width*x)/100, cy, p, "fill-opacity:0.5") + } else { + canvas.Circle((width*x)/100, cy, p, "fill-opacity:1") + } + } + canvas.Gend() + + // draw pacman: two arcs, rotated, + // the angle determines how wide the mouth is open + canvas.Gstyle("fill:yellow") + + canvas.TranslateRotate(cx, cy, -angle) + canvas.Arc(-r, 0, r, r, 30, false, true, r, 0) + canvas.Gend() + + canvas.TranslateRotate(cx, cy, angle) + canvas.Arc(-r, 0, r, r, 30, false, false, r, 0) + canvas.Gend() + + canvas.Gend() + canvas.End() +} +func tux(w http.ResponseWriter, req *http.Request) { + log.Printf("tux: %s", req.RemoteAddr) + w.Header().Set("Content-type", "image/svg+xml") + canvas := svg.New(w) + canvas.Start(width, height) + canvas.Rect(0, 0, width, height, "fill:white") + canvas.Circle(width/2, height/2, height/2-20, "fill:black") + canvas.Ellipse(width/2, height, width/2, height/2, "fill:black") + canvas.Ellipse(width/3, height/2, 20, 40, "fill:white") + canvas.Ellipse(2*width/3, height/2, 20, 40, "fill:white") + canvas.Ellipse(width/3, height/2+18, 15, 20) + canvas.Ellipse(2*width/3, height/2+18, 15, 20) + + canvas.Circle(width/3+7, height/2+20, 5, "fill:white") + canvas.Circle(2*width/3+7, height/2+20, 5, "fill:white") + + canvas.Arc(60, height-60, width/3, 50, 0, false, true, width-60, height-60, + "stroke-width:3;stroke-linecap:round;stroke:yellow;fill:yellow") + + canvas.Arc(60, height-60, width/3, 140, 0, false, false, width-60, height-60, + "stroke-width:3;stroke-linecap:round;stroke:yellow") + + beakx := []int{58, width - 58, width / 2} + beaky := []int{height - 62, height - 62, height - 20} + canvas.Polygon(beakx, beaky, "fill:yellow") + + canvas.End() +} + +const ( + d2r = math.Pi / 180 + ustyle = "stroke:#DD4814;stroke-width:8" +) + +func polar(cx, cy, r, t int) (int, int) { + fr := float64(r) + ft := float64(t) * d2r + x := fr * math.Cos(ft) + y := fr * math.Sin(ft) + return cx + int(x), cy + int(y) +} + +func ubuntu(w http.ResponseWriter, req *http.Request) { + log.Printf("ubuntu: %s", req.RemoteAddr) + w.Header().Set("Content-type", "image/svg+xml") + canvas := svg.New(w) + cx, cy := width/2, height/2 + canvas.Start(width, height) + canvas.Rect(0, 0, width, height, "fill:white") + canvas.Circle(cx, cy, cx, "fill:#DD4814") + r := width / 3 + + canvas.Circle(cx, cy, r-10, "fill:none;stroke:white;stroke-width:25") + canvas.Gstyle("fill:white;" + ustyle) + for _, t := range []int{300, 180, 60} { + px, py := polar(cx, cy, r+10, t) + canvas.Circle(px, py, 20) + } + canvas.Gend() + + canvas.Gstyle(ustyle) + for _, t := range []int{120, 0, 240} { + lx2, ly2 := polar(cx, cy, r+25, t) + canvas.Line(cx, cy, lx2, ly2) + } + canvas.Gend() + + canvas.End() +} + diff --git a/vendor/github.com/ajstarks/svgo/planets/planets.go b/vendor/github.com/ajstarks/svgo/planets/planets.go new file mode 100644 index 0000000..5393d1b --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/planets/planets.go @@ -0,0 +1,122 @@ +// planets: an exploration of scale +// +build !appengine + +package main + +import ( + "flag" + "image/png" + "os" + + "github.com/ajstarks/svgo" +) + +var ssDist = []float64{ + 0.00, // Sun + 0.34, // Mercury + 0.72, // Venus + 1.00, // Earth + 1.54, // Mars + 5.02, // Jupiter + 9.46, // Saturn + 20.11, // Uranus + 30.08} // Netpune + +var ssRad = []float64{ // Miles + 423200.0, // Sun + 1516.0, // Mercury + 3760.0, // Venus + 3957.0, // Earth + 2104.0, // Mars + 42980.0, // Jupiter + 35610.0, // Saturn + 15700.0, // Uranus + 15260.0} // Neptune + +var ssColor = []string{ // R, G, B + // Eyeballed from image + "F7730C", // Sun + "FAF8F2", // Mercury + "FFFFF2", // Venus + "0B5CE3", // Earth + "F0C61D", // Mars + "FDC791", // Jupiter + "E0C422", // Saturn + "DCF1F5", // Uranus + "39B6F7"} // Neptune + +var ssImages = []string{ + "sun.png", + "mercury.png", + "venus.png", + "earth.png", + "mars.png", + "jupiter.png", + "saturn.png", + "uranus.png", + "neptune.png"} + +var showdisk = flag.Bool("d", false, "show disk") +var canvas = svg.New(os.Stdout) + +func vmap(value float64, low1 float64, high1 float64, low2 float64, high2 float64) float64 { + return low2 + (high2-low2)*(value-low1)/(high1-low1) +} + +func main() { + + width := 1200 + height := 200 + + flag.Parse() + canvas.Start(width, height) + canvas.Title("Planets") + canvas.Rect(0, 0, width, height, "fill:black") + nobj := len(ssDist) + y := height / 2 + margin := 100 + minsize := 7.0 + labeloc := height / 4 + + var x, r, imScale, maxh float64 + var px, po int + + if *showdisk { + maxh = float64(height) / minsize + } else { + maxh = float64(height) / 4.0 + } + for i := 1; i < nobj; i++ { + x = vmap(ssDist[i], ssDist[1], ssDist[nobj-1], float64(margin), float64(width-margin)) + r = (vmap(ssRad[i], ssRad[1], ssRad[nobj-1], minsize, maxh)) / 2 + px = int(x) + if *showdisk { + po = 0 + canvas.Circle(px, y, int(r), "fill:#"+ssColor[i]) + } else { // show images + f, err := os.Open(ssImages[i]) + if err != nil { + println("bad image file:", ssImages[i]) + continue + } + defer f.Close() + p, perr := png.DecodeConfig(f) + if perr != nil { + println("bad decode:", ssImages[i]) + continue + } + imScale = r / float64(p.Width) + hs := float64(p.Height) * imScale + dy := y - (int(hs) / 2) // center the image + po = int(r) / 2 + canvas.Image(px, dy, int(r), int(hs), ssImages[i]) + } + if ssDist[i] == 1.0 { // earth + canvas.Line(px+po, y-po, px+po, y-labeloc, + "stroke-width:1px;stroke:white") + canvas.Text(px+po, y-labeloc-10, "You are here", + "fill:white; font-size:14px; font-family:Calibri; text-anchor:middle") + } + } + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/pmap/pmap.go b/vendor/github.com/ajstarks/svgo/pmap/pmap.go new file mode 100644 index 0000000..489fe25 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/pmap/pmap.go @@ -0,0 +1,244 @@ +// pmap percentage maps +// +build !appengine + +package main + +import ( + "encoding/xml" + "flag" + "fmt" + "io" + "os" + + "github.com/ajstarks/svgo" +) + +// Pmap defines a porportional map +type Pmap struct { + Top int `xml:"top,attr"` + Left int `xml:"left,attr"` + Title string `xml:"title,attr"` + Pdata []Pdata `xml:"pdata"` +} + +// Pdata defines data with a portpotional map +type Pdata struct { + Legend string `xml:"legend,attr"` + Stagger string `xml:"stagger,attr"` + Alternate string `xml:"alternate,attr"` + Item []Item `xml:"item"` +} + +// Item defines an item with porpotional map data +type Item struct { + Name string `xml:",chardata"` + Value float64 `xml:"value,attr"` +} + +var ( + width, height, fontsize, fontscale, round, gutter, pred, pgreen, pblue, oflen int + bgcolor, olcolor, colorspec, title string + showpercent, showdata, alternate, showtitle, stagger, showlegend, showtotal bool + ofpct float64 + leftmargin = 40 + topmargin = 40 + canvas = svg.New(os.Stdout) +) + +const ( + globalfmt = "stroke-width:1;font-family:Calibri,sans-serif;text-anchor:middle;font-size:%dpt" + legendstyle = "text-anchor:start;font-size:150%" + linefmt = "stroke:%s" +) + +func dopmap(location string) { + var f *os.File + var err error + if len(location) > 0 { + f, err = os.Open(location) + } else { + f = os.Stdin + } + if err == nil { + readpmap(f) + f.Close() + } else { + fmt.Fprintf(os.Stderr, "%v\n", err) + } +} + +func readpmap(r io.Reader) { + var pm Pmap + if err := xml.NewDecoder(r).Decode(&pm); err == nil { + drawpmap(pm) + } else { + fmt.Fprintf(os.Stderr, "Unable to parse pmap (%v)\n", err) + } +} + +func drawpmap(m Pmap) { + fs := fontsize + if m.Left > 0 { + leftmargin = m.Left + } + if m.Top > 0 { + topmargin = m.Top + } else { + topmargin = fs * fontscale + } + x := leftmargin + y := topmargin + if len(m.Title) > 0 { + title = m.Title + } + canvas.Title(title) + if showtitle { + dotitle(title) + } + for _, p := range m.Pdata { + pmap(x, y, fs, p) + y += fs*fontscale + (gutter + fs*2) + } +} + +func pmap(x, y, fs int, m Pdata) { + var tfill, vfmt, oc string + var up bool + h := fs * fontscale + fw := fs * 80 + slen := fs + (fs / 2) + up = false + + sum := 0.0 + for _, v := range m.Item { + sum += v.Value + } + + if len(olcolor) > 0 { + oc = olcolor + } else { + oc = bgcolor + } + loffset := (fs * fontscale) + fs + gline := fmt.Sprintf(linefmt, "gray") + wline := fmt.Sprintf(linefmt, oc) + if len(m.Legend) > 0 && showlegend { + if showtotal { + canvas.Text(x, y-fs, fmt.Sprintf("%s (total: "+floatfmt(sum)+")", m.Legend, sum), legendstyle) + } else { + canvas.Text(x, y-fs, m.Legend, legendstyle) + } + } + for i, p := range m.Item { + k := p.Name + v := p.Value + if v == 0.0 { + continue + } + pct := v / sum + pw := int(pct * float64(fw)) + xw := x + (pw / 2) + yh := y + (h / 2) + if pct >= .4 { + tfill = "fill:white" + } else { + tfill = "fill:black" + } + if round > 0 { + canvas.Roundrect(x, y, pw, h, round, round, canvas.RGBA(pred, pgreen, pblue, pct)) + } else { + canvas.Rect(x, y, pw, h, canvas.RGBA(pred, pgreen, pblue, pct)) + } + + dy := yh + fs + (fs / 2) + if pct <= ofpct || len(k) > oflen { // overflow label + if up { + dy -= loffset + yh -= loffset + canvas.Line(xw, y, xw, dy+(fs/2), gline) + } else { + dy += loffset + yh += loffset + canvas.Line(xw, y+h, xw, dy-(fs*3), gline) + } + if alternate { + up = !up + slen = fs * 2 + } else { + slen = fs * 3 + } + if stagger { + loffset += slen + } + tfill = "fill:black" + } + canvas.Text(xw, yh, k, tfill) + dpfmt := tfill + ";font-size:75%" + vfmt = floatfmt(v) + switch { + case showpercent && !showdata: + canvas.Text(xw, dy, fmt.Sprintf("%.1f%%", pct*100), dpfmt) + case showpercent && showdata: + canvas.Text(xw, dy, fmt.Sprintf(vfmt+", %.1f%%", v, pct*100), dpfmt) + case showdata && !showpercent: + canvas.Text(xw, dy, fmt.Sprintf(vfmt, v), dpfmt) + } + x += pw + if i < len(m.Item) { + canvas.Line(x, y, x, y+h, wline) + } + } +} + +func floatfmt(v float64) string { + var vfmt = "%.1f" + if v-float64(int(v)) == 0.0 { + vfmt = "%.0f" + } + return vfmt +} + +func dotitle(s string) { + offset := 40 + canvas.Text(leftmargin, height-offset, s, "text-anchor:start;font-size:250%") +} + +func init() { + flag.IntVar(&width, "w", 1024, "width") + flag.IntVar(&height, "h", 768, "height") + flag.IntVar(&fontsize, "f", 12, "font size (pt)") + flag.IntVar(&fontscale, "s", 5, "font scaling factor") + flag.IntVar(&round, "r", 0, "rounded corner size") + flag.IntVar(&gutter, "g", 100, "gutter") + flag.IntVar(&oflen, "ol", 20, "overflow length") + flag.StringVar(&bgcolor, "bg", "white", "background color") + flag.StringVar(&olcolor, "oc", "", "outline color") + flag.StringVar(&colorspec, "c", "0,0,0", "color (r,g,b)") + flag.StringVar(&title, "t", "Proportions", "title") + flag.BoolVar(&showpercent, "p", false, "show percentage") + flag.BoolVar(&showdata, "d", false, "show data") + flag.BoolVar(&alternate, "a", false, "alternate overflow labels") + flag.BoolVar(&stagger, "stagger", false, "stagger labels") + flag.BoolVar(&showlegend, "showlegend", true, "show the legend") + flag.BoolVar(&showtitle, "showtitle", false, "show the title") + flag.BoolVar(&showtotal, "showtotal", false, "show totals in the legend") + flag.Float64Var(&ofpct, "op", 0.05, "overflow percentage") + flag.Parse() + fmt.Sscanf(colorspec, "%d,%d,%d", &pred, &pgreen, &pblue) +} + +func main() { + canvas.Start(width, height) + canvas.Rect(0, 0, width, height, "fill:"+bgcolor) + canvas.Gstyle(fmt.Sprintf(globalfmt, fontsize)) + + if len(flag.Args()) == 0 { + dopmap("") + } else { + for _, f := range flag.Args() { + dopmap(f) + } + } + canvas.Gend() + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/randcomp/randcomp.go b/vendor/github.com/ajstarks/svgo/randcomp/randcomp.go new file mode 100644 index 0000000..696f67a --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/randcomp/randcomp.go @@ -0,0 +1,59 @@ +// randcomp visualizes random number generators +// +build !appengine + +package main + +import ( + "fmt" + "math/rand" + "os" + "strconv" + "time" + + "github.com/ajstarks/svgo" +) + +var canvas = svg.New(os.Stdout) + +func main() { + width := 512 + height := 256 + var n = 256 + var rx, ry int + + if len(os.Args) > 1 { + n, _ = strconv.Atoi(os.Args[1]) + } + + f, _ := os.Open("/dev/urandom") + x := make([]byte, n) + y := make([]byte, n) + f.Read(x) + f.Read(y) + f.Close() + + rand.Seed(int64(time.Now().Nanosecond()) % 1e9) + canvas.Start(600, 400) + canvas.Title("Random Integer Comparison") + canvas.Desc("Comparison of Random integers: the random device & the Go rand package") + canvas.Rect(0, 0, width/2, height, "fill:white; stroke:gray") + canvas.Rect(width/2, 0, width/2, height, "fill:white; stroke:gray") + + canvas.Desc("Left: Go rand package (red), Right: /dev/urandom") + canvas.Gstyle("stroke:none; fill-opacity:0.5") + for i := 0; i < n; i++ { + rx = rand.Intn(255) + ry = rand.Intn(255) + canvas.Circle(rx, ry, 5, canvas.RGB(127, 0, 0)) + canvas.Circle(int(x[i])+255, int(y[i]), 5, "fill:black") + } + canvas.Gend() + + canvas.Desc("Legends") + canvas.Gstyle("text-anchor:middle; font-size:18; font-family:Calibri") + canvas.Text(128, 280, "Go rand package", "") + canvas.Text(384, 280, "/dev/urandom") + canvas.Text(256, 280, fmt.Sprintf("n=%d", n), "font-size:12") + canvas.Gend() + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/richter/richter.go b/vendor/github.com/ajstarks/svgo/richter/richter.go new file mode 100644 index 0000000..a99bdee --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/richter/richter.go @@ -0,0 +1,35 @@ +// richter -- inspired by Gerhard Richter's 256 colors, 1974 +// +build !appengine + +package main + +import ( + "math/rand" + "os" + "time" + + "github.com/ajstarks/svgo" +) + +var canvas = svg.New(os.Stdout) + +var width = 700 +var height = 400 + +func main() { + rand.Seed(int64(time.Now().Nanosecond()) % 1e9) + canvas.Start(width, height) + canvas.Title("Richter") + canvas.Rect(0, 0, width, height, "fill:white") + rw := 32 + rh := 18 + margin := 5 + for i, x := 0, 20; i < 16; i++ { + x += (rw + margin) + for j, y := 0, 20; j < 16; j++ { + canvas.Rect(x, y, rw, rh, canvas.RGB(rand.Intn(255), rand.Intn(255), rand.Intn(255))) + y += (rh + margin) + } + } + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/rl/rl.go b/vendor/github.com/ajstarks/svgo/rl/rl.go new file mode 100644 index 0000000..a233d4c --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/rl/rl.go @@ -0,0 +1,34 @@ +// rl - draw random lines +// +build !appengine + +package main + +import ( + "fmt" + "math/rand" + "os" + "time" + + "github.com/ajstarks/svgo" +) + +var canvas = svg.New(os.Stdout) + +func main() { + width := 200 + height := 200 + canvas.Start(width, height) + canvas.Title("Random Lines") + canvas.Rect(0, 0, width, height, "fill:black") + rand.Seed(int64(time.Now().Nanosecond()) % 1e9) + canvas.Gstyle("stroke-width:10") + r := 0 + for i := 0; i < width; i++ { + r = rand.Intn(255) + canvas.Line(i, 0, rand.Intn(width), height, fmt.Sprintf("stroke:rgb(%d,%d,%d); opacity:0.39", r, r, r)) + } + canvas.Gend() + + canvas.Text(width/2, height/2, "Random Lines", "fill:white; font-size:20; font-family:Calibri; text-anchor:middle") + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/rpd/rpd.go b/vendor/github.com/ajstarks/svgo/rpd/rpd.go new file mode 100644 index 0000000..397c418 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/rpd/rpd.go @@ -0,0 +1,80 @@ +package main + +// Imports +import ( + "encoding/xml" + "flag" + "fmt" + "github.com/ajstarks/svgo" + "io" + "os" +) + +// +// This is small +// This is medium +// This is large +// + +type Thing struct { + Top int `xml:"top,attr"` + Left int `xml:"left,attr"` + Sep int `xml:"sep,attr"` + Item []item `xml:"item"` +} + +type item struct { + Width int `xml:"width,attr"` + Height int `xml:"height,attr"` + Name string `xml:"name,attr"` + Color string `xml:"color,attr"` + Text string `xml:",chardata"` +} + +var ( + width = flag.Int("w", 1024, "width") + height = flag.Int("h", 768, "height") + canvas = svg.New(os.Stdout) +) + +// Open the file +func dothing(location string) { + f, err := os.Open(location) + if err != nil { + fmt.Fprintf(os.Stderr, "%v\n", err) + return + } + defer f.Close() + readthing(f) +} + +// Read the file, loading the defined structure +func readthing(r io.Reader) { + var t Thing + if err := xml.NewDecoder(r).Decode(&t); err != nil { + fmt.Fprintf(os.Stderr, "Unable to parse components (%v)\n", err) + return + } + drawthing(t) +} + +// use the items of "thing" to make the picture +func drawthing(t Thing) { + x := t.Left + y := t.Top + for _, v := range t.Item { + style := fmt.Sprintf("font-size:%dpx;fill:%s", v.Width/2, v.Color) + canvas.Circle(x, y, v.Height/4, "fill:"+v.Color) + canvas.Text(x+t.Sep, y, v.Name+":"+v.Text+"/"+v.Color, style) + y += v.Height + } +} + +func main() { + flag.Parse() + for _, f := range flag.Args() { + canvas.Start(*width, *height) + dothing(f) + canvas.End() + } +} diff --git a/vendor/github.com/ajstarks/svgo/rpd/thing.xml b/vendor/github.com/ajstarks/svgo/rpd/thing.xml new file mode 100644 index 0000000..fbd9d0c --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/rpd/thing.xml @@ -0,0 +1,5 @@ + + This is small + This is medium + This is large + diff --git a/vendor/github.com/ajstarks/svgo/rr/rr.go b/vendor/github.com/ajstarks/svgo/rr/rr.go new file mode 100644 index 0000000..0f93c83 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/rr/rr.go @@ -0,0 +1,208 @@ +// radar roadmap (via Ernst and Young) +package main + +import ( + "encoding/xml" + "flag" + "fmt" + "github.com/ajstarks/svgo" + "io" + "math" + "os" + "strings" +) + +var ( + width, height, iscale, fontsize, margin int + bgcolor, itemcolor, title string + opacity float64 + showtitle bool + gstyle = "font-family:Calibri;font-size:%dpx;text-anchor:middle" + canvas = svg.New(os.Stdout) +) + +// Roadmap XML structure: +// a roadmap consists of sections, which contain items, which indicate maturity and impact +type Roadmap struct { + Title string `xml:"title,attr"` + Duration int `xml:"duration,attr"` + Unit string `xml:"unit,attr"` + Section []section `xml:"section"` +} + +type section struct { + Name string `xml:"name,attr"` + Spacing float64 `xml:"spacing,attr"` + Item []item `xml:"item"` +} + +type item struct { + Impact int `xml:"impact,attr"` + Effort int `xml:"effort,attr"` + Begin string `xml:"begin,attr"` + Age float64 `xml:"age,attr"` + Name string `xml:",chardata"` + Desc desc `xml:"desc"` +} + +type desc struct { + Description string `xml:",chardata"` +} + +// dorr does file i/o +func dorr(location string) { + var f *os.File + var err error + if len(location) > 0 { + f, err = os.Open(location) + } else { + f = os.Stdin + } + if err == nil { + readrr(f) + f.Close() + } else { + fmt.Fprintf(os.Stderr, "%v\n", err) + } +} + +// readrr reads and parses the XML specification +func readrr(r io.Reader) { + var rm Roadmap + if err := xml.NewDecoder(r).Decode(&rm); err == nil { + drawrr(rm) + } else { + fmt.Fprintf(os.Stderr, "%v\n", err) + } +} + +// drawrr draws the roadmap +func drawrr(rm Roadmap) { + + if len(rm.Title) > 0 { + title = rm.Title + } + canvas.Title(title) + canvas.Gstyle(fmt.Sprintf(gstyle, fontsize)) + canvas.Rect(0, 0, width, height, "fill:"+bgcolor) + duration := rm.Duration + if duration <= 0 { + duration = 3 + } + ns := len(rm.Section) + cx := (width / 2) + cy := (height / 2) + r := ((width - margin) / duration) / 2 + sr := r + midsize := width / 100 + + // for each unit of time, draw cencentric circles + for i := 0; i < duration; i++ { + canvas.Circle(cx, cy, sr, "fill:none;stroke:lightgray;stroke-dasharray:7,7") + canvas.Text(cx, (cy - sr), fmt.Sprintf("%s %d", rm.Unit, i+1), "font-size:150%;fill:gray") + sr += r + } + // for each section, define its boundaries and draw its label + angle := 360.0 / float64(ns) + a := angle + a2 := a / 2 + for _, s := range rm.Section { + drawseclines(cx, cy, float64(r*duration), a, a2, s.Name) + spacing := s.Spacing + if spacing == 0 { + spacing = (angle / float64(len(s.Item))) - 1 + } + iangle := a + spacing + // for each item in the section, place the marker and label + for _, i := range s.Item { + itemx, itemy := dpolar(cx, cy, i.Age*float64(r), iangle) + drawitem(itemx, itemy, i.Impact*iscale, i.Effort, i.Name) + iangle += spacing + } + a += angle + } + + canvas.Circle(cx, cy, midsize, "fill:red") + canvas.Text(cx, cy, "READY", "baseline-shift:-25%") + if showtitle { + dotitle(title) + } + canvas.Gend() +} + +// radians converts degrees to radians +func radians(d float64) float64 { + return d * (math.Pi / 180.0) +} + +// dotitle places the title text +func dotitle(s string) { + canvas.Text(width/2, height-10, s, "font-size:200%;text-anchor:middle") +} + +// dpolar returns the cartesion coordinates given the center, size, and angle (in degrees) +func dpolar(cx, cy int, r, d float64) (int, int) { + x := r * math.Cos(radians(d)) + y := r * math.Sin(radians(d)) + return cx + int(x), cy + int(y) +} + +// drawseclines defines and labels the sections +func drawseclines(cx, cy int, size, a, h float64, s string) { + fs := fontsize + (fontsize / 2) + ix, iy := dpolar(cx, cy, size, a) + ix2, iy2 := dpolar(cx, cy, size+50, a+h) + canvas.Line(cx, cy, ix, iy, "stroke:lightgray") + textlines(ix2, iy2, fs, fs+2, "middle", "black", strings.Split(s, "\\n")) +} + +// drawitem draws a roadmap item +func drawitem(x, y, isize, ieffort int, s string) { + var op float64 + if ieffort > 0 { + op = opacity * (float64(ieffort) / 10.0) + } else { + op = opacity + } + style := fmt.Sprintf("fill:%s;fill-opacity:%.2f;stroke:white", itemcolor, op) + canvas.Circle(x, y, isize/2, style) + textlines(x-(isize/2)-2, y, fontsize, fontsize+2, "end", "black", strings.Split(s, "\\n")) +} + +// textlines displays text at a specified size, leading, fill, and alignment +func textlines(x, y, fs, leading int, align, fill string, s []string) { + canvas.Gstyle(fmt.Sprintf("font-size:%dpx;text-anchor:%s;fill:%s", fs, align, fill)) + for _, v := range s { + canvas.Text(x, y, v) + y += leading + } + canvas.Gend() +} + +// init sets up the command flags +func init() { + flag.StringVar(&bgcolor, "bg", "white", "background color") + flag.StringVar(&itemcolor, "ic", "rgb(131,206,226)", "item color") + flag.IntVar(&width, "w", 800, "width") + flag.IntVar(&height, "h", 800, "height") + flag.IntVar(&fontsize, "f", 12, "fontsize (px)") + flag.IntVar(&iscale, "s", int(float64(width)*.009), "impact scale") + flag.IntVar(&margin, "m", 150, "outside margin") + flag.BoolVar(&showtitle, "showtitle", false, "show title") + flag.StringVar(&title, "t", "Roadmap", "title") + flag.Float64Var(&opacity, "o", 1.0, "opacity") + flag.Parse() +} + +// for every input file (or stdin), draw a roadmap as specified by command flags +func main() { + canvas.Start(width, height) + if len(flag.Args()) == 0 { + dorr("") + } else { + for _, f := range flag.Args() { + dorr(f) + } + } + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/shotchart/shotchart.go b/vendor/github.com/ajstarks/svgo/shotchart/shotchart.go new file mode 100644 index 0000000..107834c --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/shotchart/shotchart.go @@ -0,0 +1,150 @@ +// shotchart: make NBA shotcharts +package main + +import ( + "encoding/json" + "flag" + "fmt" + "io" + "net/http" + "os" + + "github.com/ajstarks/svgo" +) + +// shotdata defines the shotchart JSON response from stats.nba.com +type shotdata struct { + Resource string `json:"resource"` + Parameters struct { + Leagueid string `json:"LeagueID"` + Season string `json:"Season"` + Seasontype string `json:"SeasonType"` + Teamid int `json:"TeamID"` + Playerid int `json:"PlayerID"` + Contextfilter string `json:"ContextFilter"` + Contextmeasure string `json:"ContextMeasure"` + } `json:"parameters"` + Resultsets []struct { + Name string `json:"name"` + Headers []string `json:"headers"` + Rowset [][]interface{} `json:"rowSet"` + } `json:"resultSets"` +} + +// vmap maps one range into another +func vmap(value, low1, high1, low2, high2 float64) float64 { + return low2 + (high2-low2)*(value-low1)/(high1-low1) +} + +const ( + shotsURLfmt = "http://stats.nba.com/stats/shotchartdetail?PlayerID=%s&CFID=33&CFPARAMS=2014-15&ContextFilter=&ContextMeasure=FGA&DateFrom=&DateTo=&GameID=&GameSegment=&LastNGames=0&LeagueID=00&Location=&MeasureType=Base&Month=0&OpponentTeamID=0&Outcome=&PaceAdjust=N&PerMode=PerGame&Period=0&PlusMinus=N&Position=&Rank=N&RookieYear=&Season=2014-15&SeasonSegment=&SeasonType=Regular+Season&TeamID=0&VsConference=&VsDivision=&mode=Advanced&showDetails=0&showShots=1&showZones=0" + picURLfmt = "http://stats.nba.com/media/players/230x185/%s.png" + activepicURLfmt = "http://stats.nba.com/media/players/700/%s.png" +) + +// shotAPI retrieves shotchart data from the source (currently stats.nba.com) +func shotAPI(id string) (io.ReadCloser, error) { + resp, err := http.Get(fmt.Sprintf(shotsURLfmt, id)) + if err != nil { + return nil, err + } + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("unable to retreive network data for %s (%s)", id, resp.Status) + } + return resp.Body, nil +} + +// shotchart retrieves shot data given an id, either from local files or the network API +func shotchart(id string, network bool) { + var ( + shots shotdata + r io.ReadCloser + err error + picture string + ) + + if network { + r, err = shotAPI(id) + if err != nil { + fmt.Fprintf(os.Stderr, "%v\n", err) + return + } + picture = fmt.Sprintf(activepicURLfmt, id) + } else { + r, err = os.Open(id + ".json") + if err != nil { + fmt.Fprintf(os.Stderr, "%v\n", err) + return + } + picture = id + ".png" + } + + defer r.Close() + err = json.NewDecoder(r).Decode(&shots) + if err != nil { + fmt.Fprintf(os.Stderr, "%v\n", err) + return + } + + // define the canvas, read and parse the response + canvas := svg.New(os.Stdout) + width, height := 900, 846 + fw, fh := float64(width), float64(height) + //imw, imh := 230, 185 + imw, imh := 700, 440 + top := fw / 10 + canvas.Start(width, height) + canvas.Rect(0, 0, width, height, "fill:white;stroke:black;stroke-width:2") + //canvas.Image(width-imw, height-imh, imw, imh, picture) + canvas.Image(width/2, height-imh, imw, imh, picture) + canvas.Gstyle("font-family:Calibri;sans-serif;font-size:24px") + nfg := 0 + for _, r := range shots.Resultsets { + if r.Name == "Shot_Chart_Detail" { + var playername string + attempts := len(r.Rowset) + for _, rs := range r.Rowset { + var x, y float64 + var fill string + for i, v := range rs { + if i == 4 { + playername = v.(string) + } + if i == 17 { + x = v.(float64) + } + if i == 18 { + y = v.(float64) + } + if i == 20 { + xp := int(vmap(x, -300, 300, 0, fw)) + yp := int(vmap(y, -300, 300, top, fh)) + if v.(float64) == 0 { + fill = "red" + } else { + nfg++ + fill = "black" + } + canvas.Circle(xp, (yp-(height/2))+10, 4, "fill-opacity:0.3;fill:"+fill) + } + } + } + fgpct := (float64(nfg) / float64(attempts)) * 100 + canvas.Text(10, height-40, playername, "fill:gray") + canvas.Text(10, height-10, fmt.Sprintf("%d out of %d", attempts, nfg), "fill:gray") + canvas.Text(width/2, height-10, fmt.Sprintf("%.1f%%", fgpct), "text-anchor:middle;font-size:120%;fill:gray") + canvas.Gend() + } + } + canvas.End() + +} +func main() { + var network bool + flag.BoolVar(&network, "net", false, "retrieve data from the network") + flag.Parse() + + for _, file := range flag.Args() { + shotchart(file, network) + } +} diff --git a/vendor/github.com/ajstarks/svgo/skewabc/skewabc.go b/vendor/github.com/ajstarks/svgo/skewabc/skewabc.go new file mode 100644 index 0000000..01e15d3 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/skewabc/skewabc.go @@ -0,0 +1,37 @@ +// skewabc - exercise the skew functions +// +build !appengine + +package main + +import ( + "fmt" + "os" + + "github.com/ajstarks/svgo" +) + +var ( + g = svg.New(os.Stdout) + width = 500 + height = 500 +) + +func sky(x, y, w, h int, a float64, s string) { + g.Gstyle(fmt.Sprintf("font-family:sans-serif;font-size:%dpx;text-anchor:middle", w/2)) + g.SkewY(a) + g.Rect(x, y, w, h, `fill:black; fill-opacity:0.3`) + g.Text(x+w/2, y+h/2, s, `fill:white;baseline-shift:-33%`) + g.Gend() + g.Gend() +} + +func main() { + g.Start(width, height) + g.Title("Skew") + g.Rect(0, 0, width, height, "fill:white") + g.Grid(0, 0, width, height, 50, "stroke:lightblue") + sky(100, 100, 100, 100, 30, "A") + sky(200, 332, 100, 100, -30, "B") + sky(300, -15, 100, 100, 30, "C") + g.End() +} diff --git a/vendor/github.com/ajstarks/svgo/stockproduct/stockproduct.go b/vendor/github.com/ajstarks/svgo/stockproduct/stockproduct.go new file mode 100644 index 0000000..a59a15e --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/stockproduct/stockproduct.go @@ -0,0 +1,179 @@ +// stockproduct draws a bar chart comparing stock price to products +// +build !appengine + +package main + +import ( + "encoding/xml" + "flag" + "fmt" + "os" + + "github.com/ajstarks/svgo" +) + +// Parameters defines options +type Parameters struct { + showline, showimage, showproduct, showprice, showdate, showgrid bool + x, y, w, h, width, height, spacing, fontsize, dot int + minvalue, maxvalue, ginterval, opacity, rotatetext float64 + barcolor string +} + +// +// +// +// +// +// +// +// + +// StockProduct is the top-level drawing +type StockProduct struct { + Title string `xml:"title,attr"` + Sdata []Sdata `xml:"sdata"` +} + +// Sdata defines stock data +type Sdata struct { + Price float64 `xml:"price,attr"` + Date string `xml:"date,attr"` + Product string `xml:"product,attr"` + Image string `xml:"image,attr"` +} + +// vmap maps ranges +func vmap(value float64, low1 float64, high1 float64, low2 float64, high2 float64) float64 { + return low2 + (high2-low2)*(value-low1)/(high1-low1) + +} + +// barchart draws a chart from data read at location, on a SVG canvas +// if the location is the empty string, read from standard input. +// Data items are scaled according to the width, with parameters controlling the visibility +// of lines, products, images, and dates +func (p *Parameters) barchart(location string, canvas *svg.SVG) { + var ( + f *os.File + err error + sp StockProduct + ) + if len(location) > 0 { + f, err = os.Open(location) + } else { + f = os.Stdin + } + if err != nil { + fmt.Fprintln(os.Stderr, err) + return + } + defer f.Close() + if err := xml.NewDecoder(f).Decode(&sp); err != nil { + fmt.Fprintln(os.Stderr, err) + return + } + + bottom := p.y + p.h + interval := p.w / (len(sp.Sdata) - 1) + bw := interval - p.spacing + offset := 120 + halfoffset := offset / 2 + + if bw < 2 { + bw = 2 + } + canvas.Text(p.x, p.y-halfoffset, sp.Title, "font-size:400%") + if p.showgrid { + canvas.Gstyle("stroke:lightgray;stroke-width:1px") + gx := p.x - (bw / 2) + for i := p.maxvalue; i >= p.minvalue; i -= p.ginterval { + yp := int(vmap(i, p.minvalue, p.maxvalue, float64(p.y), float64(bottom))) + by := p.y + (bottom - yp) + canvas.Line(gx, by, p.x+p.w+(bw/2), by) + canvas.Text(gx-halfoffset, by, fmt.Sprintf("%.0f", i), "fill:black;stroke:none") + } + canvas.Gend() + } + canvas.Gstyle(fmt.Sprintf("stroke-opacity:%.2f;stroke:%s;stroke-width:%d;text-anchor:middle", p.opacity, p.barcolor, bw)) + for _, d := range sp.Sdata { + yp := int(vmap(d.Price, p.minvalue, p.maxvalue, float64(p.y), float64(bottom))) + by := p.y + (bottom - yp) + if p.showline { + canvas.Line(p.x, bottom, p.x, by) + } + if p.dot > 0 { + canvas.Circle(p.x, by, p.dot, fmt.Sprintf("stroke:none;fill-opacity:%.2f;fill:%s", p.opacity, p.barcolor)) + } + if p.showimage { + if len(d.Image) > 0 { + canvas.Image(p.x-bw/2, by-offset-2, bw, offset, d.Image) + } + } + canvas.Gstyle("stroke:none;fill:black") + if p.showproduct { + if p.rotatetext != 0 { + canvas.TranslateRotate(p.x, bottom+40, p.rotatetext) + canvas.Text(0, 0, d.Product) + canvas.Gend() + } else { + canvas.Text(p.x, bottom+40, d.Product) + } + } + if p.showprice { + canvas.Text(p.x, by, fmt.Sprintf("%.2f", d.Price), "font-weight:bold") + } + if p.showdate { + canvas.Text(p.x, bottom+20, d.Date) + } + canvas.Gend() + p.x += interval + } + canvas.Gend() +} + +var param Parameters + +// set parameters according to command flags +func init() { + flag.BoolVar(¶m.showline, "line", true, "show lines") + flag.BoolVar(¶m.showimage, "image", true, "show images") + flag.BoolVar(¶m.showproduct, "product", true, "show products") + flag.BoolVar(¶m.showprice, "price", true, "show prices") + flag.BoolVar(¶m.showdate, "date", true, "show dates") + flag.BoolVar(¶m.showgrid, "grid", true, "show grid") + flag.IntVar(¶m.width, "w", 1600, "overall width") + flag.IntVar(¶m.height, "h", 900, "overall height") + flag.IntVar(¶m.x, "left", 150, "left") + flag.IntVar(¶m.y, "top", 120, "top") + flag.IntVar(¶m.w, "gw", 1400, "graph width") + flag.IntVar(¶m.h, "gh", 700, "graph height") + flag.IntVar(¶m.dot, "dot", 0, "dotsize") + flag.IntVar(¶m.fontsize, "fs", 14, "font size (px)") + flag.IntVar(¶m.spacing, "spacing", 15, "bar spacing") + flag.Float64Var(¶m.maxvalue, "max", 400, "max value") + flag.Float64Var(¶m.minvalue, "min", 0, "max value") + flag.Float64Var(¶m.ginterval, "ginterval", 50, "max value") + flag.Float64Var(¶m.opacity, "opacity", 0.5, "bar opacity") + flag.Float64Var(¶m.rotatetext, "rt", 0, "rotate text") + flag.StringVar(¶m.barcolor, "color", "lightgray", "bar color") + flag.Parse() +} + +func main() { + width := 1600 + height := 900 + canvas := svg.New(os.Stdout) + canvas.Start(param.width, param.height) + canvas.Rect(0, 0, width, height, canvas.RGB(255, 255, 255)) + canvas.Gstyle(fmt.Sprintf("font-family:Calibri;font-size:%dpx", param.fontsize)) + if len(flag.Args()) == 0 { + param.barchart("", canvas) + } else { + for _, f := range flag.Args() { + param.barchart(f, canvas) + } + } + canvas.Gend() + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/svg.go b/vendor/github.com/ajstarks/svgo/svg.go new file mode 100644 index 0000000..b3b7661 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/svg.go @@ -0,0 +1,978 @@ +// Package svg provides an API for generating Scalable Vector Graphics (SVG) +package svg + +// package main +// +// import ( +// "github.com/ajstarks/svgo" +// "os" +// ) +// +// var ( +// width = 500 +// height = 500 +// canvas = svg.New(os.Stdout) +// ) +// +// func main() { +// canvas.Start(width, height) +// canvas.Circle(width/2, height/2, 100) +// canvas.Text(width/2, height/2, "Hello, SVG", +// "text-anchor:middle;font-size:30px;fill:white") +// canvas.End() +// } +// + +import ( + "fmt" + "io" + + "encoding/xml" + "strings" +) + +// SVG defines the location of the generated SVG +type SVG struct { + Writer io.Writer +} + +// Offcolor defines the offset and color for gradients +type Offcolor struct { + Offset uint8 + Color string + Opacity float64 +} + +// Filterspec defines the specification of SVG filters +type Filterspec struct { + In, In2, Result string +} + +const ( + svgtop = ` + +` + vbfmt = `viewBox="%d %d %d %d"` + + emptyclose = "/>\n" +) + +// New is the SVG constructor, specifying the io.Writer where the generated SVG is written. +func New(w io.Writer) *SVG { return &SVG{w} } + +func (svg *SVG) print(a ...interface{}) (n int, errno error) { + return fmt.Fprint(svg.Writer, a...) +} + +func (svg *SVG) println(a ...interface{}) (n int, error error) { + return fmt.Fprintln(svg.Writer, a...) +} + +func (svg *SVG) printf(format string, a ...interface{}) (n int, errno error) { + return fmt.Fprintf(svg.Writer, format, a...) +} + +func (svg *SVG) genattr(ns []string) { + for _, v := range ns { + svg.printf("\n %s", v) + } + svg.println(svgns) +} + +// Structure, Metadata, Scripting, Transformation, and Links + +// Start begins the SVG document with the width w and height h. +// Other attributes may be optionally added, for example viewbox or additional namespaces +// Standard Reference: http://www.w3.org/TR/SVG11/struct.html#SVGElement +func (svg *SVG) Start(w int, h int, ns ...string) { + svg.printf(svginitfmt, svgtop, w, "", h, "") + svg.genattr(ns) +} + +// Startunit begins the SVG document, with width and height in the specified units +// Other attributes may be optionally added, for example viewbox or additional namespaces +func (svg *SVG) Startunit(w int, h int, unit string, ns ...string) { + svg.printf(svginitfmt, svgtop, w, unit, h, unit) + svg.genattr(ns) +} + +// Startpercent begins the SVG document, with width and height as percentages +// Other attributes may be optionally added, for example viewbox or additional namespaces +func (svg *SVG) Startpercent(w int, h int, ns ...string) { + svg.printf(svginitfmt, svgtop, w, "%", h, "%") + svg.genattr(ns) +} + +// Startview begins the SVG document, with the specified width, height, and viewbox +// Other attributes may be optionally added, for example viewbox or additional namespaces +func (svg *SVG) Startview(w, h, minx, miny, vw, vh int) { + svg.Start(w, h, fmt.Sprintf(vbfmt, minx, miny, vw, vh)) +} + +func (svg *SVG) StartviewUnit(w, h int, unit string, minx, miny, vw, vh int) { + svg.Startunit(w, h, unit, fmt.Sprintf(vbfmt, minx, miny, vw, vh)) +} + +// Startraw begins the SVG document, passing arbitrary attributes +func (svg *SVG) Startraw(ns ...string) { + svg.printf(svgtop) + svg.genattr(ns) +} + +// End the SVG document +func (svg *SVG) End() { svg.println("") } + +// Script defines a script with a specified type, (for example "application/javascript"). +// if the first variadic argument is a link, use only the link reference. +// Otherwise, treat those arguments as the text of the script (marked up as CDATA). +// if no data is specified, just close the script element +func (svg *SVG) Script(scriptype string, data ...string) { + svg.printf(`\n") + + default: + svg.println(`/>`) + } +} + +// Gstyle begins a group, with the specified style. +// Standard Reference: http://www.w3.org/TR/SVG11/struct.html#GElement +func (svg *SVG) Gstyle(s string) { svg.println(group("style", s)) } + +// Gtransform begins a group, with the specified transform +// Standard Reference: http://www.w3.org/TR/SVG11/coords.html#TransformAttribute +func (svg *SVG) Gtransform(s string) { svg.println(group("transform", s)) } + +// Translate begins coordinate translation, end with Gend() +// Standard Reference: http://www.w3.org/TR/SVG11/coords.html#TransformAttribute +func (svg *SVG) Translate(x, y int) { svg.Gtransform(translate(x, y)) } + +// Scale scales the coordinate system by n, end with Gend() +// Standard Reference: http://www.w3.org/TR/SVG11/coords.html#TransformAttribute +func (svg *SVG) Scale(n float64) { svg.Gtransform(scale(n)) } + +// ScaleXY scales the coordinate system by dx and dy, end with Gend() +// Standard Reference: http://www.w3.org/TR/SVG11/coords.html#TransformAttribute +func (svg *SVG) ScaleXY(dx, dy float64) { svg.Gtransform(scaleXY(dx, dy)) } + +// SkewX skews the x coordinate system by angle a, end with Gend() +// Standard Reference: http://www.w3.org/TR/SVG11/coords.html#TransformAttribute +func (svg *SVG) SkewX(a float64) { svg.Gtransform(skewX(a)) } + +// SkewY skews the y coordinate system by angle a, end with Gend() +// Standard Reference: http://www.w3.org/TR/SVG11/coords.html#TransformAttribute +func (svg *SVG) SkewY(a float64) { svg.Gtransform(skewY(a)) } + +// SkewXY skews x and y coordinates by ax, ay respectively, end with Gend() +// Standard Reference: http://www.w3.org/TR/SVG11/coords.html#TransformAttribute +func (svg *SVG) SkewXY(ax, ay float64) { svg.Gtransform(skewX(ax) + " " + skewY(ay)) } + +// Rotate rotates the coordinate system by r degrees, end with Gend() +// Standard Reference: http://www.w3.org/TR/SVG11/coords.html#TransformAttribute +func (svg *SVG) Rotate(r float64) { svg.Gtransform(rotate(r)) } + +// TranslateRotate translates the coordinate system to (x,y), then rotates to r degrees, end with Gend() +func (svg *SVG) TranslateRotate(x, y int, r float64) { + svg.Gtransform(translate(x, y) + " " + rotate(r)) +} + +// RotateTranslate rotates the coordinate system r degrees, then translates to (x,y), end with Gend() +func (svg *SVG) RotateTranslate(x, y int, r float64) { + svg.Gtransform(rotate(r) + " " + translate(x, y)) +} + +// Group begins a group with arbitrary attributes +func (svg *SVG) Group(s ...string) { svg.printf("`)) } + +// Gid begins a group, with the specified id +func (svg *SVG) Gid(s string) { + svg.print(``) +} + +// Gend ends a group (must be paired with Gsttyle, Gtransform, Gid). +func (svg *SVG) Gend() { svg.println(``) } + +// ClipPath defines a clip path +func (svg *SVG) ClipPath(s ...string) { svg.printf(``)) } + +// ClipEnd ends a ClipPath +func (svg *SVG) ClipEnd() { + svg.println(``) +} + +// Def begins a defintion block. +// Standard Reference: http://www.w3.org/TR/SVG11/struct.html#DefsElement +func (svg *SVG) Def() { svg.println(``) } + +// DefEnd ends a defintion block. +func (svg *SVG) DefEnd() { svg.println(``) } + +// Marker defines a marker +// Standard reference: http://www.w3.org/TR/SVG11/painting.html#MarkerElement +func (svg *SVG) Marker(id string, x, y, width, height int, s ...string) { + svg.printf(`\n")) +} + +// MarkEnd ends a marker +func (svg *SVG) MarkerEnd() { svg.println(``) } + +// Pattern defines a pattern with the specified dimensions. +// The putype can be either "user" or "obj", which sets the patternUnits +// attribute to be either userSpaceOnUse or objectBoundingBox +// Standard reference: http://www.w3.org/TR/SVG11/pservers.html#Patterns +func (svg *SVG) Pattern(id string, x, y, width, height int, putype string, s ...string) { + puattr := "userSpaceOnUse" + if putype != "user" { + puattr = "objectBoundingBox" + } + svg.printf(`\n")) +} + +// PatternEnd ends a marker +func (svg *SVG) PatternEnd() { svg.println(``) } + +// Desc specified the text of the description tag. +// Standard Reference: http://www.w3.org/TR/SVG11/struct.html#DescElement +func (svg *SVG) Desc(s string) { svg.tt("desc", s) } + +// Title specified the text of the title tag. +// Standard Reference: http://www.w3.org/TR/SVG11/struct.html#TitleElement +func (svg *SVG) Title(s string) { svg.tt("title", s) } + +// Link begins a link named "name", with the specified title. +// Standard Reference: http://www.w3.org/TR/SVG11/linking.html#Links +func (svg *SVG) Link(href string, title string) { + svg.printf("") +} + +// LinkEnd ends a link. +func (svg *SVG) LinkEnd() { svg.println(``) } + +// Use places the object referenced at link at the location x, y, with optional style. +// Standard Reference: http://www.w3.org/TR/SVG11/struct.html#UseElement +func (svg *SVG) Use(x int, y int, link string, s ...string) { + svg.printf(``)) +} + +// MaskEnd ends a Mask. +func (svg *SVG) MaskEnd() { svg.println(``) } + +// Shapes + +// Circle centered at x,y, with radius r, with optional style. +// Standard Reference: http://www.w3.org/TR/SVG11/shapes.html#CircleElement +func (svg *SVG) Circle(x int, y int, r int, s ...string) { + svg.printf(`")) + xml.Escape(svg.Writer, []byte(t)) + svg.println(``) +} + +// Textpath places text optionally styled text along a previously defined path +// Standard Reference: http://www.w3.org/TR/SVG11/text.html#TextPathElement +func (svg *SVG) Textpath(t string, pathid string, s ...string) { + svg.printf("", endstyle(s, ">"), pathid) + xml.Escape(svg.Writer, []byte(t)) + svg.println(``) +} + +// Textlines places a series of lines of text starting at x,y, at the specified size, fill, and alignment. +// Each line is spaced according to the spacing argument +func (svg *SVG) Textlines(x, y int, s []string, size, spacing int, fill, align string) { + svg.Gstyle(fmt.Sprintf("font-size:%dpx;fill:%s;text-anchor:%s", size, fill, align)) + for _, t := range s { + svg.Text(x, y, t) + y += spacing + } + svg.Gend() +} + +// Colors + +// RGB specifies a fill color in terms of a (r)ed, (g)reen, (b)lue triple. +// Standard reference: http://www.w3.org/TR/css3-color/ +func (svg *SVG) RGB(r int, g int, b int) string { + return fmt.Sprintf(`fill:rgb(%d,%d,%d)`, r, g, b) +} + +// RGBA specifies a fill color in terms of a (r)ed, (g)reen, (b)lue triple and opacity. +func (svg *SVG) RGBA(r int, g int, b int, a float64) string { + return fmt.Sprintf(`fill-opacity:%.2f; %s`, a, svg.RGB(r, g, b)) +} + +// Gradients + +// LinearGradient constructs a linear color gradient identified by id, +// along the vector defined by (x1,y1), and (x2,y2). +// The stop color sequence defined in sc. Coordinates are expressed as percentages. +func (svg *SVG) LinearGradient(id string, x1, y1, x2, y2 uint8, sc []Offcolor) { + svg.printf("\n", + id, pct(x1), pct(y1), pct(x2), pct(y2)) + svg.stopcolor(sc) + svg.println("") +} + +// RadialGradient constructs a radial color gradient identified by id, +// centered at (cx,cy), with a radius of r. +// (fx, fy) define the location of the focal point of the light source. +// The stop color sequence defined in sc. +// Coordinates are expressed as percentages. +func (svg *SVG) RadialGradient(id string, cx, cy, r, fx, fy uint8, sc []Offcolor) { + svg.printf("\n", + id, pct(cx), pct(cy), pct(r), pct(fx), pct(fy)) + svg.stopcolor(sc) + svg.println("") +} + +// stopcolor is a utility function used by the gradient functions +// to define a sequence of offsets (expressed as percentages) and colors +func (svg *SVG) stopcolor(oc []Offcolor) { + for _, v := range oc { + svg.printf("\n", + pct(v.Offset), v.Color, v.Opacity) + } +} + +// Filter Effects: +// Most functions have common attributes (in, in2, result) defined in type Filterspec +// used as a common first argument. + +// Filter begins a filter set +// Standard reference: http://www.w3.org/TR/SVG11/filters.html#FilterElement +func (svg *SVG) Filter(id string, s ...string) { + svg.printf(`\n")) +} + +// Fend ends a filter set +// Standard reference: http://www.w3.org/TR/SVG11/filters.html#FilterElement +func (svg *SVG) Fend() { + svg.println(``) +} + +// FeBlend specifies a Blend filter primitive +// Standard reference: http://www.w3.org/TR/SVG11/filters.html#feBlendElement +func (svg *SVG) FeBlend(fs Filterspec, mode string, s ...string) { + switch mode { + case "normal", "multiply", "screen", "darken", "lighten": + break + default: + mode = "normal" + } + svg.printf(` 360 { + value = 0 + } + svg.printf(` 1 { + value = 1 + } + svg.printf(``) +} + +// FeCompEnd ends a feComponent filter element +// Standard reference: http://www.w3.org/TR/SVG11/filters.html#feComponentTransferElement +func (svg *SVG) FeCompEnd() { + svg.println(``) +} + +// FeComposite specifies a feComposite filter primitive +// Standard reference: http://www.w3.org/TR/SVG11/filters.html#feCompositeElement +func (svg *SVG) FeComposite(fs Filterspec, operator string, k1, k2, k3, k4 int, s ...string) { + switch operator { + case "over", "in", "out", "atop", "xor", "arithmetic": + break + default: + operator = "over" + } + svg.printf(``)) +} + +// FeDiffEnd ends a diffuse lighting filter primitive container +// Standard reference: http://www.w3.org/TR/SVG11/filters.html#feDiffuseLightingElement +func (svg *SVG) FeDiffEnd() { + svg.println(``) +} + +// FeDisplacementMap specifies a feDisplacementMap filter primitive +// Standard reference: http://www.w3.org/TR/SVG11/filters.html#feDisplacementMapElement +func (svg *SVG) FeDisplacementMap(fs Filterspec, scale float64, xchannel, ychannel string, s ...string) { + svg.printf(``) + for _, n := range nodes { + svg.printf("\n", n) + } + svg.println(``) +} + +// FeMorphology specifies a feMorphologyLight filter primitive +// Standard reference: http://www.w3.org/TR/SVG11/filters.html#feMorphologyElement +func (svg *SVG) FeMorphology(fs Filterspec, operator string, xradius, yradius float64, s ...string) { + switch operator { + case "erode", "dilate": + break + default: + operator = "erode" + } + svg.printf(`\n")) +} + +// FeSpecEnd ends a specular lighting filter primitive container +// Standard reference: http://www.w3.org/TR/SVG11/filters.html#feSpecularLightingElement +func (svg *SVG) FeSpecEnd() { + svg.println(``) +} + +// FeSpotLight specifies a feSpotLight filter primitive +// Standard reference: http://www.w3.org/TR/SVG11/filters.html#feSpotLightElement +func (svg *SVG) FeSpotLight(fs Filterspec, x, y, z, px, py, pz float64, s ...string) { + svg.printf(` 1 { + bfx = 0 + } + if bfy < 0 || bfy > 1 { + bfy = 0 + } + switch ftype[0:1] { + case "f", "F": + ftype = "fractalNoise" + case "t", "T": + ftype = "turbulence" + default: + ftype = "turbulence" + } + + var ss string + if stitch { + ss = "stitch" + } else { + ss = "noStitch" + } + svg.printf(` 0 { + svg.Gstyle(s[0]) + } + for ix := x; ix <= x+w; ix += n { + svg.Line(ix, y, ix, y+h) + } + + for iy := y; iy <= y+h; iy += n { + svg.Line(x, iy, x+w, iy) + } + if len(s) > 0 { + svg.Gend() + } + +} + +// Support functions + +// style returns a style name,attribute string +func style(s string) string { + if len(s) > 0 { + return fmt.Sprintf(`style="%s"`, s) + } + return s +} + +// pp returns a series of polygon points +func (svg *SVG) pp(x []int, y []int, tag string) { + svg.print(tag) + if len(x) != len(y) { + svg.print(" ") + return + } + lx := len(x) - 1 + for i := 0; i < lx; i++ { + svg.print(coord(x[i], y[i]) + " ") + } + svg.print(coord(x[lx], y[lx])) +} + +// endstyle modifies an SVG object, with either a series of name="value" pairs, +// or a single string containing a style +func endstyle(s []string, endtag string) string { + if len(s) > 0 { + nv := "" + for i := 0; i < len(s); i++ { + if strings.Index(s[i], "=") > 0 { + nv += (s[i]) + " " + } else { + nv += style(s[i]) + } + } + return nv + endtag + } + return endtag + +} + +// tt creates a xml element, tag containing s +func (svg *SVG) tt(tag string, s string) { + svg.print("<" + tag + ">") + xml.Escape(svg.Writer, []byte(s)) + svg.println("") +} + +// poly compiles the polygon element +func (svg *SVG) poly(x []int, y []int, tag string, s ...string) { + svg.pp(x, y, "<"+tag+" points=\"") + svg.print(`" ` + endstyle(s, "/>\n")) +} + +// onezero returns "0" or "1" +func onezero(flag bool) string { + if flag { + return "1" + } + return "0" +} + +// pct returns a percetage, capped at 100 +func pct(n uint8) uint8 { + if n > 100 { + return 100 + } + return n +} + +// islink determines if a string is a script reference +func islink(link string) bool { + return strings.HasPrefix(link, "http://") || strings.HasPrefix(link, "#") || + strings.HasPrefix(link, "../") || strings.HasPrefix(link, "./") +} + +// group returns a group element +func group(tag string, value string) string { return fmt.Sprintf(``, tag, value) } + +// scale return the scale string for the transform +func scale(n float64) string { return fmt.Sprintf(`scale(%g)`, n) } + +// scaleXY return the scale string for the transform +func scaleXY(dx, dy float64) string { return fmt.Sprintf(`scale(%g,%g)`, dx, dy) } + +// skewx returns the skewX string for the transform +func skewX(angle float64) string { return fmt.Sprintf(`skewX(%g)`, angle) } + +// skewx returns the skewX string for the transform +func skewY(angle float64) string { return fmt.Sprintf(`skewY(%g)`, angle) } + +// rotate returns the rotate string for the transform +func rotate(r float64) string { return fmt.Sprintf(`rotate(%g)`, r) } + +// translate returns the translate string for the transform +func translate(x, y int) string { return fmt.Sprintf(`translate(%d,%d)`, x, y) } + +// coord returns a coordinate string +func coord(x int, y int) string { return fmt.Sprintf(`%d,%d`, x, y) } + +// ptag returns the beginning of the path element +func ptag(x int, y int) string { return fmt.Sprintf(` 0 { + attrs += fmt.Sprintf(`in="%s" `, s.In) + } + if len(s.In2) > 0 { + attrs += fmt.Sprintf(`in2="%s" `, s.In2) + } + if len(s.Result) > 0 { + attrs += fmt.Sprintf(`result="%s" `, s.Result) + } + return attrs +} + +// tablevalues outputs a series of values as a XML attribute +func (svg *SVG) tablevalues(s string, t []float64) { + svg.printf(` %s="`, s) + for i := 0; i < len(t)-1; i++ { + svg.printf("%g ", t[i]) + } + svg.printf(`%g"%s`, t[len(t)-1], emptyclose) +} + +// imgchannel validates the image channel indicator +func imgchannel(c string) string { + switch c { + case "R", "G", "B", "A": + return c + case "r", "g", "b", "a": + return strings.ToUpper(c) + case "red", "green", "blue", "alpha": + return strings.ToUpper(c[0:1]) + case "Red", "Green", "Blue", "Alpha": + return c[0:1] + } + return "R" +} diff --git a/vendor/github.com/ajstarks/svgo/svgdef.pdf b/vendor/github.com/ajstarks/svgo/svgdef.pdf new file mode 100644 index 0000000000000000000000000000000000000000..cc8ff60c8f6b16fe190b14fafbdbbca2e5870720 GIT binary patch literal 234105 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�kpEQBB|qrs0!aVSA=V&rTlbgYubC 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

v&`Q4+4X0dI)ZWQ&bj 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

  • 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

    U-5HO$n7R9al1uA>I+HThSqdU1utYwCu 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μ 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 + + +Object Definitions + + + + + + + + + + + + + + + + +x, y + +w +Square(x, y, w int, style ...string) + + + +x, y + +h +w +Rect(x, y, w, h int, style ...string) + + + +x, y + +h +w +CenterRect(x, y, w, h int, style ...string) + + + +x, y + +h +w + + +ry +rx +Roundrect(x, y, w, h, rx, ry int, style ...string) + + + +x, y + +x, y + +x, y + +x, y + +x, y + +x, y + +Polygon(x, y []int, style ...string) + + + + +x, y + + +r +Circle(x, y, r int, style ...string) + + + + + +x, y + + + +rx +ry +Ellipse(x, y, rx, ry int, style ...string) + + + + +x1, y1 + +x2, y2 + +Line(x1, y1, x2, y2 int, style ...string) + + + +x, y + +x, y + +x, y + +x, y + +Polyline(x, y []int, style ...string) + + + +sx, sy + +ex, ey + +Arc(sx, sy, ax, ay, r int, lflag, sflag bool, ex, ey int, style ...string) + + + + + +x, y +Path(s string, style ...string) + + + +sx, sy + +cx, cy + +ex, ey + +Qbez(sx, sy, cx, cy, ex, ey int, style ...string) + + + +sx, sy + +cx, cy + +px, py + +ex, ey + +Bezier(sx, sy, cx, cy, px, py, ex, ey int, style ...string) + + + +x, y + +h +w + +Image(x, y, w, h, int path string, style ...string) + + + + +x1%, y1% + +x2%, y2% +LinearGradient(s string, x1, y1, x2, y2 uint8, oc []Offcolor) + + + + +cx%, cy% + +fx%, fy% +RadialGradient(s string, cx, cy, r, fx, fy uint8, oc []Offcolor) + + + +0, 0 + +x, y +Translate(x, y int) + + + + + + + +x, y +h +w +n + + + + + + + + + + + + + + + + +Grid(x, y, w, h, n int, style ...string) + + + +x, y +hello, this is SVG +Text(x, y int, s string, style ...string) + + + +0, 0 + + + + +Scale(n float64) + + + +0, 0 + + + + +ScaleXY(x, y float64) + + + +0, 0 + + + + +SkewX(a float64) + + + +0, 0 + + + + +SkewY(a float64) + + + +0, 0 + + + + +SkewXY(x, y float64) + + + +0, 0 +Rotate(r float64) + + +r + + + + + +It's "fine" & "dandy" to draw text along a path +Textpath(s, pathid string, style ...string) + + + +New(w io Writer) +Start(w, h int, options ...string)/End() +Startview(w, h, minx, miny, vw, vh int) +Group(s ...string)/Gend() +Gstyle(s string)/Gend() +Gtransform(s string)/Gend() +Gid(id string)/Gend() +ClipPath(s ...string)/ClipEnd() +Def()/DefEnd() +Marker()/MarkerEnd() +Pattern()/PatternEnd() +Desc(s string) +Title(s string) +Script(type, data ...string) +Mask(id string, x,y,w,h int, style ...string)/MaskEnd() +Link(href string, title string)/LinkEnd() +Use(x int, y int, link string, style ...string) + + +specify destination +begin/end the document +begin/end the document with viewport +begin/end group with attributes +begin/end group style +begin/end group transform +begin/end group id +begin/end clip path +begin/end a defintion block +begin/end markers +begin/end pattern +set the description element +set the title element +define a script +begin/end mask element +begin/end link to href, with a title +use defined objects + +Textlines(x, y int, s []string, size, spacing int, fill, align string) + + + + + + + +r +g +b +-> + +RGB(r, g, b int) + + + + + + + + +alpha +r +g +b +-> + +RGBA(r, g, b int, opacity float64) + + +SVG Go Library Description + + + +SVG Go Library +github.com/ajstarks/svgo + +Object Usage + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/github.com/ajstarks/svgo/svgdef/svgdef.go b/vendor/github.com/ajstarks/svgo/svgdef/svgdef.go new file mode 100644 index 0000000..6daba5f --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/svgdef/svgdef.go @@ -0,0 +1,536 @@ +// svgdef - SVG Object Definition and Use +// +build !appengine + +package main + +import ( + "math" + "os" + + "github.com/ajstarks/svgo" +) + +const ( + textsize = 24 + coordsize = 4 + objcolor = "rgb(0,0,127)" + objstyle = "fill:none; stroke-width:2;stroke:" + objcolor + fobjstyle = "fill-opacity:0.25;fill:" + objcolor + legendstyle = "fill:gray; text-anchor:middle" + titlestyle = "fill:black; text-anchor:middle;font-size:24px" + linestyle = "stroke:black; stroke-width:1" + gtextstyle = "font-family:Calibri,sans; text-anchor:middle; font-size:24px" + coordstring = "x, y" + tpathstring = `It's "fine" & "dandy" to draw text along a path` +) + +var ( + canvas = svg.New(os.Stdout) + grayfill = canvas.RGB(220, 220, 220) + oc1 = svg.Offcolor{Offset: 0, Color: "white", Opacity: 1.0} + oc2 = svg.Offcolor{Offset: 25, Color: "lightblue", Opacity: 1.0} + oc3 = svg.Offcolor{Offset: 75, Color: "blue", Opacity: 1.0} + oc4 = svg.Offcolor{Offset: 100, Color: objcolor, Opacity: 1.0} + ga = []svg.Offcolor{oc1, oc2, oc3, oc4} +) + +// defcoodstr defines coordinate strings: (x,y) +func defcoordstr(x int, y int, s string) { + canvas.Circle(x, y, coordsize, grayfill) + canvas.Text(x, y-textsize, s, legendstyle) +} + +// defcoord defines a coordinate +func defcoord(x, y, n int) { + canvas.Circle(x, y, coordsize, grayfill) + canvas.Text(x, y+n, coordstring, legendstyle) +} + +// deflegend makes object legends +func deflegend(x int, y int, size int, legend string) { + canvas.Text(x, y+size+textsize, legend, titlestyle) +} + +// defcircle defines the circle object for arbitrary placement and size +func defcircle(id string, w, h int, legend string) { + canvas.Gid(id) + canvas.Translate(w, h) + defcoord(0, 0, -textsize) + canvas.Circle(0, 0, h, objstyle) + canvas.Line(0, 0, h, 0, linestyle) + canvas.Text(h/2, textsize, "r", legendstyle) + deflegend(0, 0, h, legend) + canvas.Gend() + canvas.Gend() +} + +// defellipse defines the ellipse object for arbitrary placement and size +func defellipse(id string, w int, h int, legend string) { + canvas.Gid(id) + canvas.Translate(w, h) + defcoord(0, 0, -textsize) + canvas.Ellipse(0, 0, w, h, objstyle) + canvas.Line(0, 0, w, 0, linestyle) + canvas.Line(0, 0, 0, h, linestyle) + canvas.Text(w/2, textsize, "rx", legendstyle) + canvas.Text(-textsize, (h / 2), "ry", legendstyle) + deflegend(0, 0, h, legend) + canvas.Gend() + canvas.Gend() +} + +// defrect defines the rectangle object for arbitrary placement and size +func defrect(id string, w int, h int, legend string) { + canvas.Gid(id) + defcoord(0, 0, -textsize) + canvas.Rect(0, 0, w, h, objstyle) + canvas.Text(-textsize, (h / 2), "h", legendstyle) + canvas.Text((w / 2), -textsize, "w", legendstyle) + deflegend((w / 2), 0, h, legend) + canvas.Gend() +} + +// defcrect defines the centered rectangle object for arbitrary placement and size +func defcrect(id string, w int, h int, legend string) { + canvas.Gid(id) + defcoord(w/2, h/2, -textsize) + canvas.Rect(0, 0, w, h, objstyle) + canvas.Text(-textsize, (h / 2), "h", legendstyle) + canvas.Text((w / 2), -textsize, "w", legendstyle) + deflegend((w / 2), 0, h, legend) + canvas.Gend() +} + +// defsquare defines the square object for arbitrary placement and size +func defsquare(id string, w int, legend string) { + canvas.Gid(id) + defcoord(0, 0, -textsize) + canvas.Square(0, 0, w, objstyle) + canvas.Text((w / 2), -textsize, "w", legendstyle) + deflegend((w / 2), 0, w, legend) + canvas.Gend() +} + +// defimage defines the image object for arbitrary placement and size +func defimage(id string, w int, h int, s string, legend string) { + canvas.Gid(id) + defcoord(0, 0, -textsize) + canvas.Rect(0, 0, w, h, objstyle) + canvas.Text(-textsize, (h / 2), "h", legendstyle) + canvas.Text((w / 2), -textsize, "w", legendstyle) + canvas.Image(0, 0, w, h, s) + deflegend(w/2, h, 0, legend) + canvas.Gend() +} + +// defline defines the line object for arbitrary placement and size +func defline(id string, w int, h int, legend string) { + canvas.Gid(id) + defcoordstr(0, 0, "x1, y1") + defcoordstr(w, 0, "x2, y2") + canvas.Line(0, 0, w, 0, objstyle) + deflegend(w/2, h, 0, legend) + canvas.Gend() +} + +// defarc defines the arc object for arbitrary placement and size +func defarc(id string, w int, h int, legend string) { + canvas.Gid(id) + defcoordstr(0, 0, "sx, sy") + defcoordstr(w*2, 0, "ex, ey") + canvas.Arc(0, 0, h, h, 0, false, true, w*2, 0, objstyle) + deflegend(w, h, h, legend) + canvas.Gend() +} + +// defbez defines the cublic bezier object for arbitrary placement and size +func defbez(id string, x int, y int, h int, legend string) { + sx, sy := 0, 0 + cx, cy := x, -y + px, py := x, y + ex, ey := x*2, 0 + canvas.Gid(id) + defcoordstr(sx, sy, "sx, sy") + defcoordstr(cx, cy, "cx, cy") + defcoordstr(px, py, "px, py") + defcoordstr(ex, ey, "ex, ey") + canvas.Bezier(sx, sy, cx, cy, px, py, ex, ey, objstyle) + deflegend(px, h, 0, legend) + canvas.Gend() +} + +// defqbez defines the quadratic bezier object for arbitrary placement and size +func defqbez(id string, px int, py int, h int, legend string) { + sx, sy := 0, 0 + ex, ey := px*2, 0 + cx, cy := (ex-px)/3, -py-(py/2) + canvas.Gid(id) + defcoordstr(sx, sy, "sx, sy") + defcoordstr(cx, cy, "cx, cy") + defcoordstr(ex, ey, "ex, ey") + canvas.Qbez(sx, sy, cx, cy, ex, ey, objstyle) + deflegend(px, h, 0, legend) + canvas.Gend() +} + +// defroundrect defines the roundrect object for arbitrary placement and size +func defroundrect(id string, w int, h int, rx int, ry int, legend string) { + canvas.Gid(id) + defcoord(0, 0, -textsize) + canvas.Roundrect(0, 0, w, h, rx, ry, objstyle) + canvas.Text(-textsize, (h / 2), "h", legendstyle) + canvas.Text((w / 2), -textsize, "w", legendstyle) + canvas.Line(rx, 0, rx, ry, linestyle) + canvas.Line(0, ry, rx, ry, linestyle) + canvas.Text(rx+textsize, ry-(ry/2), "ry", legendstyle) + canvas.Text((rx / 2), ry+textsize, "rx", legendstyle) + deflegend((w / 2), 0, h, legend) + canvas.Gend() +} + +// defpolygon defines the polygon object for arbitrary placement and size +func defpolygon(id string, w int, h int, legend string) { + var x = []int{0, w / 2, w, w, w / 2, 0} + var y = []int{0, -h / 4, 0, (h * 3) / 4, h / 2, (h * 3) / 4} + canvas.Gid(id) + for i := 0; i < len(x); i++ { + defcoord(x[i], y[i], -textsize) + } + canvas.Polygon(x, y, objstyle) + deflegend(w/2, h, 0, legend) + canvas.Gend() +} + +// defpolyline defines the polyline object for arbitrary placement and size +func defpolyline(id string, w int, h int, legend string) { + var x = []int{0, w / 3, (w * 3) / 4, w} + var y = []int{0, -(h / 2), -(h / 3), -h} + canvas.Gid(id) + for i := 0; i < len(x); i++ { + defcoord(x[i], y[i], -textsize) + } + canvas.Polyline(x, y, objstyle) + deflegend(w/2, h, 0, legend) + canvas.Gend() +} + +// defpath defines the path object for arbitrary placement and size +func defpath(id string, x, y int, legend string) { + var w3path = `M36,5l12,41l12-41h33v4l-13,21c30,10,2,69-21,28l7-2c15,27,33,-22,3,-19v-4l12-20h-15l-17,59h-1l-13-42l-12,42h-1l-20-67h9l12,41l8-28l-4-13h9` + var cpath = `M94,53c15,32,30,14,35,7l-1-7c-16,26-32,3-34,0M122,16c-10-21-34,0-21,30c-5-30 16,-38 23,-21l5-10l-2-9` + canvas.Gid(id) + canvas.Path(w3path, `fill="`+objcolor+`"`) + canvas.Path(cpath, canvas.RGBA(0, 0, 0, 0.5)) + defcoord(0, 0, -textsize) + deflegend(x/2, y+50, textsize, legend) + canvas.Gend() +} + +// deflg defines the linear gradient object for arbitrary placement and size +func deflg(id string, w int, h int, legend string) { + canvas.Gid(id) + canvas.Rect(0, 0, w, h, "fill:url(#linear)") + defcoordstr(0, 0, "x1%, y1%") + defcoordstr(w, 0, "x2%, y2%") + deflegend((w / 2), 0, h, legend) + canvas.Gend() +} + +// defrg defines the radial gradient object for arbitrary placement and size +func defrg(id string, w int, h int, legend string) { + canvas.Gid(id) + canvas.Rect(0, 0, w, h, "fill:url(#radial)") + defcoordstr(0, 0, "cx%, cy%") + defcoordstr(w/2, h/2, "fx%, fy%") + deflegend((w / 2), 0, h, legend) + canvas.Gend() +} + +// deftrans defines the trans object for arbitrary placement and size +func deftrans(id string, w, h int, legend string) { + tx := w / 3 + canvas.Gid(id) + defcoordstr(0, 0, "0, 0") + defcoordstr(w-tx, 0, "x, y") + deflegend(w/2, 0, h, legend) + canvas.Rect(0, 0, tx, h, objstyle) + canvas.Translate(w-tx, 0) + canvas.Rect(0, 0, tx, h, fobjstyle) + canvas.Gend() + canvas.Gend() +} + +// defgrid defines the grid object for arbitrary placement and size +func defgrid(id string, w, h int, legend string) { + n := h / 4 + canvas.Gid(id) + defcoord(0, 0, -textsize) + canvas.Text(-textsize, (h / 2), "h", legendstyle) + canvas.Text((w / 2), -textsize, "w", legendstyle) + canvas.Text(n+textsize, n/2, "n", legendstyle) + canvas.Grid(0, 0, w, h, n, "stroke:"+objcolor) + deflegend((w / 2), 0, h, legend) + canvas.Gend() +} + +// deftext defines the text object for arbitrary placement and size +func deftext(id string, w, h int, text string, legend string) { + canvas.Gid(id) + defcoord(0, h/2, textsize) + canvas.Text(0, h/2, text, "text-anchor:start;font-size:32pt") + deflegend(w/2, 0, h, legend) + canvas.Gend() +} + +// deftextpath defines the textpath object for arbitrary placement and size +func deftextpath(id string, pathid string, s string, w, h int, legend string) { + canvas.Gid(id) + canvas.Textpath(s, pathid, `fill="`+objcolor+`"`, `text-anchor="start"`, `font-size="16pt"`) + deflegend(w/2, 0, h, legend) + canvas.Gend() +} + +// defscale defines the scale object for arbitrary placement and size +func defscale(id string, w, h int, n float64, legend string) { + canvas.Gid(id) + defcoordstr(0, 0, "0, 0") + canvas.Rect(0, 0, w, h, objstyle) + canvas.Scale(n) + canvas.Rect(0, 0, w, h, fobjstyle) + canvas.Gend() + deflegend(w/2, 0, h, legend) + canvas.Gend() +} + +// defscaleXY defines the scaleXY object for arbitrary placement and size +func defscaleXY(id string, w, h int, dx, dy float64, legend string) { + canvas.Gid(id) + defcoordstr(0, 0, "0, 0") + canvas.Rect(0, 0, w, h, objstyle) + canvas.ScaleXY(dx, dy) + canvas.Rect(0, 0, w, h, fobjstyle) + canvas.Gend() + deflegend(w/2, 0, h, legend) + canvas.Gend() +} + +// defskewX defines the skewX object for arbitrary placement and size +func defskewX(id string, w, h int, angle float64, legend string) { + canvas.Gid(id) + defcoordstr(0, 0, "0, 0") + canvas.Rect(0, 0, w, h, objstyle) + canvas.SkewX(angle) + canvas.Rect(0, 0, w, h, fobjstyle) + canvas.Gend() + deflegend(w/2, 0, h, legend) + canvas.Gend() +} + +// defskewY defines the skewY object for arbitrary placement and size +func defskewY(id string, w, h int, angle float64, legend string) { + canvas.Gid(id) + defcoordstr(0, 0, "0, 0") + canvas.Rect(0, 0, w, h, objstyle) + canvas.SkewY(angle) + canvas.Rect(0, 0, w, h, fobjstyle) + canvas.Gend() + deflegend(w/2, 0, h, legend) + canvas.Gend() +} + +// defskewXY defines the skewXY object for arbitrary placement and size +func defskewXY(id string, w, h int, ax, ay float64, legend string) { + canvas.Gid(id) + defcoordstr(0, 0, "0, 0") + canvas.Rect(0, 0, w, h, objstyle) + canvas.SkewXY(ax, ay) + canvas.Rect(0, 0, w, h, fobjstyle) + canvas.Gend() + deflegend(w/2, 0, h, legend) + canvas.Gend() +} + +// defrotate defines the rotate object for arbitrary placement and size +func defrotate(id string, w, h int, deg float64, legend string) { + t := deg * (math.Pi / 180.0) + r := float64(w / 2) + rx := r * math.Cos(t) + ry := r * math.Sin(t) + canvas.Gid(id) + defcoordstr(0, 0, "0, 0") + deflegend(w/2, 0, h, legend) + canvas.Rect(0, 0, w, h, objstyle) + canvas.Qbez(w/2, 0, (w/2)+10, int(ry)/2, int(rx), int(ry), "fill:none;stroke:gray") + canvas.Text(w/4, textsize, "r", legendstyle) + canvas.Rotate(deg) + canvas.Rect(0, 0, w, h, fobjstyle) + canvas.Gend() + canvas.Gend() +} + +// defmeta defines the metadata objects +func defmeta(id string, w int, name, desc []string, legend string) { + canvas.Gid(id) + canvas.Textlines(0, textsize, name, 24, 28, "black", "start") + canvas.Textlines(w+150, textsize, desc, 24, 28, "rgb(127,127,127)", "start") + deflegend(w, 0, 30*len(name), legend) + canvas.Gend() +} + +// defrgb defines the rgb object for arbitrary placement and size +func defrgb(id string, w, h, r, g, b int, opacity float64, legend string) { + size := h / 8 + canvas.Gid(id) + canvas.Gstyle(legendstyle) + colordot(w/4, 0, size, r, 0, 0, 1.0) + colordot(w/2, 0, size, 0, g, 0, 1.0) + colordot(w*3/4, 0, size, 0, 0, b, 1.0) + colordot(w, 0, size, r, g, b, opacity) + if opacity < 1.0 { + colordot(w+10, 0, size, r, g, b, opacity) + canvas.Text(w, h/2, "alpha") + } + canvas.Text(w/4, h/2, "r") + canvas.Text(w/2, h/2, "g") + canvas.Text(w*3/4, h/2, "b") + canvas.Text(w-(w/8), size-size/2, "->") + canvas.Gend() + deflegend(w/2, 0, h, legend) + canvas.Gend() +} + +// defobjects defines a set of objects with the specified dimensions, +// once defined, the objects are referenced for placement +func defobjects(w, h int) { + var ( + metatext = []string{ + "New(w io Writer)", + "Start(w, h int, options ...string)/End()", + "Startview(w, h, minx, miny, vw, vh int)", + "Group(s ...string)/Gend()", + "Gstyle(s string)/Gend()", + "Gtransform(s string)/Gend()", + "Gid(id string)/Gend()", + "ClipPath(s ...string)/ClipEnd()", + "Def()/DefEnd()", + "Marker()/MarkerEnd()", + "Pattern()/PatternEnd()", + "Desc(s string)", + "Title(s string)", + "Script(type, data ...string)", + "Mask(id string, x,y,w,h int, style ...string)/MaskEnd()", + "Link(href string, title string)/LinkEnd()", + "Use(x int, y int, link string, style ...string)", + } + metadesc = []string{ + "specify destination", + "begin/end the document", + "begin/end the document with viewport", + "begin/end group with attributes", + "begin/end group style", + "begin/end group transform", + "begin/end group id", + "begin/end clip path", + "begin/end a defintion block", + "begin/end markers", + "begin/end pattern", + "set the description element", + "set the title element", + "define a script", + "begin/end mask element", + "begin/end link to href, with a title", + "use defined objects", + } + ) + h2 := h / 2 + canvas.Desc("Object Definitions") + canvas.Def() + canvas.LinearGradient("linear", 0, 0, 100, 0, ga) + canvas.RadialGradient("radial", 0, 0, 100, 50, 50, ga) + canvas.Path("M 0,0 A62,62 0 0 1 250,0", `id="tpath"`) + defsquare("square", h, "Square(x, y, w int, style ...string)") + defrect("rect", w, h, "Rect(x, y, w, h int, style ...string)") + defcrect("crect", w, h, "CenterRect(x, y, w, h int, style ...string)") + defroundrect("roundrect", w, h, 25, 25, "Roundrect(x, y, w, h, rx, ry int, style ...string)") + defpolygon("polygon", w, h, "Polygon(x, y []int, style ...string)") + defcircle("circle", h, h2, "Circle(x, y, r int, style ...string)") + defellipse("ellipse", h, h2, "Ellipse(x, y, rx, ry int, style ...string)") + defline("line", w, h, "Line(x1, y1, x2, y2 int, style ...string)") + defpolyline("polyline", w, h, "Polyline(x, y []int, style ...string)") + defarc("arc", h, h2, "Arc(sx, sy, ax, ay, r int, lflag, sflag bool, ex, ey int, style ...string)") + defpath("path", h, h2, "Path(s string, style ...string)") + defqbez("qbez", h, h2, h, "Qbez(sx, sy, cx, cy, ex, ey int, style ...string)") + defbez("bezier", h, h2, h, "Bezier(sx, sy, cx, cy, px, py, ex, ey int, style ...string)") + defimage("image", 128, 128, "gophercolor128x128.png", "Image(x, y, w, h, int path string, style ...string)") + deflg("lgrad", w, h, "LinearGradient(s string, x1, y1, x2, y2 uint8, oc []Offcolor)") + defrg("rgrad", w, h, "RadialGradient(s string, cx, cy, r, fx, fy uint8, oc []Offcolor)") + deftrans("trans", w, h, "Translate(x, y int)") + defgrid("grid", w, h, "Grid(x, y, w, h, n int, style ...string)") + deftext("text", w, h, "hello, this is SVG", "Text(x, y int, s string, style ...string)") + defscale("scale", w, h, 0.5, "Scale(n float64)") + defscaleXY("scalexy", w, h, 0.5, 0.75, "ScaleXY(x, y float64)") + defskewX("skewx", w, h, 30, "SkewX(a float64)") + defskewY("skewy", w, h, 10, "SkewY(a float64)") + defskewXY("skewxy", w, h, 10, 10, "SkewXY(x, y float64)") + defrotate("rotate", w, h, 30, "Rotate(r float64)") + deftextpath("textpath", "#tpath", tpathstring, w, h, "Textpath(s, pathid string, style ...string)") + defmeta("meta", w*2, metatext, metadesc, "Textlines(x, y int, s []string, size, spacing int, fill, align string)") + defrgb("rgb", w, h, 44, 77, 232, 1.0, "RGB(r, g, b int)") + defrgb("rgba", w, h, 44, 77, 232, 0.33, "RGBA(r, g, b int, opacity float64)") + canvas.DefEnd() +} + +// colordot makes a colored dot, with opacity +func colordot(x, y, r, red, green, blue int, a float64) { + // canvas.Circle(x,y,r+textsize/6,"fill:none;stroke:"+objcolor) + if a == 1.0 { + canvas.Circle(x, y, r, canvas.RGB(red, green, blue)) + } else { + canvas.Circle(x, y, r, canvas.RGBA(red, green, blue, a)) + } +} + +// placerow is a helper for placeobjects, placing to previously +// defined objects row-wise +func placerow(w int, s []string) { + for x, name := range s { + canvas.Use(x*w, 0, "#"+name) + } +} + +// placeobjects places a grid of objects on the canvas as specified +// by a string array. +func placeobjects(x, y, w, h int, data [][]string) { + canvas.Desc("Object Usage") + for _, object := range data { + canvas.Translate(x, y) + placerow(w, object) + canvas.Gend() + y += h + } +} + +var roworder = [][]string{ + {"rect", "crect", "roundrect", "square", "line", "polyline"}, + {"polygon", "circle", "ellipse", "arc", "qbez", "bezier"}, + {"trans", "scale", "scalexy", "skewx", "skewy", "skewxy"}, + {"rotate", "text", "textpath", "path", "image", "grid"}, + {"lgrad", "rgrad", "rgb", "rgba", "meta"}, +} + +func main() { + width := 4500 + height := (width * 3) / 4 + canvas.Start(width, height) + defobjects(250, 125) + canvas.Title("SVG Go Library Description") + canvas.Rect(0, 0, width, height, "fill:white;stroke:black;stroke-width:2") + canvas.Gstyle(gtextstyle) + canvas.Link("http://github.com/ajstarks/svgo", "SVGo Library") + canvas.Text(width/2, 150, "SVG Go Library", "font-size:125px") + canvas.Text(width/2, 200, "github.com/ajstarks/svgo", "font-size:50px;fill:gray") + canvas.LinkEnd() + placeobjects(400, 400, 700, 600, roworder) + canvas.Gend() + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/svgopher/svgopher.go b/vendor/github.com/ajstarks/svgo/svgopher/svgopher.go new file mode 100644 index 0000000..084781c --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/svgopher/svgopher.go @@ -0,0 +1,76 @@ +// svgopher - Go mascot remix +// +build !appengine + +package main + +import ( + "os" + + "github.com/ajstarks/svgo" +) + +var ( + width = 500 + height = 300 + canvas = svg.New(os.Stdout) +) + +func background(v int) { canvas.Rect(0, 0, width, height, canvas.RGB(v, v, v)) } + +func gordon(x, y, w, h int) { + + w10 := w / 10 + w12 := w / 12 + w2 := w / 2 + w3 := w / 3 + w8 := w / 8 + w6 := w / 6 + xw := x + w + h23 := (h * 2) / 3 + + blf := "fill:black" + wf := "fill:white" + nf := "fill:brown" + brf := "fill:brown; fill-opacity:0.2" + brb := "fill:rgb(210,161,161)" + + canvas.Gstyle("fill:none; stroke:none") + canvas.Bezier(x, y+h, x, y+h, x+w2, y-h, x+w, y+h, brb) + canvas.Roundrect(x, y+(h-1), w, h, 10, 10, brb) + canvas.Circle(x, y+h, w12, brf) // left ear + canvas.Circle(x, y+h, w12-10, nf) + + canvas.Circle(x+w, y+h, w12, brf) // right ear + canvas.Circle(x+w, y+h, w12-10, nf) + + canvas.Circle(x+w3, y+h23, w/9, wf) // left eye + canvas.Circle(x+w3+10, y+h23, w10-10, blf) + canvas.Circle(x+w3+15, y+h23, 5, wf) + + canvas.Circle(xw-w3, y+h23, w/9, wf) // right eye + canvas.Circle(xw-w3+10, y+h23, w10-10, blf) + canvas.Circle(xw-(w3)+15, y+h23, 5, wf) + + canvas.Roundrect(x+w2-w8, y+h+30, w8, w6, 5, 5, wf) // left tooth + canvas.Roundrect(x+w2, y+h+30, w8, w6, 5, 5, wf) // right tooth + + canvas.Ellipse(x+(w2), y+h+30, w6, w12, nf) // snout + canvas.Ellipse(x+(w2), y+h+10, w10, w12, blf) // nose + + canvas.Gend() +} + +func main() { + canvas.Start(width, height) + canvas.Title("SVG Gopher") + background(255) + canvas.Gtransform("translate(100, 100)") + canvas.Gtransform("rotate(-30)") + gordon(48, 48, 240, 72) + canvas.Gend() + canvas.Gend() + canvas.Link("svgdef.svg", "SVG Spec & Usage") + canvas.Text(90, 145, "SVG", "font-family:Calibri,sans-serif;font-size:80;fill:brown") + canvas.LinkEnd() + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/svgplay/svgplay.go b/vendor/github.com/ajstarks/svgo/svgplay/svgplay.go new file mode 100644 index 0000000..8b6f844 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/svgplay/svgplay.go @@ -0,0 +1,291 @@ +// svgplay: sketch with SVGo, (derived from the old misc/goplay), except: +// (1) only listen on localhost, (default port 1999) +// (2) always render html, +// (3) SVGo default code, +package main + +import ( + "bytes" + "flag" + "io/ioutil" + "log" + "net/http" + "os" + "os/exec" + "path/filepath" + "strconv" + "text/template" +) + +var ( + httpListen = flag.String("port", "1999", "port to listen on") +) + +var ( + // a source of numbers, for naming temporary files + uniq = make(chan int) +) + +func main() { + flag.Parse() + + // source of unique numbers + go func() { + for i := 0; ; i++ { + uniq <- i + } + }() + + http.HandleFunc("/", FrontPage) + http.HandleFunc("/compile", Compile) + log.Printf("☠ ☠ ☠ Warning: this server allows a client connecting to 127.0.0.1:%s to execute code on this computer ☠ ☠ ☠", *httpListen) + log.Fatal(http.ListenAndServe("127.0.0.1:"+*httpListen, nil)) +} + +// FrontPage is an HTTP handler that renders the svgoplay interface. +// If a filename is supplied in the path component of the URI, +// its contents will be put in the interface's text area. +// Otherwise, the default "hello, world" program is displayed. +func FrontPage(w http.ResponseWriter, req *http.Request) { + data, err := ioutil.ReadFile(req.URL.Path[1:]) + if err != nil { + data = helloWorld + } + frontPage.Execute(w, data) +} + +// Compile is an HTTP handler that reads Go source code from the request, +// runs the program (returning any errors), +// and sends the program's output as the HTTP response. +func Compile(w http.ResponseWriter, req *http.Request) { + out, err := compile(req) + if err != nil { + compileError(w, out, err) + return + } + + // write the output of target as the http response + w.Write(out) +} + +var ( + tmpdir, pkgdir, buildpid string +) + +func init() { + // find real temporary directory (for rewriting filename in output) + var err error + tmpdir, err = filepath.EvalSymlinks(os.TempDir()) + if err != nil { + log.Fatal(err) + } + + buildpid = strconv.Itoa(os.Getpid()) +} + +func compile(req *http.Request) (out []byte, err error) { + // target is the base name for .go, object, executable files + target := filepath.Join(tmpdir, "svgplay"+buildpid+strconv.Itoa(<-uniq)) + src := target + ".go" + + // write body to target.go + body := new(bytes.Buffer) + if _, err = body.ReadFrom(req.Body); err != nil { + return + } + defer os.Remove(src) + if err = ioutil.WriteFile(src, body.Bytes(), 0666); err != nil { + return + } + return run("", "go", "run", src) +} + +// error writes compile, link, or runtime errors to the HTTP connection. +// The JavaScript interface uses the 404 status code to identify the error. +func compileError(w http.ResponseWriter, out []byte, err error) { + w.WriteHeader(404) + if out != nil { + elines := bytes.Split(out, []byte{'\n'}) + for _, l := range elines { + i := bytes.Index(l, []byte{':'}) + output.Execute(w, l[i+1:]) + } + } else { + output.Execute(w, err.Error()) + } +} + +// run executes the specified command and returns its output and an error. +func run(dir string, args ...string) ([]byte, error) { + var buf bytes.Buffer + cmd := exec.Command(args[0], args[1:]...) + cmd.Dir = dir + cmd.Stdout = &buf + cmd.Stderr = cmd.Stdout + err := cmd.Run() + return buf.Bytes(), err +} + +var frontPage = template.Must(template.New("frontPage").Parse(frontPageText)) // HTML template +var output = template.Must(template.New("output").Parse(outputText)) // HTML template + +var outputText = `

    {{printf "%s" . |html}}
    ` + +var frontPageText = ` + + +svgplay: SVGo sketching + + + + +
    + +
    +(Shift-Enter to compile and run.)     + Compile and run after each keystroke +
    +
    + +
    +
    +
    + + +` + +var helloWorld = []byte(`package main + +import ( + "math/rand" + "os" + "time" + "github.com/ajstarks/svgo" +) + +func ri(n int) int { return rand.Intn(n) } + +func main() { + canvas := svg.New(os.Stdout) + width := 500 + height := 500 + nstars := 250 + style := "font-size:48pt;fill:white;text-anchor:middle" + + rand.Seed(time.Now().Unix()) + canvas.Start(width, height) + canvas.Rect(0,0,width,height) + for i := 0; i < nstars; i++ { + canvas.Circle(ri(width), ri(height), ri(3), "fill:white") + } + canvas.Circle(width/2, height, width/2, "fill:rgb(77, 117, 232)") + canvas.Text(width/2, height*4/5, "hello, world", style) + canvas.End() +}`) diff --git a/vendor/github.com/ajstarks/svgo/svgplot/mksvgplotdef b/vendor/github.com/ajstarks/svgo/svgplot/mksvgplotdef new file mode 100644 index 0000000..e1dbc94 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/svgplot/mksvgplotdef @@ -0,0 +1,24 @@ +#!/bin/sh +rm f??*.svg +gopts="-bx=50 -by=20 -width=460 -height=130 -pw=400 -ph=90 -barsize=3 -fontsize=11" +data="test.d" +# opt +svgplot $gopts -showbg -connect=f -label=showbg $data > f00.svg +svgplot $gopts -connect -label=connect $data > f01.svg +svgplot $gopts -showbar -connect=f -label=showbar $data > f02.svg +svgplot $gopts -area -connect=f -label=area $data > f03.svg +svgplot $gopts -showdot -connect=f -label=showdot $data > f04.svg +svgplot $gopts -showx -label=showx $data > f05.svg +svgplot $gopts -showy -label=showy $data > f06.svg +svgplot $gopts -showfile -label=showfile $data > f07.svg +# attr +svgplot $gopts -bgcolor=lightsteelblue -label=bgcolor $data > f08.svg +svgplot $gopts -linecolor=red -label=linecolor $data > f09.svg +svgplot $gopts -barcolor=red -showbar -connect=f -label=barcolor $data > f10.svg +svgplot $gopts -areacolor=red -area -connect=f -label=hcolor $data > f11.svg +svgplot $gopts -showdot -dotcolor=red -connect=f -label=dotcolor $data > f12.svg +svgplot $gopts -label=labelcolor -labelcolor=red $data > f13.svg +svgplot $gopts -label=fontsize $data > f14.svg +svgplot $gopts -font=Courier -label="font" $data > f15.svg +svgrid -h 1200 -w 1024 -r=f -x=50 -y=50 -g 10 -c 8 f??.svg > svgplotdef.svg + diff --git a/vendor/github.com/ajstarks/svgo/svgplot/svgplot.go b/vendor/github.com/ajstarks/svgo/svgplot/svgplot.go new file mode 100644 index 0000000..06f54a3 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/svgplot/svgplot.go @@ -0,0 +1,314 @@ +//svgplot -- plot data (a stream of x,y coordinates) +// +build !appengine + +package main + +import ( + "flag" + "fmt" + "io" + "math" + "os" + + "github.com/ajstarks/svgo" +) + +// rawdata defines data as float64 x,y coordinates +type rawdata struct { + x float64 + y float64 +} + +type options map[string]bool +type attributes map[string]string +type measures map[string]int + +// plotset defines plot metadata +type plotset struct { + opt options + attr attributes + size measures +} + +var ( + canvas = svg.New(os.Stdout) + plotopt = options{} + plotattr = attributes{} + plotnum = measures{} + ps = plotset{plotopt, plotattr, plotnum} + plotw, ploth, plotc, gwidth, gheight, gutter, beginx, beginy int +) + +const ( + globalfmt = "font-family:%s;font-size:%dpt;stroke-width:%dpx" + linestyle = "fill:none;stroke:" + linefmt = "fill:none;stroke:%s" + barfmt = linefmt + ";stroke-width:%dpx" + ticfmt = "stroke:rgb(200,200,200);stroke-width:1px" + labelfmt = ticfmt + ";text-anchor:end;fill:black" + textfmt = "stroke:none;baseline-shift:-33.3%" + smallint = -(1 << 30) +) + +// init initializes command flags and sets default options +func init() { + + // boolean options + showx := flag.Bool("showx", false, "show the xaxis") + showy := flag.Bool("showy", false, "show the yaxis") + showbar := flag.Bool("showbar", false, "show data bars") + area := flag.Bool("area", false, "area chart") + connect := flag.Bool("connect", true, "connect data points") + showdot := flag.Bool("showdot", false, "show dots") + showbg := flag.Bool("showbg", true, "show the background color") + showfile := flag.Bool("showfile", false, "show the filename") + sameplot := flag.Bool("sameplot", false, "plot on the same frame") + + // attributes + bgcolor := flag.String("bgcolor", "rgb(240,240,240)", "plot background color") + barcolor := flag.String("barcolor", "gray", "bar color") + dotcolor := flag.String("dotcolor", "black", "dot color") + linecolor := flag.String("linecolor", "gray", "line color") + areacolor := flag.String("areacolor", "gray", "area color") + font := flag.String("font", "Calibri,sans", "font") + labelcolor := flag.String("labelcolor", "black", "label color") + plotlabel := flag.String("label", "", "plot label") + + // sizes + dotsize := flag.Int("dotsize", 2, "dot size") + linesize := flag.Int("linesize", 2, "line size") + barsize := flag.Int("barsize", 2, "bar size") + fontsize := flag.Int("fontsize", 11, "font size") + xinterval := flag.Int("xint", 10, "x axis interval") + yinterval := flag.Int("yint", 4, "y axis interval") + ymin := flag.Int("ymin", smallint, "y minimum") + ymax := flag.Int("ymax", smallint, "y maximum") + + // meta options + flag.IntVar(&beginx, "bx", 100, "initial x") + flag.IntVar(&beginy, "by", 50, "initial y") + flag.IntVar(&plotw, "pw", 500, "plot width") + flag.IntVar(&ploth, "ph", 500, "plot height") + flag.IntVar(&plotc, "pc", 2, "plot columns") + flag.IntVar(&gutter, "gutter", ploth/10, "gutter") + flag.IntVar(&gwidth, "width", 1024, "canvas width") + flag.IntVar(&gheight, "height", 768, "canvas height") + + flag.Parse() + + // fill in the plotset -- all options, attributes, and sizes + plotopt["showx"] = *showx + plotopt["showy"] = *showy + plotopt["showbar"] = *showbar + plotopt["area"] = *area + plotopt["connect"] = *connect + plotopt["showdot"] = *showdot + plotopt["showbg"] = *showbg + plotopt["showfile"] = *showfile + plotopt["sameplot"] = *sameplot + + plotattr["bgcolor"] = *bgcolor + plotattr["barcolor"] = *barcolor + plotattr["linecolor"] = *linecolor + plotattr["dotcolor"] = *dotcolor + plotattr["areacolor"] = *areacolor + plotattr["font"] = *font + plotattr["label"] = *plotlabel + plotattr["labelcolor"] = *labelcolor + + plotnum["dotsize"] = *dotsize + plotnum["linesize"] = *linesize + plotnum["fontsize"] = *fontsize + plotnum["xinterval"] = *xinterval + plotnum["yinterval"] = *yinterval + plotnum["barsize"] = *barsize + plotnum["ymin"] = *ymin + plotnum["ymax"] = *ymax +} + +// fmap maps world data to document coordinates +func fmap(value float64, low1 float64, high1 float64, low2 float64, high2 float64) float64 { + return low2 + (high2-low2)*(value-low1)/(high1-low1) +} + +// doplot opens a file and makes a plot +func doplot(x, y int, location string) { + var f *os.File + var err error + if len(location) > 0 { + if plotopt["showfile"] { + plotattr["label"] = location + } + f, err = os.Open(location) + } else { + f = os.Stdin + } + if err != nil { + fmt.Fprintf(os.Stderr, "%v\n", err) + return + } + nd, data := readxy(f) + f.Close() + + if nd >= 2 { + plot(x, y, plotw, ploth, ps, data) + } +} + +// plot places a plot at the specified location with the specified dimemsions +// usinng the specified settings, using the specified data +func plot(x, y, w, h int, settings plotset, d []rawdata) { + nd := len(d) + if nd < 2 { + fmt.Fprintf(os.Stderr, "%d is not enough points to plot\n", len(d)) + return + } + // Compute the minima and maxima + maxx, minx := d[0].x, d[0].x + maxy, miny := d[0].y, d[0].y + for _, v := range d { + + if v.x > maxx { + maxx = v.x + } + if v.y > maxy { + maxy = v.y + } + if v.x < minx { + minx = v.x + } + if v.y < miny { + miny = v.y + } + } + + if settings.size["ymin"] != smallint { + miny = float64(settings.size["ymin"]) + } + if settings.size["ymax"] != smallint { + maxy = float64(settings.size["ymax"]) + } + // Prepare for a area or line chart by allocating + // polygon coordinates; for the hrizon plot, you need two extra coordinates + // for the extrema. + needpoly := settings.opt["area"] || settings.opt["connect"] + var xpoly, ypoly []int + if needpoly { + xpoly = make([]int, nd+2) + ypoly = make([]int, nd+2) + // preload the extrema of the polygon, + // the bottom left and bottom right of the plot's rectangle + xpoly[0] = x + ypoly[0] = y + h + xpoly[nd+1] = x + w + ypoly[nd+1] = y + h + } + // Draw the plot's bounding rectangle + if settings.opt["showbg"] && !settings.opt["sameplot"] { + canvas.Rect(x, y, w, h, "fill:"+settings.attr["bgcolor"]) + } + // Loop through the data, drawing items as specified + spacer := 10 + canvas.Gstyle(fmt.Sprintf(globalfmt, + settings.attr["font"], settings.size["fontsize"], settings.size["linesize"])) + + for i, v := range d { + xp := int(fmap(v.x, minx, maxx, float64(x), float64(x+w))) + yp := int(fmap(v.y, miny, maxy, float64(y), float64(y-h))) + + if needpoly { + xpoly[i+1] = xp + ypoly[i+1] = yp + h + } + if settings.opt["showbar"] { + canvas.Line(xp, yp+h, xp, y+h, + fmt.Sprintf(barfmt, settings.attr["barcolor"], settings.size["barsize"])) + } + if settings.opt["showdot"] { + canvas.Circle(xp, yp+h, settings.size["dotsize"], "fill:"+settings.attr["dotcolor"]) + } + if settings.opt["showx"] { + if i%settings.size["xinterval"] == 0 { + canvas.Text(xp, (y+h)+(spacer*2), fmt.Sprintf("%d", int(v.x)), "text-anchor:middle") + canvas.Line(xp, (y + h), xp, (y+h)+spacer, ticfmt) + } + } + } + // Done constructing the points for the area or line plots, display them in one shot + if settings.opt["area"] { + canvas.Polygon(xpoly, ypoly, "fill:"+settings.attr["areacolor"]) + } + + if settings.opt["connect"] { + canvas.Polyline(xpoly[1:nd+1], ypoly[1:nd+1], linestyle+settings.attr["linecolor"]) + } + // Put on the y axis labels, if specified + if settings.opt["showy"] { + bot := math.Floor(miny) + top := math.Ceil(maxy) + yrange := top - bot + interval := yrange / float64(settings.size["yinterval"]) + canvas.Gstyle(labelfmt) + for yax := bot; yax <= top; yax += interval { + yaxp := fmap(yax, bot, top, float64(y), float64(y-h)) + canvas.Text(x-spacer, int(yaxp)+h, fmt.Sprintf("%.1f", yax), textfmt) + canvas.Line(x-spacer, int(yaxp)+h, x, int(yaxp)+h) + } + canvas.Gend() + } + // Finally, tack on the label, if specified + if len(settings.attr["label"]) > 0 { + canvas.Text(x, y+spacer, settings.attr["label"], "font-size:120%;fill:"+settings.attr["labelcolor"]) + } + + canvas.Gend() +} + +// readxy reads coordinates (x,y float64 values) from a io.Reader +func readxy(f io.Reader) (int, []rawdata) { + var ( + r rawdata + err error + n, nf int + ) + data := make([]rawdata, 1) + for ; err == nil; n++ { + if n > 0 { + data = append(data, r) + } + nf, err = fmt.Fscan(f, &data[n].x, &data[n].y) + if nf != 2 { + continue + } + } + return n - 1, data[0 : n-1] +} + +// plotgrid places plots on a grid, governed by a number of columns. +func plotgrid(x, y int, files []string) { + px := x + for i, f := range files { + if i > 0 && i%plotc == 0 && !plotopt["sameplot"] { + px = x + y += (ploth + gutter) + } + doplot(px, y, f) + if !plotopt["sameplot"] { + px += (plotw + gutter) + } + } +} + +// main plots data from specified files or standard input in a +// grid where plotc specifies the number of columns. +func main() { + canvas.Start(gwidth, gheight) + canvas.Rect(0, 0, gwidth, gheight, "fill:white") + filenames := flag.Args() + if len(filenames) == 0 { + doplot(beginx, beginy, "") + } else { + plotgrid(beginx, beginy, filenames) + } + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/svgplot/test.d b/vendor/github.com/ajstarks/svgo/svgplot/test.d new file mode 100644 index 0000000..e79c144 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/svgplot/test.d @@ -0,0 +1,51 @@ +0 493.65 +1 497.57 +2 506.38 +3 521.03 +4 532.44 +5 535.36 +6 546.60 +7 531.99 +8 527.28 +9 534.01 +10 538.26 +11 528.94 +12 597.62 +13 594.94 +14 602.55 +15 595.35 +16 606.99 +17 618.23 +18 618.98 +19 622.52 +20 607.22 +21 610.94 +22 603.69 +23 606.77 +24 592.40 +25 601.17 +26 577.52 +27 579.04 +28 546.02 +29 573.41 +30 549.01 +31 562.13 +32 563.77 +33 557.23 +34 539.00 +35 533.15 +36 504.88 +37 490.92 +38 498.17 +39 518.82 +40 523.29 +41 520.04 +42 526.86 +43 539.08 +44 540.70 +45 540.96 +46 532.50 +47 524.84 +48 522.18 +49 534.03 +50 534.96 diff --git a/vendor/github.com/ajstarks/svgo/svgrid/svgrid.go b/vendor/github.com/ajstarks/svgo/svgrid/svgrid.go new file mode 100644 index 0000000..4d36b0e --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/svgrid/svgrid.go @@ -0,0 +1,107 @@ +// svgrid -- composite SVG files in a grid +// +build !appengine + +package main + +import ( + "encoding/xml" + "flag" + "fmt" + "io" + "os" + + "github.com/ajstarks/svgo" +) + +// SVG is a SVG document +type SVG struct { + Width string `xml:"width,attr"` + Height string `xml:"height,attr"` + Doc string `xml:",innerxml"` +} + +var ( + byrow bool + startx, starty, count, gutter, gwidth, gheight int + canvas = svg.New(os.Stdout) +) + +// init sets up command line options +func init() { + flag.BoolVar(&byrow, "r", true, "order row wise") + flag.IntVar(&startx, "x", 0, "begin x") + flag.IntVar(&starty, "y", 0, "begin y") + flag.IntVar(&count, "c", 3, "columns or rows") + flag.IntVar(&gutter, "g", 100, "gutter") + flag.IntVar(&gwidth, "w", 1024, "width") + flag.IntVar(&gheight, "h", 768, "height") + flag.Parse() +} + +// placepic puts a SVG file at a location +func placepic(x, y int, filename string) (int, int) { + var ( + s SVG + width, height int + wunit, hunit string + ) + f, err := os.Open(filename) + if err != nil { + fmt.Fprintf(os.Stderr, "%v\n", err) + return 0, 0 + } + defer f.Close() + if err := xml.NewDecoder(f).Decode(&s); err != nil { + fmt.Fprintf(os.Stderr, "Unable to parse (%v)\n", err) + return 0, 0 + } + + // read the width and height, including any units + // if there are errors use 10 as a default + nw, _ := fmt.Sscanf(s.Width, "%d%s", &width, &wunit) + if nw < 1 { + width = 10 + } + nh, _ := fmt.Sscanf(s.Height, "%d%s", &height, &hunit) + if nh < 1 { + height = 10 + } + canvas.Group(`clip-path="url(#pic)"`, fmt.Sprintf(`transform="translate(%d,%d)"`, x, y)) + canvas.ClipPath(`id="pic"`) + canvas.Rect(0, 0, width, height) + canvas.ClipEnd() + io.WriteString(canvas.Writer, s.Doc) + canvas.Gend() + return width, height +} + +// compose places files row or column-wise +func compose(x, y, n int, rflag bool, files []string) { + px := x + py := y + var pw, ph int + for i, f := range files { + if i > 0 && i%n == 0 { + if rflag { + px = x + py += gutter + ph + } else { + px += gutter + pw + py = y + } + } + pw, ph = placepic(px, py, f) + if rflag { + px += gutter + pw + } else { + py += gutter + ph + } + } +} + +// main lays out files as specified on the command line +func main() { + canvas.Start(gwidth, gheight) + compose(startx, starty, count, byrow, flag.Args()) + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/tsg/tsg.go b/vendor/github.com/ajstarks/svgo/tsg/tsg.go new file mode 100644 index 0000000..8605392 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/tsg/tsg.go @@ -0,0 +1,126 @@ +// tsg -- twitter search grid +// +build !appengine + +package main + +import ( + "encoding/xml" + "flag" + "fmt" + "io" + "net/http" + "net/url" + "os" + + "github.com/ajstarks/svgo" +) + +var canvas = svg.New(os.Stdout) + +// Feed is the Atom feed structure +type Feed struct { + XMLName xml.Name `xml:"http://www.w3.org/2005/Atom feed"` + Entry []Entry `xml:"entry"` +} + +// Entry defines an entry within an Aton feed +type Entry struct { + Link []Link `xml:"link"` + Title string `xml:"title"` + Author Person `xml:"author"` +} + +// Link defines a link within an Atom feed +type Link struct { + Rel string `xml:"rel,attr"` + Href string `xml:"href,attr"` +} + +// Person defines a person responsible for the tweet +type Person struct { + Name string `xml:"name"` +} + +// Text defines the text of the tweet +type Text struct { + Type string `xml:",attr"` + Body string `xml:",chardata"` +} + +var ( + nresults = flag.Int("n", 100, "Maximum results (up to 100)") + since = flag.String("d", "", "Search since this date (YYYY-MM-DD)") +) + +const ( + queryURI = "http://search.twitter.com/search.atom?q=%s&since=%s&rpp=%d" + textfmt = "font-family:Calibri,Lucida,sans;fill:gray;text-anchor:middle;font-size:48px" + imw = 48 + imh = 48 +) + +// ts dereferences the twitter search URL and reads the XML (Atom) response +func ts(s string, date string, n int) { + + r, err := http.Get(fmt.Sprintf(queryURI, url.QueryEscape(s), date, n)) + if err != nil { + fmt.Fprintf(os.Stderr, "%v\n", err) + return + } + if r.StatusCode == http.StatusOK { + readatom(r.Body) + } else { + fmt.Fprintf(os.Stderr, + "Twitter is unable to search for %s (%s)\n", s, r.Status) + } + r.Body.Close() +} + +// readatom unmarshals the twitter search response and formats the results into a grid +func readatom(r io.Reader) { + var twitter Feed + err := xml.NewDecoder(r).Decode(&twitter) + if err == nil { + tgrid(twitter, 25, 25, 50, 50, 10) + } else { + fmt.Fprintf(os.Stderr, "Unable to parse the Atom feed (%v)\n", err) + } +} + +// tgrid makes a clickable grid of tweets from the Atom feed +func tgrid(t Feed, x, y, w, h, nc int) { + var slink, imlink string + xp := x + for i, entry := range t.Entry { + for _, link := range entry.Link { + switch link.Rel { + case "alternate": + slink = link.Href + case "image": + imlink = link.Href + } + } + if i%nc == 0 && i > 0 { + xp = x + y += h + } + canvas.Link(slink, slink) + canvas.Image(xp, y, imw, imh, imlink) + canvas.LinkEnd() + xp += w + } +} + +// for every non-flag argument, make a twitter search grid +func main() { + flag.Parse() + width := 550 + height := 700 + canvas.Start(width, height) + for _, s := range flag.Args() { + canvas.Title("Twitter search for " + s) + ts(s, *since, *nresults) + canvas.Text(width/2, height-50, s, textfmt) + } + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/tumblrgrid/tlist b/vendor/github.com/ajstarks/svgo/tumblrgrid/tlist new file mode 100644 index 0000000..c709df1 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/tumblrgrid/tlist @@ -0,0 +1,4 @@ +f0o0od.tumblr.com +ign0ranceisbliiiss.tumblr.com +agilaagira.tumblr.com +geek-art.tumblr.com diff --git a/vendor/github.com/ajstarks/svgo/tumblrgrid/tumblrgrid.go b/vendor/github.com/ajstarks/svgo/tumblrgrid/tumblrgrid.go new file mode 100644 index 0000000..82c20e8 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/tumblrgrid/tumblrgrid.go @@ -0,0 +1,218 @@ +// tumblrgrid: display a flexible grid of pictures from tumblr, filtered by tags +// +build !appengine + +package main + +import ( + "encoding/json" + "flag" + "fmt" + "io" + "io/ioutil" + "net/http" + "os" + + "github.com/ajstarks/svgo" +) + +var ( + localfile, postlink bool + ncols, gutter, thumbwidth, piclimit int + filtertag string +) + +const ( + apiKey = "APIKEY" + apifmt = "http://api.tumblr.com/v2/blog/%s/posts?api_key=%s&type=photo&limit=%d" +) + +// Tumblr is the JSON data descriptions +type Tumblr struct { + Meta meta + Response response +} + +type meta struct { + Msg string + Status int +} + +type response struct { + Blog blog + Posts []posts + Total_posts int +} + +type blog struct { + Name string + Posts int + Title string + Updated int + Description string + Url string +} + +type posts struct { + Photos []photos + Tags []string + Type string + Link_url string + Post_url string +} + +type photos struct { + Alt_sizes []altsizes +} + +type altsizes struct { + Height int + Url string + Width int +} + +// resource gives a ReadCloser given a local file or URL +func resource(name string) (io.ReadCloser, error) { + if len(name) == 0 { + return os.Stdin, nil + } + if localfile { + return os.Open(name) + } + h, err := http.Get(fmt.Sprintf(apifmt, name, apiKey, piclimit)) + return h.Body, err +} + +// grid displays tumblr photos in a flexible grid +func grid(canvas *svg.SVG, location string, x, y, nc, gutter int) { + var ( + t Tumblr + r io.ReadCloser + err error + b []byte + ) + + //get data from the resource, put it into the data structure + if r, err = resource(location); err != nil { + fmt.Fprintln(os.Stderr, err) + return + } + + defer r.Close() + if b, err = ioutil.ReadAll(r); err != nil { + fmt.Fprintf(os.Stderr, "%s %v\n", location, err) + return + } + + if err = json.Unmarshal(b, &t); err != nil { + fmt.Fprintf(os.Stderr, "%s, %v\n", location, err) + return + } + + // create the linked blog title + fontsize := thumbwidth / 3 + title := t.Response.Blog.Title + + if len(title) == 0 { + title = t.Response.Blog.Name + } + canvas.Link(t.Response.Blog.Url, t.Response.Blog.Name) + if nc < 4 { // if the columns are too narrow, rotate the title text 90 degrees + canvas.TranslateRotate(x, y/2, 90) + canvas.Text(fontsize, fontsize, title, "fill:lightgray") + canvas.Gend() + } else { + canvas.Text(x, y/2, title, "fill:lightgray") + } + canvas.LinkEnd() + + // walk through the posts, displaying thumbnails, filtered by tags + np := 0 + xp := x + + for _, posts := range t.Response.Posts { + if np >= piclimit { + break + } + if !intag(filtertag, posts.Tags) { + continue + } + for _, photos := range posts.Photos { + for i, p := range photos.Alt_sizes { + if i == 0 { // link to the first image in the list + if postlink { + canvas.Link(posts.Post_url, "Photo") + } else { + canvas.Link(p.Url, "Photo") + } + } + if p.Width == thumbwidth { + np++ + canvas.Image(xp, y, p.Width, p.Width, p.Url) + xp += p.Width + gutter + if np%nc == 0 { + xp = x + y += p.Width + gutter + } + } + } + canvas.LinkEnd() + } + } +} + +// intag searches for tags in list +func intag(tag string, list []string) bool { + if len(tag) == 0 { + return true + } + for _, s := range list { + if s == tag { + return true + } + } + return false +} + +// init sets up command flags +func init() { + flag.BoolVar(&localfile, "f", false, "read from local files") + flag.BoolVar(&postlink, "p", false, "link to original post") + flag.IntVar(&ncols, "nc", 5, "number of columns") + flag.IntVar(&gutter, "g", 5, "gutter (pixels)") + flag.IntVar(&thumbwidth, "tw", 75, "thumbnail width") + flag.IntVar(&piclimit, "n", 30, "picture limit") + flag.StringVar(&filtertag, "tag", "", "filter tag") + flag.Parse() +} + +func main() { + + np := len(flag.Args()) + if np == 0 { + np = 1 + } + + thalf := thumbwidth / 2 + x := thalf + y := 50 + nrows := piclimit / ncols + colincr := (ncols * thumbwidth) + (ncols * gutter) + thalf + width := (colincr * np) + thalf + height := (thumbwidth * nrows) + (nrows * gutter) + y + thalf + gstyle := "font-family:Calibri,sans-serif;font-size:18px" + + canvas := svg.New(os.Stdout) + canvas.Start(width, height) + canvas.Rect(0, 0, width, height, "fill:rgb(43,62,87)") // tumblr blue + canvas.Gstyle(gstyle) + if len(flag.Args()) == 0 { + grid(canvas, "", x, y, ncols, gutter) + } else { + for _, f := range flag.Args() { + grid(canvas, f, x, y, ncols, gutter) + x += colincr + } + } + canvas.Gend() + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/turbulence/turbulence.go b/vendor/github.com/ajstarks/svgo/turbulence/turbulence.go new file mode 100644 index 0000000..e247d4d --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/turbulence/turbulence.go @@ -0,0 +1,73 @@ +// turbulence example from http://www.w3.org/TR/2003/REC-SVG11-20030114/filters.html#feTurbulence +// +build !appengine + +package main + +import ( + "fmt" + "github.com/ajstarks/svgo" + "os" +) + +var ( + canvas = svg.New(os.Stdout) + width = 500 + height = 500 +) + +type perlin struct { + id string + ftype string + basefreqx float64 + basefreqy float64 + octave int + seed int64 + tile bool +} + +func (p perlin) defturbulence() { + x := svg.Filterspec{} + canvas.Filter(p.id) + canvas.FeTurbulence(x, p.ftype, p.basefreqx, p.basefreqy, p.octave, p.seed, p.tile) + canvas.Fend() +} + +func (p perlin) frect(x, y, w, h int) { + bot := y + h + canvas.Rect(x, y, w, h, fmt.Sprintf(`filter="url(#%s)"`, p.id)) + canvas.Text(x+w/2, bot+25, fmt.Sprintf("type=%s", p.ftype)) + canvas.Text(x+w/2, bot+40, fmt.Sprintf("baseFrequency=%.2f", p.basefreqx)) + canvas.Text(x+w/2, bot+55, fmt.Sprintf("numOctaves=%d", p.octave)) +} + +func main() { + var t1, t2, t3, t4, t5, t6 perlin + + t1 = perlin{"Turb1", "t", 0.05, 0.05, 2, 0, false} + t2 = perlin{"Turb2", "t", 0.10, 0.10, 2, 0, false} + t3 = perlin{"Turb3", "t", 0.05, 0.05, 8, 0, false} + t4 = perlin{"Turb4", "f", 0.10, 0.10, 4, 0, false} + t5 = perlin{"Turb5", "f", 0.40, 0.40, 4, 0, false} + t6 = perlin{"Turb6", "f", 0.10, 0.10, 1, 0, false} + + canvas.Start(width, height) + canvas.Title("Example of feTurbulence") + canvas.Def() + t1.defturbulence() + t2.defturbulence() + t3.defturbulence() + t4.defturbulence() + t5.defturbulence() + t6.defturbulence() + canvas.DefEnd() + + canvas.Gstyle("font-size:10;font-family:Verdana;text-anchor:middle") + t1.frect(25, 25, 100, 75) + t2.frect(175, 25, 100, 75) + t3.frect(325, 25, 100, 75) + t4.frect(25, 180, 100, 75) + t5.frect(175, 180, 100, 75) + t6.frect(325, 180, 100, 75) + canvas.Gend() + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/vismem/vismem.go b/vendor/github.com/ajstarks/svgo/vismem/vismem.go new file mode 100644 index 0000000..f0d1b54 --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/vismem/vismem.go @@ -0,0 +1,51 @@ +// vismem visualizes memory locations +// +build !appengine + +package main + +import ( + "os" + + "github.com/ajstarks/svgo" +) + +var canvas = svg.New(os.Stdout) + +func main() { + width := 512 + height := 512 + n := 1024 + rowsize := 32 + diameter := 16 + var value int + var source string + + if len(os.Args) > 1 { + source = os.Args[1] + } else { + source = "/dev/urandom" + } + + f, _ := os.Open(source) + mem := make([]byte, n) + f.Read(mem) + f.Close() + + canvas.Start(width, height) + canvas.Title("Visualize Files") + canvas.Rect(0, 0, width, height, "fill:white") + dx := diameter / 2 + dy := diameter / 2 + canvas.Gstyle("fill-opacity:1.0") + for i := 0; i < n; i++ { + value = int(mem[i]) + if i%rowsize == 0 && i != 0 { + dx = diameter / 2 + dy += diameter + } + canvas.Circle(dx, dy, diameter/2, canvas.RGB(value, value, value)) + dx += diameter + } + canvas.Gend() + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/webfonts/webfonts.go b/vendor/github.com/ajstarks/svgo/webfonts/webfonts.go new file mode 100644 index 0000000..6a6593e --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/webfonts/webfonts.go @@ -0,0 +1,62 @@ +// webfonts demo +// +build !appengine + +package main + +import ( + "fmt" + "io/ioutil" + "net/http" + "net/url" + "os" + "strings" + + "github.com/ajstarks/svgo" +) + +var ( + canvas = svg.New(os.Stdout) + width = 500 + height = 1100 + fontlist = "Sue Ellen Francisco|Over the Rainbow|Pacifico|Inconsolata|Miltonian|Megrim|Monofett|Permanent Marker|Homemade Apple|Ultra" +) + +const ( + gwfURI = "http://fonts.googleapis.com/css?family=" + fontfmt = "\n" + gfmt = "fill:white;font-size:36pt;text-anchor:middle" +) + +func googlefont(f string) []string { + empty := []string{} + r, err := http.Get(gwfURI + url.QueryEscape(f)) + if err != nil { + return empty + } + defer r.Body.Close() + b, rerr := ioutil.ReadAll(r.Body) + if rerr != nil || r.StatusCode != http.StatusOK { + return empty + } + canvas.Def() + fmt.Fprintf(canvas.Writer, fontfmt, b) + canvas.DefEnd() + return strings.Split(fontlist, "|") +} + +func main() { + canvas.Start(width, height) + canvas.Title("Webfonts") + if len(os.Args) > 1 { + fontlist = os.Args[1] + } + fl := googlefont(fontlist) + canvas.Rect(0, 0, width, height) + canvas.Ellipse(width/2, height+50, width/2, height/5, "fill:rgb(44,77,232)") + canvas.Gstyle(gfmt) + for i, f := range fl { + canvas.Text(width/2, (i+1)*100, "Hello, World", "font-family:"+f) + } + canvas.Gend() + canvas.End() +} diff --git a/vendor/github.com/ajstarks/svgo/websvg/websvg.go b/vendor/github.com/ajstarks/svgo/websvg/websvg.go new file mode 100644 index 0000000..cc8000b --- /dev/null +++ b/vendor/github.com/ajstarks/svgo/websvg/websvg.go @@ -0,0 +1,73 @@ +// websvg draws SVG in a web server +// +build !appengine + +package main + +import ( + "flag" + "log" + "net/http" + "strings" + + "github.com/ajstarks/svgo" +) + +const defaultstyle = "fill:rgb(127,0,0)" + +var port = flag.String("port", ":2003", "http service address") + +func main() { + flag.Parse() + http.Handle("/circle/", http.HandlerFunc(circle)) + http.Handle("/rect/", http.HandlerFunc(rect)) + http.Handle("/arc/", http.HandlerFunc(arc)) + http.Handle("/text/", http.HandlerFunc(text)) + err := http.ListenAndServe(*port, nil) + if err != nil { + log.Println("ListenAndServe:", err) + } +} + +func shapestyle(path string) string { + i := strings.LastIndex(path, "/") + 1 + if i > 0 && len(path[i:]) > 0 { + return "fill:" + path[i:] + } + return defaultstyle +} + +func circle(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Content-Type", "image/svg+xml") + s := svg.New(w) + s.Start(500, 500) + s.Title("Circle") + s.Circle(250, 250, 125, shapestyle(req.URL.Path)) + s.End() +} + +func rect(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Content-Type", "image/svg+xml") + s := svg.New(w) + s.Start(500, 500) + s.Title("Rectangle") + s.Rect(250, 250, 100, 200, shapestyle(req.URL.Path)) + s.End() +} + +func arc(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Content-Type", "image/svg+xml") + s := svg.New(w) + s.Start(500, 500) + s.Title("Arc") + s.Arc(250, 250, 100, 100, 0, false, false, 100, 125, shapestyle(req.URL.Path)) + s.End() +} + +func text(w http.ResponseWriter, req *http.Request) { + w.Header().Set("Content-Type", "image/svg+xml") + s := svg.New(w) + s.Start(500, 500) + s.Title("Text") + s.Text(250, 250, "Hello, world", "text-anchor:middle;font-size:32px;"+shapestyle(req.URL.Path)) + s.End() +} From bf6ea48661cb89cfb5d3cebfb2e1c9c4aa232f90 Mon Sep 17 00:00:00 2001 From: Edward Muller Date: Mon, 12 Oct 2015 15:59:47 -0700 Subject: [PATCH 2/2] Add Heroku's app.json / Button --- README.md | 2 ++ app.json | 15 +++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 app.json diff --git a/README.md b/README.md index c8b58e7..878452c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Sigil +![Deploy To Heroku](https://heroku.com/deploy?template=https://github.com/cupcake/sigil/tree/master) + ![Sigil's inverted Sigil](https://sigil.cupcake.io/Sigil?inverted=1) ![Sigil's Sigil](https://sigil.cupcake.io/Sigil) diff --git a/app.json b/app.json new file mode 100644 index 0000000..f46ffb5 --- /dev/null +++ b/app.json @@ -0,0 +1,15 @@ +{ + "name": "sigil", + "description": "Deterministic identicon generator", + "keywords": [ + "go", + "identicon" + ], + "image": "heroku/go", + "mount_dir": "src/github.com/cupcake/sigil", + "website": "https://sigil.cupcake.io/", + "repository": "http://github.com/cupcake/sigil", + "env": { + "GO15VENDOREXPERIMENT": "1" + } +}