-
Notifications
You must be signed in to change notification settings - Fork 0
/
webkit.go
116 lines (103 loc) · 2.08 KB
/
webkit.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package webkit
import (
"errors"
"image"
"runtime"
"sync"
"github.com/gotk3/gotk3/glib"
"github.com/gotk3/gotk3/gtk"
"github.com/sourcegraph/go-webkit2/webkit2"
)
var startGTKOnce sync.Once
type (
Conv struct {
webView *webkit2.WebView
resultChan chan Result
cnt int
mu sync.Mutex
}
Job struct {
SrcHTML []byte
ResultChan chan Result
}
Result struct {
Img *image.RGBA
Err error
}
)
func NewConv() *Conv {
startGTKOnce.Do(func() {
go func() {
runtime.LockOSThread()
gtk.Init(nil)
gtk.Main()
}()
})
webview, resultChan := newWebview()
conv := &Conv{
webView: webview,
resultChan: resultChan,
}
return conv
}
func (c *Conv) HTMLToImage(srcHTML []byte, img *image.RGBA) error {
c.mu.Lock()
defer c.mu.Unlock()
if c.webView == nil {
c.webView, c.resultChan = newWebview()
}
glib.IdleAdd(func() bool {
c.webView.LoadHTML(string(srcHTML), "/src_html")
return false
})
result := <-c.resultChan
if result.Err != nil {
return result.Err
}
*img = *result.Img
c.cnt++
if c.cnt >= 100 {
c.Close()
c.cnt = 0
}
return nil
}
func (c *Conv) Close() error {
if c.webView != nil {
c.webView.Destroy()
c.webView = nil
}
if c.resultChan != nil {
close(c.resultChan)
c.resultChan = nil
}
return nil
}
func newWebview() (*webkit2.WebView, chan Result) {
resultChan := make(chan Result)
webViewChan := make(chan *webkit2.WebView)
glib.IdleAdd(func() bool {
webView := webkit2.NewWebView()
webView.Connect("load-failed", func() {
resultChan <- Result{Err: errors.New("load failed")}
})
webView.Connect("load-changed", func(_ *glib.Object, i int) {
loadEvent := webkit2.LoadEvent(i)
if loadEvent == webkit2.LoadFinished {
webView.GetSnapshot(func(img *image.RGBA, err error) {
if err != nil {
resultChan <- Result{Err: err}
return
}
if img == nil || img.Pix == nil {
resultChan <- Result{Err: errors.New("result image is nil")}
}
resultChan <- Result{Img: img}
})
}
})
webViewChan <- webView
return false
})
return <-webViewChan, resultChan
}