forked from charmbracelet/freeze
-
Notifications
You must be signed in to change notification settings - Fork 0
/
png.go
98 lines (86 loc) · 2.38 KB
/
png.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
package main
import (
"bytes"
"context"
"os"
"os/exec"
"github.com/beevik/etree"
"github.com/charmbracelet/freeze/font"
"github.com/kanrichan/resvg-go"
)
func libsvgConvert(doc *etree.Document, _, _ float64, output string) error {
_, err := exec.LookPath("rsvg-convert")
if err != nil {
return err //nolint: wrapcheck
}
svg, err := doc.WriteToBytes()
if err != nil {
return err //nolint: wrapcheck
}
// rsvg-convert is installed use that to convert the SVG to PNG,
// since it is faster.
rsvgConvert := exec.Command("rsvg-convert", "-o", output)
rsvgConvert.Stdin = bytes.NewReader(svg)
err = rsvgConvert.Run()
return err //nolint: wrapcheck
}
func resvgConvert(doc *etree.Document, w, h float64, output string) error {
svg, err := doc.WriteToBytes()
if err != nil {
return err //nolint: wrapcheck
}
worker, err := resvg.NewDefaultWorker(context.Background())
if err != nil {
printErrorFatal("Unable to write output", err)
}
defer worker.Close() //nolint: errcheck
fontdb, err := worker.NewFontDBDefault()
if err != nil {
printErrorFatal("Unable to write output", err)
}
defer fontdb.Close() //nolint: errcheck
err = fontdb.LoadFontData(font.JetBrainsMonoTTF)
if err != nil {
printErrorFatal("Unable to load font", err)
}
err = fontdb.LoadFontData(font.JetBrainsMonoNLTTF)
if err != nil {
printErrorFatal("Unable to load font", err)
}
pixmap, err := worker.NewPixmap(uint32(w), uint32(h))
if err != nil {
printError("Unable to write output", err)
os.Exit(1)
}
defer pixmap.Close() //nolint: errcheck
tree, err := worker.NewTreeFromData(svg, &resvg.Options{
Dpi: 192,
ShapeRenderingMode: resvg.ShapeRenderingModeGeometricPrecision,
TextRenderingMode: resvg.TextRenderingModeOptimizeLegibility,
ImageRenderingMode: resvg.ImageRenderingModeOptimizeQuality,
DefaultSizeWidth: float32(w),
DefaultSizeHeight: float32(h),
})
if err != nil {
printError("Unable to write output", err)
os.Exit(1)
}
defer tree.Close() //nolint: errcheck
err = tree.ConvertText(fontdb)
if err != nil {
return err //nolint: wrapcheck
}
err = tree.Render(resvg.TransformIdentity(), pixmap)
if err != nil {
return err //nolint: wrapcheck
}
png, err := pixmap.EncodePNG()
if err != nil {
return err //nolint: wrapcheck
}
err = os.WriteFile(output, png, 0o600)
if err != nil {
return err //nolint: wrapcheck
}
return err //nolint: wrapcheck
}