Skip to content

Commit 57b3081

Browse files
authored
vg/vggio: first import of a Gio-backed canvas
* vg/vggio: first import of a Gio-backed canvas Updates #627.
1 parent 21a4159 commit 57b3081

File tree

6 files changed

+208
-8
lines changed

6 files changed

+208
-8
lines changed

.github/workflows/golangci-lint.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ jobs:
88
runs-on: ubuntu-latest
99
steps:
1010
- uses: actions/checkout@v2
11+
- name: cgo-dependencies
12+
run: sudo apt install pkg-config libgles2-mesa-dev libxkbcommon-dev libxkbcommon-x11-dev
1113
- name: golangci-lint
1214
uses: golangci/golangci-lint-action@v1
1315
with:

.travis.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
sudo: false
1+
sudo: true
22

33
language: go
44
go_import_path: gonum.org/v1/plot
@@ -29,6 +29,9 @@ before_install:
2929
- go get golang.org/x/tools/cmd/cover
3030
- go get github.com/mattn/goveralls
3131

32+
before_script:
33+
- sudo apt-get install -qq pkg-config libgles2-mesa-dev libxkbcommon-dev libxkbcommon-x11-dev
34+
3235
# Get deps, build, test, and ensure the code is gofmt'ed.
3336
# If we are building as gonum, then we have access to the coveralls api key, so we can run coverage as well.
3437
script:

go.mod

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@ module gonum.org/v1/plot
33
go 1.13
44

55
require (
6+
gioui.org v0.0.0-20200618124658-602d54dc5ef7
67
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af
78
github.com/fogleman/gg v1.3.0
89
github.com/go-latex/latex v0.0.0-20200518072620-0806b477ea35
910
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
1011
github.com/jung-kurt/gofpdf v1.16.2
11-
golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495
12-
golang.org/x/image v0.0.0-20200430140353-33d19683fad8
12+
golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3
13+
golang.org/x/image v0.0.0-20200618115811-c13761719519
1314
gonum.org/v1/gonum v0.7.0
1415
rsc.io/pdf v0.1.1
1516
)

go.sum

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
2+
gioui.org v0.0.0-20200618124658-602d54dc5ef7 h1:PH02mpvkp5MNZcqi/wWY+YJTG5kvvuyc6kJ/efTGfXE=
3+
gioui.org v0.0.0-20200618124658-602d54dc5ef7/go.mod h1:jiUwifN9cRl/zmco43aAqh0aV+s9GbhG13KcD+gEpkU=
14
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
25
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af h1:wVe6/Ea46ZMeNkQjjBW6xcqyQA/j5e0D6GytH95g0gQ=
36
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
@@ -9,6 +12,7 @@ github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
912
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
1013
github.com/go-fonts/dejavu v0.1.0 h1:JSajPXURYqpr+Cu8U9bt8K+XcACIHWqWrvWCKyeFmVQ=
1114
github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g=
15+
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
1216
github.com/go-latex/latex v0.0.0-20200518072620-0806b477ea35 h1:uroDDLmuCK5Pz5J/Ef5vCL6F0sJmAtZFTm0/cF027F4=
1317
github.com/go-latex/latex v0.0.0-20200518072620-0806b477ea35/go.mod h1:PNI+CcWytn/2Z/9f1SGOOYn0eILruVyp0v2/iAs8asQ=
1418
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
@@ -24,25 +28,37 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
2428
github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w=
2529
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
2630
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
31+
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
2732
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
2833
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
2934
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
30-
golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495 h1:I6A9Ag9FpEKOjcKrRNjQkPHawoXIhKyTGfvvjFAiiAk=
31-
golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
35+
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
36+
golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3 h1:n9HxLrNxWWtEb1cA950nuEEj3QnKbtsCJ6KjcgisNUs=
37+
golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE=
3238
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
3339
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067 h1:KYGJGHOQy8oSi1fDlSpcZF0+juKwk/hEMv5SiwHogR0=
3440
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
41+
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
3542
golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
3643
golang.org/x/image v0.0.0-20200430140353-33d19683fad8 h1:6WW6V3x1P/jokJBpRQYUJnMHRP6isStQwCozxnU7XQw=
3744
golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
38-
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
39-
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
45+
golang.org/x/image v0.0.0-20200618115811-c13761719519 h1:1e2ufUJNM3lCHEY5jIgac/7UTjd6cgJNdatjPdFWf34=
46+
golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
47+
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
48+
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
49+
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
50+
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
51+
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
4052
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
4153
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
54+
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
55+
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 h1:1/DFK4b7JH8DmkqhUk48onnSfrPzImPoVxuomtbT2nk=
56+
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
4257
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
4358
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
4459
golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
45-
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
60+
golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
61+
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
4662
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
4763
gonum.org/v1/gonum v0.7.0 h1:Hdks0L0hgznZLG9nzXb8vZ0rRvqNvAcgAp84y7Mwkgw=
4864
gonum.org/v1/gonum v0.7.0/go.mod h1:L02bwd0sqlsvRv41G7wGWFCsVNZFv/k1xzGIxeANHGM=

vg/vggio/example_vg_test.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Copyright ©2020 The Gonum Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package vggio_test
6+
7+
import (
8+
"log"
9+
"os"
10+
"time"
11+
12+
"gioui.org/app"
13+
"gioui.org/io/key"
14+
"gioui.org/io/system"
15+
"gioui.org/unit"
16+
17+
"gonum.org/v1/plot"
18+
"gonum.org/v1/plot/vg"
19+
"gonum.org/v1/plot/vg/draw"
20+
"gonum.org/v1/plot/vg/vggio"
21+
)
22+
23+
func ExampleCanvas() {
24+
const (
25+
w = 20 * vg.Centimeter
26+
h = 15 * vg.Centimeter
27+
dpi = 96
28+
)
29+
go func(w, h vg.Length) {
30+
win := app.NewWindow(
31+
app.Title("Gonum"),
32+
app.Size(
33+
unit.Px(float32(w.Dots(dpi))),
34+
unit.Px(float32(h.Dots(dpi))),
35+
),
36+
)
37+
defer win.Close()
38+
39+
done := time.NewTimer(2 * time.Second)
40+
defer done.Stop()
41+
42+
for {
43+
select {
44+
case e := <-win.Events():
45+
switch e := e.(type) {
46+
case system.FrameEvent:
47+
p, err := plot.New()
48+
if err != nil {
49+
log.Fatalf("could not create plot: %+v", err)
50+
}
51+
p.Title.Text = "My title"
52+
p.X.Label.Text = "X"
53+
p.Y.Label.Text = "Y"
54+
55+
cnv := vggio.New(e, w, h, vggio.UseDPI(dpi))
56+
p.Draw(draw.New(cnv))
57+
cnv.Paint(e)
58+
59+
case key.Event:
60+
switch e.Name {
61+
case "Q", key.NameEscape:
62+
os.Exit(0)
63+
}
64+
}
65+
case <-done.C:
66+
os.Exit(0)
67+
}
68+
}
69+
}(w, h)
70+
71+
app.Main()
72+
73+
// Output:
74+
}

vg/vggio/vg.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Copyright ©2020 The Gonum Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// Package vggio provides a vg.Canvas implementation backed by Gioui.
6+
package vggio // import "gonum.org/v1/plot/vg/vggio"
7+
8+
import (
9+
"image/color"
10+
11+
"gioui.org/f32"
12+
"gioui.org/io/system"
13+
"gioui.org/layout"
14+
"gioui.org/op"
15+
"gioui.org/op/paint"
16+
17+
"gonum.org/v1/plot/vg"
18+
"gonum.org/v1/plot/vg/vgimg"
19+
)
20+
21+
// Canvas implements the vg.Canvas interface,
22+
// drawing to an image.Image using vgimg and painting that image
23+
// into a Gioui context.
24+
type Canvas struct {
25+
*vgimg.Canvas
26+
gtx layout.Context
27+
}
28+
29+
// DefaultDPI is the default dot resolution for image
30+
// drawing in dots per inch.
31+
const DefaultDPI = 96
32+
33+
// New returns a new image canvas with the provided dimensions and options.
34+
// The currently accepted options are UseDPI and UseBackgroundColor.
35+
// If the resolution or background color are not specified, defaults are used.
36+
func New(e system.FrameEvent, w, h vg.Length, opts ...option) *Canvas {
37+
cfg := &config{
38+
dpi: DefaultDPI,
39+
bkg: color.White,
40+
}
41+
for _, opt := range opts {
42+
opt(cfg)
43+
}
44+
c := &Canvas{
45+
gtx: layout.NewContext(new(op.Ops), e),
46+
Canvas: vgimg.NewWith(
47+
vgimg.UseDPI(cfg.dpi),
48+
vgimg.UseWH(w, h),
49+
vgimg.UseBackgroundColor(cfg.bkg),
50+
),
51+
}
52+
return c
53+
}
54+
55+
type config struct {
56+
dpi int
57+
bkg color.Color
58+
}
59+
60+
type option func(*config)
61+
62+
// UseDPI sets the dots per inch of a canvas. It should only be
63+
// used as an option argument when initializing a new canvas.
64+
func UseDPI(dpi int) option {
65+
if dpi <= 0 {
66+
panic("DPI must be > 0.")
67+
}
68+
return func(c *config) {
69+
c.dpi = dpi
70+
}
71+
}
72+
73+
// UseBackgroundColor specifies the image background color.
74+
// Without UseBackgroundColor, the default color is white.
75+
func UseBackgroundColor(c color.Color) option {
76+
return func(cfg *config) {
77+
cfg.bkg = c
78+
}
79+
}
80+
81+
func (c *Canvas) pt32(p vg.Point) f32.Point {
82+
_, h := c.Size()
83+
dpi := c.DPI()
84+
return f32.Point{
85+
X: float32(p.X.Dots(dpi)),
86+
Y: float32(h.Dots(dpi) - p.Y.Dots(dpi)),
87+
}
88+
}
89+
90+
// Paint paints the canvas' content on the screen.
91+
func (c *Canvas) Paint(e system.FrameEvent) {
92+
w, h := c.Size()
93+
box := vg.Rectangle{Max: vg.Point{X: w, Y: h}}
94+
img := c.Canvas.Image()
95+
ops := c.gtx.Ops
96+
min := c.pt32(box.Min)
97+
max := c.pt32(box.Max)
98+
r32 := f32.Rect(min.X, min.Y, max.X, max.Y)
99+
100+
paint.NewImageOp(img).Add(ops)
101+
paint.PaintOp{Rect: r32}.Add(ops)
102+
103+
e.Frame(ops)
104+
}

0 commit comments

Comments
 (0)