Repository navigation
Expand file tree
/
Copy pathexport.go
More file actions
81 lines (73 loc) · 2.31 KB
/
Copy pathexport.go
File metadata and controls
81 lines (73 loc) · 2.31 KB
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
// export.go: turning SVG markup — raw bytes or generated Stages — into
// raster images and PNG files, plus the bridge that feeds a Stage into
// the viewer Model.
package ntsvg
import (
"errors"
"fmt"
"image"
"image/png"
"os"
tea "charm.land/bubbletea/v2"
"nimbleterminal.dev/ntsvg/stage"
)
// RasterizeSVG rasterizes raw SVG bytes into an RGBA image fitted to
// maxW × maxH pixels while preserving aspect ratio. It uses the same
// pure-Go oksvg/rasterx backend as the widget's default renderer, so it
// works on every build target.
func RasterizeSVG(data []byte, maxW, maxH int) (image.Image, error) {
r, err := DefaultRendererFactory()("export", data)
if err != nil {
return nil, err
}
defer r.Close()
return r.Render(maxW, maxH)
}
// RasterizeStage rasterizes a generated Stage into an RGBA image fitted
// to maxW × maxH pixels while preserving aspect ratio.
func RasterizeStage(s *stage.Stage, maxW, maxH int) (image.Image, error) {
if s == nil {
return nil, errors.New("nil stage")
}
return RasterizeSVG(s.Bytes(), maxW, maxH)
}
// WritePNG rasterizes raw SVG bytes and writes them to path as a PNG (0644).
// maxW / maxH cap the output resolution.
func WritePNG(path string, data []byte, maxW, maxH int) error {
img, err := RasterizeSVG(data, maxW, maxH)
if err != nil {
return err
}
f, err := os.Create(path)
if err != nil {
return err
}
defer f.Close()
if err := png.Encode(f, img); err != nil {
return fmt.Errorf("encode png %q: %w", path, err)
}
return nil
}
// WriteStagePNG rasterizes a generated Stage and writes it to path as a
// PNG (0644). maxW / maxH cap the output resolution.
func WriteStagePNG(path string, s *stage.Stage, maxW, maxH int) error {
if s == nil {
return errors.New("nil stage")
}
return WritePNG(path, s.Bytes(), maxW, maxH)
}
// ShowStage loads a generated Stage into the viewer, exactly as if its
// SVG markup had been opened from disk. The returned Cmd performs the
// metadata scan and rasterize off the UI goroutine. Pair with stage.New
// / stage.NewChart to display generated vector graphics or charts inside
// a Bubble Tea program.
func (m *Model) ShowStage(s *stage.Stage) tea.Cmd {
if s == nil {
return m.SetSVGData("stage.svg", nil)
}
name := "stage.svg"
if title := s.Title(); title != "" {
name = title
}
return m.SetSVGData(name, s.Bytes())
}